51 virtual inline void setParams(
const double* rwork,
const int* iwork = 0)
63 inline void calc(
const double& Sw)
99 bool implemented =
false;
113 inline void calc(
const double& Sw)
154 VGMorig(
const double* rwork,
const int* iwork = 0):
170 inline void setParams(
const double* rwork,
const int* iwork = 0)
191 inline void calc(
const double& Sw)
193 double Seovmmo,Seovm,Seovmmh,S,Smmo,S2mmo,Sm,S2m,pcesub1,pcesub2;
197 Seovmmo = pow(
Se_eps,((1.0/
m)-1.0));
199 Seovmmh = pow(
Se_eps,((1.0/
m)-0.5));
202 S2mmo = pow(S,2.0*
m-1.0);
206 pcesub1 = pow(((1.0/Seovm)-1.0),((1.0/
n)-1.0));
207 pcesub2 = pcesub1*((1.0/Seovm)-1.0);
209 krw = sqrt(
Se)*(1.0-Sm)*(1.0-Sm);
210 dkrw = (0.5*(1.0/sqrt(
Se_eps))*(1.0-Sm)*(1.0-Sm) + 2.0*(1-Sm)*Smmo*Seovmmh)*
dSe_dSw;
212 krn = sqrt(1.0-
Se)*S2m;
226 VGM(
const double* rwork,
const int* iwork = 0):
267 inline void calc(
const double& Sw)
271 double sBar,psiC,DsBar_DpC,DDsBar_DDpC,DkrW_DpC,DkrN_DpC;
273 alphaPsiC, alphaPsiC_n, alphaPsiC_nM1, alphaPsiC_nM2,
275 sqrt_sBar, sqrt_1minusSbar,
276 sBarByOnePlus_alphaPsiC_n, sBarBy_onePlus_alphaPsiC_n_2;
280 onePlus_alphaPsiC_n = pow(sBar,1.0/-
m);
281 alphaPsiC_n = onePlus_alphaPsiC_n - 1.0;
282 alphaPsiC = pow(alphaPsiC_n,1.0/
n);
283 psiC = alphaPsiC/
alpha;
285 alphaPsiC_nM1 = alphaPsiC_n/alphaPsiC;
286 sBarByOnePlus_alphaPsiC_n = sBar/onePlus_alphaPsiC_n;
287 sqrt_sBar = sqrt(sBar);
288 sqrt_1minusSbar = sqrt(1.0 - sBar);
290 DsBar_DpC = -
alpha*(
n-1.0)*alphaPsiC_nM1
291 *sBarByOnePlus_alphaPsiC_n;
294 vBar = 1.0-alphaPsiC_nM1*sBar;
295 uBar = alphaPsiC_nM1*sBar;
298 krw = sqrt_sBar*vBar*vBar;
299 krn = sqrt_1minusSbar*uBar*uBar;
310 alphaPsiC_nM2 = alphaPsiC_nM1/alphaPsiC;
312 sBarBy_onePlus_alphaPsiC_n_2 = sBarByOnePlus_alphaPsiC_n
313 /onePlus_alphaPsiC_n;
315 *((2*
n-1.)*alphaPsiC_nM1*alphaPsiC_nM1
316 *sBarBy_onePlus_alphaPsiC_n_2
319 *sBarByOnePlus_alphaPsiC_n);
323 DkrW_DpC = (0.5/sqrt_sBar)*DsBar_DpC*vBar*vBar
326 (
alpha*(
n-1.0)*alphaPsiC_nM2*sBar
327 + alphaPsiC_nM1 * DsBar_DpC);
335 DkrN_DpC = -(0.5/sqrt_1minusSbar)*DsBar_DpC*uBar*uBar
337 2.0*sqrt_1minusSbar*uBar*
338 (
alpha*(
n-1.0)*alphaPsiC_nM2*sBar
339 + alphaPsiC_nM1 * DsBar_DpC);
344 (
alpha*(
n-1.0)*alphaPsiC_nM2*sBar
345 + alphaPsiC_nM1 * DsBar_DpC)
350 if (psiC < ns_del && psiC > 0.0 )
363 double DpC_Dse = 0.0;
364 if (fabs(DsBar_DpC) > 0.0)
365 DpC_Dse = 1.0/DsBar_DpC;
366 double DpC_Dsw = DpC_Dse*
dSe_dSw;
367 dkrw = DkrW_DpC*DpC_Dsw;
368 dkrn = DkrN_DpC*DpC_Dsw;
376 double sBar,psiC,DsBar_DpC,DDsBar_DDpC,DkrW_DpC,DkrN_DpC;
378 alphaPsiC, alphaPsiC_n, alphaPsiC_nM1, alphaPsiC_nM2,
380 sqrt_sBar, sqrt_1minusSbar,
381 sBarByOnePlus_alphaPsiC_n, sBarBy_onePlus_alphaPsiC_n_2;
384 psiC =
max(0.0,psicIn);
385 alphaPsiC =
alpha*psiC;
386 alphaPsiC_n = pow(alphaPsiC,
n);
387 alphaPsiC_nM1 = alphaPsiC_n/alphaPsiC;
388 onePlus_alphaPsiC_n = 1.0 + alphaPsiC_n;
389 sBar = pow(onePlus_alphaPsiC_n,-
m);
390 sBarByOnePlus_alphaPsiC_n = sBar/onePlus_alphaPsiC_n;
391 sqrt_sBar = sqrt(sBar);
392 sqrt_1minusSbar = sqrt(1.0 - sBar);
394 DsBar_DpC = -
alpha*(
n-1.0)*alphaPsiC_nM1
395 *sBarByOnePlus_alphaPsiC_n;
397 vBar = 1.0-alphaPsiC_nM1*sBar;
398 uBar = alphaPsiC_nM1*sBar;
401 krw = sqrt_sBar*vBar*vBar;
402 krn = sqrt_1minusSbar*uBar*uBar;
419 alphaPsiC_nM2 = alphaPsiC_nM1/alphaPsiC;
421 sBarBy_onePlus_alphaPsiC_n_2 = sBarByOnePlus_alphaPsiC_n
422 /onePlus_alphaPsiC_n;
424 *((2*
n-1.)*alphaPsiC_nM1*alphaPsiC_nM1
425 *sBarBy_onePlus_alphaPsiC_n_2
428 *sBarByOnePlus_alphaPsiC_n);
432 DkrW_DpC = (0.5/sqrt_sBar)*DsBar_DpC*vBar*vBar
435 (
alpha*(
n-1.0)*alphaPsiC_nM2*sBar
436 + alphaPsiC_nM1 * DsBar_DpC);
444 DkrN_DpC = -(0.5/sqrt_1minusSbar)*DsBar_DpC*uBar*uBar
446 2.0*sqrt_1minusSbar*uBar*
447 (
alpha*(
n-1.0)*alphaPsiC_nM2*sBar
448 + alphaPsiC_nM1 * DsBar_DpC);
453 (
alpha*(
n-1.0)*alphaPsiC_nM2*sBar
454 + alphaPsiC_nM1 * DsBar_DpC)
459 if (psiC < ns_del && psiC > 0.0 )
482 VGB(
const double* rwork,
const int* iwork = 0):
486 inline void calc(
const double& Sw)
488 double S,Smmo,Sm,
alpha,Se1ovMmo;
492 Se1ovMmo = pow(
Se_eps,((1.0/
m)-1.0));
494 Smmo = pow(S,(
m-1.0));
521 BCM(
const double* rwork,
const int* iwork = 0):
527 inline void setParams(
const double* rwork,
const int* iwork = 0)
534 inline void calc(
const double& Sw)
536 double Value,Expon,krwovSe,Oovbclpo,Oovbcl,X,sqrt1mu;
540 Oovbclpo = Oovbcl+1.0;
544 krwovSe = pow(
Se,(Expon-1.0));
545 sqrt1mu = sqrt(1.0-
Se);
550 krn = sqrt1mu*Value*Value;
551 dkrn = (-0.5*(1.0/sqrt1mu)*Value*Value - 2.0*sqrt1mu*Value*Oovbclpo*X )*
dSe_dSw;
562 BCB(
const double* rwork,
const int* iwork = 0):
BCM(rwork,iwork)
565 inline void calc(
const double& Sw)
567 double Se2ovL,Se2,Se3,omSe,Expon,Semoovlmo,Se_cutOff;
575 Se_cutOff =
max(1.0e-4,
Se);
576 Semoovlmo = pow(Se_cutOff,((-1.0/
lambda)-1.0));
581 krn = (omSe*omSe)*(1.0-Se2ovL*
Se);
710 virtual inline void calc(
const double& Sw)
773 virtual inline void setParams(
const double* rwork,
const int* iwork = 0)
862 const double thetaSR,
864 double &DthetaW_DpsiC,
868 const double m_vg = 1.0 - 1.0 / n_vg;
869 const double thetaS = thetaR + thetaSR;
871 const double pcBar = alpha * psiC;
872 double pcBarStar = pcBar;
873 if (pcBar < 1.0e-8) pcBarStar = 1.0e-8;
874 const double pcBar_nM2 = pow(pcBarStar, n_vg - 2);
875 const double pcBar_nM1 = pcBar_nM2 * pcBar;
876 const double pcBar_n = pcBar_nM1 * pcBar;
877 const double onePlus_pcBar_n = 1.0 + pcBar_n;
879 const double sBar = pow(onePlus_pcBar_n, -m_vg);
881 const double DsBar_DpsiC =
882 alpha * (1.0 - n_vg) * (sBar / onePlus_pcBar_n) * pcBar_nM1;
884 const double vBar = 1.0 - pcBar_nM1 * sBar;
885 const double vBar2 = vBar * vBar;
886 const double DvBar_DpsiC =
887 -alpha * (n_vg - 1.0) * pcBar_nM2 * sBar - pcBar_nM1 * DsBar_DpsiC;
889 thetaW = thetaSR * sBar + thetaR;
890 DthetaW_DpsiC = thetaSR * DsBar_DpsiC;
892 const double sqrt_sBar = sqrt(sBar);
893 double sqrt_sBarStar = sqrt_sBar;
894 if (sqrt_sBar < 1.0e-8) sqrt_sBarStar = 1.0e-8;
895 KWr = sqrt_sBar * vBar2;
896 DKWr_DpsiC = ((0.5 / sqrt_sBarStar) * DsBar_DpsiC * vBar2
897 + 2.0 * sqrt_sBar * vBar * DvBar_DpsiC);
923 const double thetaSR,
926 double psiC, pcBar, pcBar_n, sBar, thetaW, thetaS, m_vg;
927 m_vg = 1.0 - 1.0 / n_vg;
928 thetaS = thetaR + thetaSR;
930 const double pcBarMax = 1.0e4;
931 const double SeMin = pow(1.0 + pow(pcBarMax, n_vg), -m_vg);
932 if (thetaW > thetaR + SeMin * thetaSR && thetaW < thetaS) {
933 sBar = (thetaW - thetaR) / thetaSR;
934 pcBar_n = pow(sBar, -1.0 / m_vg) - 1.0;
935 pcBar = pow(pcBar_n, 1.0 / n_vg);
936 psiC = pcBar / alpha;
938 }
else if (thetaW >= thetaS) {
939 if (
u < 0.0)
u = 0.0;
941 u = -pcBarMax / alpha;
960 const double thetaSR,
963 const double u_prev =
u;
965 const double thetaS = thetaR + thetaSR;
966 const double m_vg = 1.0 - 1.0 / n_vg;
968 const double psiC0 = -
u;
969 if (psiC0 <= 0.0) {
return; }
970 const double rhom0 = rho * std::exp(beta *
u);
971 const double thetaW_imp = m / rhom0;
979 const double pcBarMax = 1.0e4;
980 const double SeMin = std::pow(1.0 + std::pow(pcBarMax, n_vg), -m_vg);
981 if (thetaW_imp < thetaR + SeMin * thetaSR) {
return; }
982 const double thetaEps = 1e-12;
984 if (thetaW_imp > 0.99 * thetaS) {
985 const double thetaWc = std::min(thetaW_imp, thetaS - thetaEps);
986 m_target = rhom0 * thetaWc;
991 const double thetaW_guess = std::min(m_target / rhom0, thetaS - thetaEps);
992 if (thetaW_guess > thetaR + thetaEps && thetaW_guess < thetaS - thetaEps) {
993 const double sBar = (thetaW_guess - thetaR) / thetaSR;
994 if (sBar > 0.0 && sBar < 1.0) {
995 const double pcBar_n = std::pow(sBar, -1.0 / m_vg) - 1.0;
997 const double pcBar = std::pow(pcBar_n, 1.0 / n_vg);
998 const double u_guess = -pcBar / alpha;
999 if (std::isfinite(u_guess) && u_guess < 0.0) {
1010 const int maxIts = 50;
1011 const double tol = 1e-12 * std::max(1.0, std::fabs(m));
1012 const double duMax = 1.0 / alpha;
1014 auto theta_and_dtheta_du = [&](
double u,
1016 double &dtheta_du) ->
bool
1018 const double psiC = -
u;
1020 if (psiC <= 0.0) {
return false; }
1022 const double pcBar = alpha * psiC;
1023 const double pcBarStar = (pcBar < 1e-12) ? 1e-12 : pcBar;
1024 const double pcBar_nM2 = std::pow(pcBarStar, n_vg - 2.0);
1025 const double pcBar_nM1 = pcBar_nM2 * pcBar;
1026 const double pcBar_n = pcBar_nM1 * pcBar;
1027 const double onePlus_pcBar_n = 1.0 + pcBar_n;
1028 const double sBar = std::pow(onePlus_pcBar_n, -m_vg);
1030 const double DsBar_DpsiC =
1031 alpha * (1.0 - n_vg) * (sBar / onePlus_pcBar_n) * pcBar_nM1;
1033 thetaW = thetaR + thetaSR * sBar;
1034 dtheta_du = -thetaSR * DsBar_DpsiC;
1035 if (thetaW <= thetaR + thetaEps)
return false;
1036 if (thetaW >= thetaS - thetaEps)
return false;
1039 for (
int it = 0; it < maxIts; ++it)
1041 if (-
u <= 0.0) {
u = u_prev;
return; }
1043 double thetaW, dtheta_du;
1044 if (!theta_and_dtheta_du(
u, thetaW, dtheta_du)) {
1048 const double rhom = rho * std::exp(beta *
u);
1049 const double g = rhom * thetaW - m_target;
1050 if (std::fabs(g) < tol)
return;
1052 const double gp = rhom * (beta * thetaW + dtheta_du);
1054 const double gpTol = 1e-14 * std::max(1.0, std::fabs(rhom * thetaW));
1055 if (std::fabs(gp) < gpTol) {
u = u_prev;
return; }
1057 double du = -g / gp;
1058 if (du > duMax) du = duMax;
1059 if (du < -duMax) du = -duMax;
1062 if (-
u <= 0.0) {
u = u_prev;
return; }
1093 : ((2.0 + 3.0 * lam) / lam);
1099 const double thetaR,
1100 const double thetaSR,
1102 double &DthetaW_DpsiC,
1107 const double thetaS = thetaR + thetaSR;
1111 DthetaW_DpsiC = 0.0;
1116 const double pcBar = alpha * psiC;
1120 DthetaW_DpsiC = 0.0;
1126 const double Se = pow(pcBar, -lam);
1127 const double dSe_DpsiC = -lam * alpha * pow(pcBar, -lam - 1.0);
1128 thetaW = thetaR + thetaSR * Se;
1129 DthetaW_DpsiC = thetaSR * dSe_DpsiC;
1131 const double exp_w =
bc_eta(lam, kr_model);
1132 KWr = pow(Se, exp_w);
1133 DKWr_DpsiC = exp_w * pow(Se, exp_w - 1.0) * dSe_DpsiC;
1140 const double thetaR,
1141 const double thetaSR,
1144 const double thetaS = thetaR + thetaSR;
1145 const double thetaW = m / rho;
1149 const double psiCMax_over_pd = 1.0e4;
1150 const double SeMin = pow(psiCMax_over_pd, -lam);
1151 if (thetaW > thetaR + SeMin * thetaSR && thetaW < thetaS) {
1152 const double Se = (thetaW - thetaR) / thetaSR;
1153 if (Se > 0.0 && Se < 1.0) {
1154 const double pcBar = pow(Se, -1.0 / lam);
1155 const double psiC = pcBar / alpha;
1158 }
else if (thetaW >= thetaS) {
1159 if (
u < -1.0 / alpha)
u = -1.0 / alpha;
1161 u = -psiCMax_over_pd / alpha;
1199 const double thetaR,
1200 const double thetaSR,
1203 if (-
u <= 0.0) {
return; }
1207 auto g_of = [&](
const double uu) ->
double {
1208 const double pcBar = alpha * (-uu);
1209 const double Se = (pcBar <= 1.0) ? 1.0 : pow(pcBar, -lam);
1210 return rho * std::exp(beta * uu) * (thetaR + thetaSR * Se) - m;
1215 const double u_entry = -1.0 / alpha;
1216 const double u_wall = -(1.0 + 1.0e-9) / alpha;
1217 if (g_of(u_wall) <= 0.0) {
u = u_entry;
return; }
1224 const double psiCMax_over_pd = 1.0e4;
1225 const double u_floor = -psiCMax_over_pd / alpha;
1226 if (g_of(u_floor) > 0.0) {
return; }
1228 double lo = u_floor, hi = u_wall;
1233 const double Se = (m / rho - thetaR) / thetaSR;
1234 if (Se > 0.0 && Se < 1.0) {
1235 const double u_guess = -pow(Se, -1.0 / lam) / alpha;
1236 if (std::isfinite(u_guess) && u_guess > lo && u_guess < hi)
u = u_guess;
1237 else u = 0.5 * (lo + hi);
1238 }
else u = 0.5 * (lo + hi);
1240 if (!(
u > lo &&
u < hi))
u = 0.5 * (lo + hi);
1244 const int maxIts = 100;
1245 const double tol = 1e-12 * std::max(1.0, std::fabs(m));
1247 for (
int it = 0; it < maxIts; ++it) {
1250 const double pcBar = alpha * (-
u);
1251 const double Se = pow(pcBar, -lam);
1252 const double dSe_DpsiC = -lam * alpha * pow(pcBar, -lam - 1.0);
1253 const double thetaW = thetaR + thetaSR * Se;
1254 const double dtheta_du = -thetaSR * dSe_DpsiC;
1256 const double rhom = rho * std::exp(beta *
u);
1257 const double g = rhom * thetaW - m;
1258 if (std::fabs(g) < tol)
return;
1259 if (g > 0.0) hi =
u;
else lo =
u;
1261 const double gp = rhom * (beta * thetaW + dtheta_du);
1262 const double gpTol = 1e-14 * std::max(1.0, std::fabs(rhom * thetaW));
1263 double u_next = (std::fabs(gp) > gpTol) ? (
u - g / gp) : 0.5 * (lo + hi);
1265 if (!(u_next > lo && u_next < hi)) u_next = 0.5 * (lo + hi);
1267 if (std::fabs(u_next -
u) <= 1e-15 * std::fabs(
u))
return;
1346 const double thetaR,
1347 const double thetaSR,
1349 double &DthetaW_DpsiC,
1357 const double x = -alpha * psiC;
1360 thetaW = thetaR + thetaSR * Se;
1361 DthetaW_DpsiC = thetaSR * dSe_DpsiC;
1363 DKWr_DpsiC = dSe_DpsiC;
1380 const double thetaR,
1381 const double thetaSR,
1385 const double thetaW = m / rho;
1388 if (thetaW > thetaR + SeMin * thetaSR && thetaW < thetaR + SeMax * thetaSR) {
1389 const double Se = (thetaW - thetaR) / thetaSR;
1390 const double u_new = std::log(Se) / alpha;
1391 if (std::isfinite(u_new))
u = u_new;
1417 const double thetaR,
1418 const double thetaSR,
1423 auto g_of = [&](
const double uu) ->
double {
1424 const double x = alpha * uu;
1426 return rho * std::exp(beta * uu) * (thetaR + thetaSR * Se) - m;
1430 if (g_of(u_rail) <= 0.0) {
u = u_rail;
return; }
1433 if (g_of(u_floor) > 0.0) {
return; }
1435 double lo = u_floor, hi = u_rail;
1440 const double Se = (m / rho - thetaR) / thetaSR;
1441 double u_guess = 0.5 * (lo + hi);
1443 const double u_analytic = std::log(Se) / alpha;
1444 if (std::isfinite(u_analytic) && u_analytic > lo && u_analytic < hi)
1445 u_guess = u_analytic;
1449 if (!(
u > lo &&
u < hi))
u = 0.5 * (lo + hi);
1453 const int maxIts = 100;
1454 const double tol = 1e-12 * std::max(1.0, std::fabs(m));
1456 for (
int it = 0; it < maxIts; ++it) {
1457 const double Se = std::exp(alpha *
u);
1458 const double thetaW = thetaR + thetaSR * Se;
1459 const double dtheta_du = thetaSR * alpha * Se;
1461 const double rhom = rho * std::exp(beta *
u);
1462 const double g = rhom * thetaW - m;
1463 if (std::fabs(g) < tol)
return;
1464 if (g > 0.0) hi =
u;
else lo =
u;
1466 const double gp = rhom * (beta * thetaW + dtheta_du);
1467 const double gpTol = 1e-14 * std::max(1.0, std::fabs(rhom * thetaW));
1468 double u_next = (std::fabs(gp) > gpTol) ? (
u - g / gp) : 0.5 * (lo + hi);
1470 if (!(u_next > lo && u_next < hi)) u_next = 0.5 * (lo + hi);
1472 if (std::fabs(u_next -
u) <= 1e-15 * std::fabs(
u))
return;
1531 const double m_vg = 1.0 - 1.0 / n_vg;
1541 const double SeStar = (Se < 1.0e-3) ? 1.0e-3 : Se;
1542 const double SemInvM = pow(SeStar, -1.0 / m_vg);
1543 const double pcBar_n_raw = SemInvM - 1.0;
1567 const double eps_pcBar = 1.0e-3;
1570 const double pcBar_n_raw_clamped = (pcBar_n_raw > -0.5 * eps_pcBar)
1573 const double pcBar_n = pcBar_n_raw_clamped + eps_pcBar;
1574 const double pcBar = pow(pcBar_n, 1.0 / n_vg);
1585 const double dpcBar_n_dSe = -(1.0 / m_vg) * (SemInvM / SeStar);
1586 const double dpcBar_dSe = (1.0 / n_vg) * (pcBar / pcBar_n) * dpcBar_n_dSe;
1592 const double dSeStar_dSe = (Se < 1.0e-3) ? 0.0 : 1.0;
1593 Dpc_DSe = (dpcBar_dSe / alpha) * dSeStar_dSe;
1600 const double inv_m = 1.0 / m_vg;
1601 const double inv_n = 1.0 / n_vg;
1602 const double d2pcBar_n_dSe2 = inv_m * (inv_m + 1.0) * (SemInvM / (SeStar * SeStar));
1603 const double pcBar_n_pow_a = pow(pcBar_n, inv_n - 2.0);
1604 const double pcBar_n_pow_b = pow(pcBar_n, inv_n - 1.0);
1605 const double d2pcBar_dSe2 = inv_n * ((inv_n - 1.0) * pcBar_n_pow_a * dpcBar_n_dSe * dpcBar_n_dSe
1606 + pcBar_n_pow_b * d2pcBar_n_dSe2);
1607 D2pc_DSe2 = (d2pcBar_dSe2 / alpha) * dSeStar_dSe;
1663 const double delta_smooth = 5.0e-2;
1665 if (Se >= 1.0 + delta_smooth) {
1688 const double inv_alpha = 1.0 / alpha;
1689 const double m0_t = (-inv_alpha / lam) * delta_smooth;
1690 const double t = (Se - 1.0) / delta_smooth;
1691 const double t2 = t * t, t3 = t2 * t;
1692 const double H00 = 2.0 * t3 - 3.0 * t2 + 1.0;
1693 const double H10 = t3 - 2.0 * t2 + t;
1694 const double dH00 = 6.0 * t2 - 6.0 * t;
1695 const double dH10 = 3.0 * t2 - 4.0 * t + 1.0;
1696 const double d2H00 = 12.0 * t - 6.0;
1697 const double d2H10 = 6.0 * t - 4.0;
1698 pc = H00 * inv_alpha + H10 * m0_t;
1699 Dpc_DSe = (dH00 * inv_alpha + dH10 * m0_t) / delta_smooth;
1700 D2pc_DSe2 = (d2H00 * inv_alpha + d2H10 * m0_t) / (delta_smooth * delta_smooth);
1723 const double Se_min_pc = 1.0e-2;
1724 if (Se < Se_min_pc) {
1725 const double SemInvLam_min = pow(Se_min_pc, -1.0 / lam);
1726 const double pc_min = SemInvLam_min / alpha;
1727 const double slope_min = -(SemInvLam_min / Se_min_pc) / (alpha * lam);
1728 pc = pc_min + slope_min * (Se - Se_min_pc);
1729 Dpc_DSe = slope_min;
1735 const double SemInvLam = pow(Se, -1.0 / lam);
1736 pc = SemInvLam / alpha;
1739 Dpc_DSe = -(SemInvLam / Se) / (alpha * lam);
1742 const double inv_lam = 1.0 / lam;
1743 D2pc_DSe2 = inv_lam * (inv_lam + 1.0) * (SemInvLam / (Se * Se)) / alpha;
1762 const double thetaR,
1763 const double thetaSR,
1765 double &DthetaW_DSe,
1769 const double m_vg = 1.0 - 1.0 / n_vg;
1770 thetaW = thetaR + thetaSR * Se;
1771 DthetaW_DSe = thetaSR;
1783 const double SeStar = (Se < 1.0e-12) ? 1.0e-12 : Se;
1784 const double SeInvM = pow(SeStar, 1.0 / m_vg);
1785 const double x_ = 1.0 - SeInvM;
1786 const double xStar = (x_ < 1.0e-12) ? 1.0e-12 : x_;
1787 const double y_ = pow(xStar, m_vg);
1788 const double term = 1.0 - y_;
1789 const double sqrtSe = sqrt(SeStar);
1790 const double sqrtSe_safe = (sqrtSe < 1.0e-12) ? 1.0e-12 : sqrtSe;
1792 KWr = sqrtSe * term * term;
1794 const double Dterm_DSe = pow(xStar, m_vg - 1.0) * pow(SeStar, 1.0 / m_vg - 1.0);
1795 DKWr_DSe = (0.5 / sqrtSe_safe) * term * term + 2.0 * sqrtSe * term * Dterm_DSe;
1803 const double Se_trap = 1.0)
1808 const double inv_trap = 1.0 / Se_trap;
1809 const double Se = Se_w * inv_trap;
1810 const double m_vg = 1.0 - 1.0 / n_vg;
1822 const double SeStar = (Se < 1.0e-12) ? 1.0e-12 : Se;
1823 const double SeInvM = pow(SeStar, 1.0 / m_vg);
1824 const double x_ = 1.0 - SeInvM;
1825 const double xStar = (x_ < 1.0e-12) ? 1.0e-12 : x_;
1827 const double y2m = pow(xStar, 2.0 * m_vg);
1828 const double oneMinusSe = 1.0 - Se;
1829 const double oneMinusSeStar = (oneMinusSe < 1.0e-12) ? 1.0e-12 : oneMinusSe;
1830 const double sqrt_oms = sqrt(oneMinusSeStar);
1831 KNr = sqrt_oms * y2m;
1833 const double Dy2m_DSe = -2.0 * pow(xStar, 2.0 * m_vg - 1.0) * pow(SeStar, 1.0 / m_vg - 1.0);
1834 DKNr_DSe = ((-0.5 / sqrt_oms) * y2m + sqrt_oms * Dy2m_DSe) * inv_trap;
1840 const double thetaR,
1841 const double thetaSR,
1843 double &DthetaW_DSe,
1847 thetaW = thetaR + thetaSR * Se;
1848 DthetaW_DSe = thetaSR;
1861 const double exp_w = (2.0 + 3.0 * lam) / lam;
1862 KWr = pow(Se, exp_w);
1863 DKWr_DSe = exp_w * pow(Se, exp_w - 1.0);
1871 const double Se_trap = 1.0)
1882 const double inv_trap = 1.0 / Se_trap;
1883 const double Se = Se_w * inv_trap;
1914 const double delta_brn = 5.0e-2;
1915 const double s_min_brn = 1.0e-3;
1916 const double Se_a = 1.0 - delta_brn;
1928 DKNr_DSe = -s_min_brn * inv_trap;
1932 const double exp_n = (2.0 + lam) / lam;
1936 const double SeExp = pow(Se, exp_n);
1937 const double oneMinusSe = 1.0 - Se;
1938 const double Y = 1.0 - SeExp;
1939 KNr = oneMinusSe * oneMinusSe *
Y;
1940 DKNr_DSe = (-2.0 * oneMinusSe *
Y
1941 - oneMinusSe * oneMinusSe * exp_n * pow(Se, exp_n - 1.0)) * inv_trap;
1950 const double SeExp_a = pow(Se_a, exp_n);
1951 const double oneMinusSe_a = 1.0 - Se_a;
1952 const double Y_a = 1.0 - SeExp_a;
1953 const double fa = oneMinusSe_a * oneMinusSe_a * Y_a;
1954 const double da = -2.0 * oneMinusSe_a * Y_a
1955 - oneMinusSe_a * oneMinusSe_a * exp_n * pow(Se_a, exp_n - 1.0);
1957 const double t = (Se - Se_a) / delta_brn;
1958 const double t2 = t * t;
1959 const double t3 = t2 * t;
1962 const double H00 = 2.0 * t3 - 3.0 * t2 + 1.0;
1963 const double H10 = t3 - 2.0 * t2 + t;
1964 const double H11 = t3 - t2;
1965 const double dH00 = 6.0 * t2 - 6.0 * t;
1966 const double dH10 = 3.0 * t2 - 4.0 * t + 1.0;
1967 const double dH11 = 3.0 * t2 - 2.0 * t;
1969 KNr = H00 * fa + H10 * delta_brn * da + H11 * delta_brn * (-s_min_brn);
1970 DKNr_DSe = (dH00 * fa + dH10 * delta_brn * da
1971 + dH11 * delta_brn * (-s_min_brn)) / delta_brn * inv_trap;
void piecewiseLinearTableLookup(double x, int nv, int *start, double *y, double *dy, const double *xv, const double *yv)
BCB(const double *rwork, const int *iwork=0)
void calc(const double &Sw)
void calc(const double &Sw)
void setParams(const double *rwork, const int *iwork=0)
BCM(const double *rwork, const int *iwork=0)
void calc(const PskRelation &psk, const DensityRelation &density_w, const DensityRelation &density_n)
FractionalFlowVariables(double muwIn, double munIn)
void calc(const double &Sw)
virtual void setParams(const double *rwork, const int *iwork=0)
PskRelation(const double *rwork, const int *iwork=0)
virtual void setTolerances(const double *rwork_tol)
virtual void calc_from_psic(const double &psicIn)
void calc_Se(const double &Sw)
virtual void calc_from_psic(const double &psicIn)
PskSpline(const double *rworkIn, const int *iworkIn=0)
virtual void calc(const double &Sw)
const double * splineArray
virtual void setParams(const double *rwork, const int *iwork=0)
void calc(const double &Sw)
virtual void calc_from_psic(const double &psicIn)
SimplePSK(const double *rwork, const int *iwork=0)
void calc(const double &Sw)
VGB(const double *rwork, const int *iwork=0)
virtual void setTolerances(const double *rwork_tol)
void calc(const double &Sw)
virtual void calc_from_psic(const double &psicIn)
VGM(const double *rwork, const int *iwork=0)
void calc_Se(const double &Sw)
void calc_Se_eps(const double &Se)
void setParams(const double *rwork, const int *iwork=0)
void calc(const double &Sw)
virtual void setTolerances(const double *rwork_tol)
VGMorig(const double *rwork, const int *iwork=0)
void vgm_kr_nonwetting_from_Se(const double Se_w, const double, const double n_vg, double &KNr, double &DKNr_DSe, const double Se_trap=1.0)
void bc_wetting_from_Se(const double Se, const double, const double lam, const double thetaR, const double thetaSR, double &thetaW, double &DthetaW_DSe, double &KWr, double &DKWr_DSe)
void bc_kr_nonwetting_from_Se(const double Se_w, const double, const double lam, double &KNr, double &DKNr_DSe, const double Se_trap=1.0)
void vgm_pc_from_Se(const double Se, const double alpha, const double n_vg, double &pc, double &Dpc_DSe, double &D2pc_DSe2)
void vgm_wetting_from_Se(const double Se, const double, const double n_vg, const double thetaR, const double thetaSR, double &thetaW, double &DthetaW_DSe, double &KWr, double &DKWr_DSe)
void bc_pc_from_Se(const double Se, const double alpha, const double lam, double &pc, double &Dpc_DSe, double &D2pc_DSe2)
void vgm_invert_analytic(const double m, const double rho, const double alpha, const double n_vg, const double thetaR, const double thetaSR, double &u)
void gardner_invert_analytic(const double m, const double rho, const double alpha, const double n_vg, const double thetaR, const double thetaSR, double &u)
constexpr double gardner_alphaPsiCMax
void bc_wetting(const double psiC, const double alpha, const double lam, const double thetaR, const double thetaSR, double &thetaW, double &DthetaW_DpsiC, double &KWr, double &DKWr_DpsiC, const bc_kr kr_model=bc_kr::burdine)
double bc_eta(const double lam, const bc_kr kr_model)
void vgm_wetting(const double psiC, const double alpha, const double n_vg, const double thetaR, const double thetaSR, double &thetaW, double &DthetaW_DpsiC, double &KWr, double &DKWr_DpsiC)
constexpr double gardner_alphaPsiMax
void bc_invert_newton(const double m, const double rho, const double beta, const double alpha, const double lam, const double thetaR, const double thetaSR, double &u)
void gardner_invert_newton(const double m, const double rho, const double beta, const double alpha, const double n_vg, const double thetaR, const double thetaSR, double &u)
void vgm_invert_newton(const double m, const double rho, const double beta, const double alpha, const double n_vg, const double thetaR, const double thetaSR, double &u)
void gardner_wetting(const double psiC, const double alpha, const double n_vg, const double thetaR, const double thetaSR, double &thetaW, double &DthetaW_DpsiC, double &KWr, double &DKWr_DpsiC)
void bc_invert_analytic(const double m, const double rho, const double alpha, const double lam, const double thetaR, const double thetaSR, double &u)
CompressibleN_FractionalFlowVariables(double muwIn, double munIn)
void calc(const PskRelation &psk, const DensityRelation &density_w, const DensityRelation &density_n)