20 static_cast<std::underlying_type_t<LowCapillaryPressureExtension::ExtensionStrategy>
>(
31 std::underlying_type_t<LowCapillaryPressureExtension::ExtensionStrategy> strategy;
43 static_cast<std::underlying_type_t<HighCapillaryPressureExtension::ExtensionStrategy>
>(
54 std::underlying_type_t<HighCapillaryPressureExtension::ExtensionStrategy> strategy;
72 seff = 1.0 + std::pow(-alpha *
p, n);
73 return std::pow(seff, -m);
84 Real n = 1.0 / (1.0 - m);
85 Real inner = 1.0 + std::pow(-alpha *
p, n);
86 Real dinner_dp = -n * alpha * std::pow(-alpha *
p, n - 1.0);
87 Real dseff_dp = -m * std::pow(inner, -m - 1) * dinner_dp;
99 Real n = 1.0 / (1.0 - m);
100 Real inner = 1.0 + std::pow(-alpha *
p, n);
101 Real dinner_dp = -n * alpha * std::pow(-alpha *
p, n - 1.0);
102 Real d2inner_dp2 = n * (n - 1.0) * alpha * alpha * std::pow(-alpha *
p, n - 2.0);
103 Real d2seff_dp2 = m * (m + 1.0) * std::pow(inner, -m - 2.0) * std::pow(dinner_dp, 2.0) -
104 m * std::pow(inner, -m - 1.0) * d2inner_dp2;
114 else if (seff <= 0.0)
118 Real
a = std::pow(seff, -1.0 / m) - 1.0;
119 return std::min(std::pow(
a, 1.0 - m) / alpha, pc_max);
126 if (seff <= 0.0 || seff >= 1.0)
130 Real
a = std::pow(seff, -1.0 / m) - 1.0;
132 if (std::pow(
a, 1.0 - m) / alpha > pc_max)
135 return (m - 1.0) * std::pow(
a, -m) * std::pow(seff, -1.0 - 1.0 / m) / m / alpha;
142 if (seff <= 0.0 || seff >= 1.0)
146 Real
a = std::pow(seff, -1.0 / m) - 1.0;
148 if (std::pow(
a, 1.0 - m) / alpha > pc_max)
152 Real d2pc = -std::pow(
a, -1.0 - m) * std::pow(seff, -2.0 - 2.0 / m) +
153 ((1.0 + m) / m) * std::pow(
a, -m) * std::pow(seff, -1.0 / m - 2.0);
154 d2pc *= (1.0 - m) / m / alpha;
164 if (seff <= 0.0 || seff >= 1.0)
167 const Real
a = 1.0 - std::pow(seff, 1.0 / m);
168 const Real da = -1.0 / m * std::pow(seff, 1.0 / m - 1.0);
169 const Real
b = 1.0 - std::pow(
a, m);
170 const Real
db = -m * std::pow(
a, m - 1.0) * da;
172 return 0.5 * std::pow(seff, -0.5) * Utility::pow<2>(
b) + 2.0 * std::sqrt(seff) *
b *
db;
179 if (seff <= 0.0 || seff >= 1.0)
182 const Real
a = 1.0 - std::pow(seff, 1.0 / m);
183 const Real da = -1.0 / m * std::pow(seff, 1.0 / m - 1.0);
184 const Real d2a = -(1.0 / m) * (1.0 / m - 1.0) * std::pow(seff, 1.0 / m - 2.0);
185 const Real
b = 1.0 - std::pow(
a, m);
186 const Real
db = -m * std::pow(
a, m - 1.0) * da;
187 const Real d2b = -m * (m - 1.0) * std::pow(
a, m - 2.0) * da * da - m * std::pow(
a, m - 1.0) * d2a;
189 return -0.25 * std::pow(seff, -1.5) * Utility::pow<2>(
b) + 2.0 * std::pow(seff, -0.5) *
b *
db +
190 2.0 * std::sqrt(seff) *
db *
db + 2.0 * std::sqrt(seff) *
b * d2b;
197 if (seff <= 0.0 || seff >= 1.0)
200 const Real
a = std::pow(1.0 - seff, 1.0 / m);
201 const Real da = -1.0 / m *
a / (1.0 - seff);
202 const Real
b = std::pow(1.0 -
a, 2.0 * m);
203 const Real
db = -2.0 * m *
b / (1.0 -
a) * da;
205 return 0.5 * std::pow(seff, -0.5) *
b + std::sqrt(seff) *
db;
212 if (seff <= 0.0 || seff >= 1.0)
215 const Real
a = std::pow(1.0 - seff, 1.0 / m);
216 const Real da = -1.0 / m *
a / (1.0 - seff);
217 const Real d2a = 1.0 / m * (1.0 / m - 1) * std::pow(1.0 - seff, 1.0 / m - 2.0);
218 const Real
b = std::pow(1.0 -
a, 2.0 * m);
219 const Real
db = -2.0 * m *
b / (1.0 -
a) * da;
221 -2.0 * m * (
db / (1.0 -
a) * da +
b * Utility::pow<2>(da / (1.0 -
a)) +
b / (1.0 -
a) * d2a);
223 return -0.25 * std::pow(seff, -1.5) *
b + std::pow(seff, -0.5) *
db + std::sqrt(seff) * d2b;
241 pc = low_ext.
Pc + low_ext.
dPc * 0.5 * (sl * sl - low_ext.
S * low_ext.
S) / low_ext.
S;
244 pc = low_ext.
Pc * std::exp(low_ext.
dPc * (sl - low_ext.
S) / low_ext.
Pc);
261 const Real expon = -high_ext.
dPc / high_ext.
Pc * (1.0 - high_ext.
S);
262 pc = high_ext.
Pc * std::pow((1.0 - sl) / (1.0 - high_ext.
S), expon);
271 const Real seff = (sl - slmin) / (1.0 - sgrdel - slmin);
274 else if (seff <= 0.0)
278 const Real
a = std::pow(seff, n / (1.0 - n)) - 1.0;
279 pc = (1.0 / alpha) * std::pow(
a, 1.0 / n);
299 dpc = low_ext.
dPc * sl / low_ext.
S;
302 dpc = low_ext.
dPc * std::exp(low_ext.
dPc * (sl - low_ext.
S) / low_ext.
Pc);
319 const Real expon = -high_ext.
dPc / high_ext.
Pc * (1.0 - high_ext.
S);
320 dpc = high_ext.
dPc * std::pow((1.0 - sl) / (1.0 - high_ext.
S), expon - 1.0);
329 const Real seff = (sl - slmin) / (1.0 - sgrdel - slmin);
332 else if (seff <= 0.0)
336 const Real
a = std::pow(seff, n / (1.0 - n)) - 1.0;
337 const Real dseff = 1.0 / (1.0 - sgrdel - slmin);
338 const Real dpc_dseff = (1.0 / alpha / (1.0 - n)) * std::pow(
a, 1.0 / n - 1.0) *
339 std::pow(seff, n / (1.0 - n) - 1.0);
340 dpc = dpc_dseff * dseff;
360 d2pc = low_ext.
dPc / low_ext.
S;
363 d2pc = std::pow(low_ext.
dPc, 2) / low_ext.
Pc *
364 std::exp(low_ext.
dPc * (sl - low_ext.
S) / low_ext.
Pc);
381 const Real expon = -high_ext.
dPc / high_ext.
Pc * (1.0 - high_ext.
S);
382 d2pc = high_ext.
dPc * (1.0 - expon) / (1.0 - high_ext.
S) *
383 std::pow((1.0 - sl) / (1.0 - high_ext.
S), expon - 2.0);
392 const Real seff = (sl - slmin) / (1.0 - sgrdel - slmin);
395 else if (seff <= 0.0)
399 const Real
a = std::pow(seff, n / (1.0 - n)) - 1.0;
400 const Real dseff = 1.0 / (1.0 - sgrdel - slmin);
401 const Real d2pc_dseff =
402 (1.0 / alpha / (1.0 - n)) *
403 (std::pow(
a, 1.0 / n - 2.0) * std::pow(seff, 2.0 * (n / (1.0 - n) - 1.0)) +
404 (n / (1.0 - n) - 1.0) * std::pow(
a, 1.0 / n - 1.0) * std::pow(seff, n / (1.0 - n) - 2.0));
405 d2pc = d2pc_dseff * dseff * dseff;
428 const Real s2 = low_ext.
S * low_ext.
S + 2.0 * (pc - low_ext.
Pc) * low_ext.
S / low_ext.
dPc;
439 const Real ss = low_ext.
S + std::log(pc / low_ext.
Pc) * low_ext.
Pc / low_ext.
dPc;
453 if (pc < high_ext.
Pc)
459 const Real expon = -high_ext.
dPc / high_ext.
Pc * (1.0 - high_ext.
S);
460 s = 1.0 - std::pow(pc / high_ext.
Pc, 1.0 / expon) * (1.0 - high_ext.
S);
468 if (pc == std::numeric_limits<Real>::max())
472 const Real seffpow = 1.0 + std::pow(pc * alpha, n);
473 const Real seff = std::pow(seffpow, (1.0 - n) / n);
474 s = (1.0 - sgrdel - slmin) * seff + slmin;
497 const Real s2 = low_ext.
S * low_ext.
S + 2.0 * (pc - low_ext.
Pc) * low_ext.
S / low_ext.
dPc;
504 const Real ds2 = 2.0 * low_ext.
S / low_ext.
dPc;
505 ds = 0.5 * ds2 / std::sqrt(s2);
511 const Real s = low_ext.
S + std::log(pc / low_ext.
Pc) * low_ext.
Pc / low_ext.
dPc;
517 ds = low_ext.
Pc / pc / low_ext.
dPc;
525 if (pc < high_ext.
Pc)
531 const Real expon = -high_ext.
dPc / high_ext.
Pc * (1.0 - high_ext.
S);
532 ds = -(1.0 - high_ext.
S) / pc / expon * std::pow(pc / high_ext.
Pc, 1.0 / expon);
540 if (pc == std::numeric_limits<Real>::max())
544 const Real seffpow = 1.0 + std::pow(pc * alpha, n);
545 const Real dseffpow = n * (seffpow - 1.0) / pc;
546 const Real seff = std::pow(seffpow, (1.0 - n) / n);
547 const Real dseff = (1.0 - n) / n * seff / seffpow * dseffpow;
548 ds = (1.0 - sgrdel - slmin) * dseff;
571 const Real s2 = low_ext.
S * low_ext.
S + 2.0 * (pc - low_ext.
Pc) * low_ext.
S / low_ext.
dPc;
578 const Real ds2 = 2.0 * low_ext.
S / low_ext.
dPc;
579 d2s = -0.25 * ds2 * ds2 / std::pow(s2, 1.5);
585 const Real s = low_ext.
S + std::log(pc / low_ext.
Pc) * low_ext.
Pc / low_ext.
dPc;
591 d2s = -low_ext.
Pc / std::pow(pc, 2.0) / low_ext.
dPc;
599 if (pc < high_ext.
Pc)
605 const Real expon = -high_ext.
dPc / high_ext.
Pc * (1.0 - high_ext.
S);
606 d2s = -(1.0 - high_ext.
S) * (1.0 / expon) * (1.0 / expon - 1.0) /
607 std::pow(high_ext.
Pc, 2.0) * std::pow(pc / high_ext.
Pc, 1.0 / expon - 2.0);
615 if (pc == std::numeric_limits<Real>::max())
619 const Real seffpow = 1.0 + std::pow(pc * alpha, n);
620 const Real dseffpow = n * (seffpow - 1.0) / pc;
621 const Real d2seffpow = (n - 1.0) * dseffpow / pc;
622 const Real seff = std::pow(seffpow, (1.0 - n) / n);
623 const Real dseff = (1.0 - n) / n * seff / seffpow * dseffpow;
626 (dseff * dseffpow - seff * dseffpow * dseffpow / seffpow + seff * d2seffpow) / seffpow;
627 d2s = (1.0 - sgrdel - slmin) * d2seff;
639 Real upper_liquid_param,
647 const Real sl_bar = (sl - slr) / (1.0 - slr);
652 if (sgrdel == 0.0 || sl <= sldel)
653 a = std::pow(1.0 - std::pow(sl_bar, 1.0 / m), m);
659 const Real my_sldel = (sldel < slr) ? slr : sldel;
660 const Real my_sgrdel = (sldel < slr) ? sgrmax : sgrdel;
661 if (sl >= 1.0 - 0.5 * my_sgrdel)
665 a = std::pow(1.0 - std::pow(sl_bar, 1.0 / m), m);
667 else if (sl > upper_liquid_param * (1.0 - my_sgrdel))
672 sl, upper_liquid_param * (1.0 - my_sgrdel), y0, y0p, 1.0 - 0.5 * my_sgrdel, y1, y1p);
677 const Real sl_bar_del = (my_sldel - slr) / (1.0 - slr);
678 const Real s_gt_bar =
679 my_sgrdel * (sl - my_sldel) / (1.0 - slr) / (1.0 - my_sldel - my_sgrdel);
680 a = (1 - s_gt_bar / (1.0 - sl_bar_del)) *
681 std::pow(1.0 - std::pow(sl_bar + s_gt_bar, 1.0 / m), m);
682 b = s_gt_bar / (1.0 - sl_bar_del) * std::pow(1.0 - std::pow(sl_bar_del, 1.0 / m), m);
685 return std::sqrt(sl_bar) * Utility::pow<2>(1.0 -
a -
b);
695 Real upper_liquid_param,
704 return std::numeric_limits<Real>::max();
705 const Real sl_bar = (sl - slr) / (1.0 - slr);
706 const Real sl_bar_prime = 1.0 / (1.0 - slr);
713 if (sgrdel == 0.0 || sl <= sldel)
715 const Real
c = std::pow(sl_bar, 1.0 / m);
716 const Real dc_dsbar =
c / m / sl_bar;
717 a = std::pow(1.0 -
c, m);
718 const Real da_dsbar = -m *
a / (1.0 -
c) * dc_dsbar;
719 a_prime = da_dsbar * sl_bar_prime;
726 const Real my_sldel = (sldel < slr) ? slr : sldel;
727 const Real my_sgrdel = (sldel < slr) ? sgrmax : sgrdel;
728 if (sl >= 1.0 - 0.5 * my_sgrdel)
732 const Real
c = std::pow(sl_bar, 1.0 / m);
733 const Real dc_dsbar =
c / m / sl_bar;
734 a = std::pow(1.0 -
c, m);
735 const Real da_dsbar = -m *
a / (1.0 -
c) * dc_dsbar;
736 a_prime = da_dsbar * sl_bar_prime;
738 else if (sl > upper_liquid_param * (1.0 - my_sgrdel))
743 sl, upper_liquid_param * (1.0 - my_sgrdel), y0, y0p, 1.0 - 0.5 * my_sgrdel, y1, y1p);
748 const Real sl_bar_del = (my_sldel - slr) / (1.0 - slr);
749 const Real s_gt_bar =
750 my_sgrdel * (sl - my_sldel) / (1.0 - slr) / (1.0 - my_sldel - my_sgrdel);
751 const Real s_gt_bar_prime = my_sgrdel / (1.0 - slr) / (1.0 - my_sldel - my_sgrdel);
752 const Real
c = std::pow(sl_bar + s_gt_bar, 1.0 / m);
753 const Real c_prime =
c / m / (sl_bar + s_gt_bar) * (sl_bar_prime + s_gt_bar_prime);
754 a = (1 - s_gt_bar / (1.0 - sl_bar_del)) * std::pow(1.0 -
c, m);
756 -s_gt_bar_prime / (1.0 - sl_bar_del) * std::pow(1.0 -
c, m) - m *
a / (1.0 -
c) * c_prime;
757 b = s_gt_bar / (1.0 - sl_bar_del) * std::pow(1.0 - std::pow(sl_bar_del, 1.0 / m), m);
758 b_prime = s_gt_bar_prime *
b / s_gt_bar;
761 const Real kr = std::sqrt(sl_bar) * Utility::pow<2>(1.0 -
a -
b);
762 return 0.5 * kr / sl_bar * sl_bar_prime -
763 std::sqrt(sl_bar) * 2.0 * (1.0 -
a -
b) * (a_prime + b_prime);
784 if (sl > 1.0 - sgrdel)
786 const Real sl_bar = (sl - slr) / (1.0 - slr);
788 if (sgrdel != 0.0 && sl > sldel)
794 const Real my_sldel = (sldel < slr) ? slr : sldel;
795 const Real my_sgrdel = (sldel < slr) ? sgrmax : sgrdel;
796 s_gt_bar = my_sgrdel * (sl - my_sldel) / (1.0 - slr) / (1.0 - my_sldel - my_sgrdel);
799 if (sl_bar + s_gt_bar < 1.0)
802 const Real
a = std::pow(1.0 - (sl_bar + s_gt_bar), gamma);
803 const Real
c = std::pow(sl_bar + s_gt_bar, 1.0 / m);
804 const Real
b = std::pow(1.0 -
c, 2.0 * m);
805 kr = k_rg_max *
a *
b;
828 if (sl > 1.0 - sgrdel)
830 const Real sl_bar = (sl - slr) / (1.0 - slr);
831 const Real sl_bar_prime = 1.0 / (1.0 - slr);
833 Real s_gt_bar_prime = 0.0;
834 if (sgrdel != 0.0 && sl > sldel)
840 const Real my_sldel = (sldel < slr) ? slr : sldel;
841 const Real my_sgrdel = (sldel < slr) ? sgrmax : sgrdel;
842 s_gt_bar = my_sgrdel * (sl - my_sldel) / (1.0 - slr) / (1.0 - my_sldel - my_sgrdel);
843 s_gt_bar_prime = my_sgrdel / (1.0 - slr) / (1.0 - my_sldel - my_sgrdel);
846 if (sl_bar + s_gt_bar < 1.0)
849 const Real
a = std::pow(1.0 - (sl_bar + s_gt_bar), gamma);
850 const Real a_prime = -gamma *
a / (1.0 - (sl_bar + s_gt_bar)) * (sl_bar_prime + s_gt_bar_prime);
851 const Real
c = std::pow(sl_bar + s_gt_bar, 1.0 / m);
853 (
c == 0 ? 0.0 :
c / m / (sl_bar + s_gt_bar) * (sl_bar_prime + s_gt_bar_prime));
854 const Real
b = std::pow(1.0 -
c, 2.0 * m);
855 const Real b_prime = -2.0 * m *
b / (1.0 -
c) * c_prime;
856 kr_prime = k_rg_max * (
a * b_prime + a_prime *
b);
const GeochemicalDatabaseReader db("database/moose_testdb.json", true, true, false)
Real dcubic(Real x, Real x0, Real y0, Real y0p, Real x1, Real y1, Real y1p)
Derivative of cubic function, f(x), with respect to x.
Real cubic(Real x, Real x0, Real y0, Real y0p, Real x1, Real y1, Real y1p)
Cubic function f(x) that satisfies f(x0) = y0 f'(x0) = y0p f(x1) = y1 f'(x1) = y1p.
van Genuchten effective saturation, capillary pressure and relative permeability functions.
Real d2saturationHys(Real pc, Real slmin, Real sgrdel, Real alpha, Real n, const LowCapillaryPressureExtension &low_ext=LowCapillaryPressureExtension(), const HighCapillaryPressureExtension &high_ext=HighCapillaryPressureExtension())
Second derivative of Hysteretic saturation function with respect to pc.
void dataLoad(std::istream &stream, LowCapillaryPressureExtension &extension, void *context)
Real d2capillaryPressureHys(Real sl, Real slmin, Real sgrdel, Real alpha, Real n, const LowCapillaryPressureExtension &low_ext=LowCapillaryPressureExtension(), const HighCapillaryPressureExtension &high_ext=HighCapillaryPressureExtension())
Second derivative of capillaryPressureHys with respect to sl.
Real drelativePermeabilityNWHys(Real sl, Real slr, Real sgrdel, Real sgrmax, Real sldel, Real m, Real gamma, Real k_rg_max, Real y0p)
Derivative of hysteretic relative permeability for gas with respect to the liquid saturation.
Real dRelativePermeability(Real seff, Real m)
Derivative of relative permeability with respect to effective saturation.
void dataStore(std::ostream &stream, LowCapillaryPressureExtension &extension, void *context)
Real saturationHys(Real pc, Real slmin, Real sgrdel, Real alpha, Real n, const LowCapillaryPressureExtension &low_ext=LowCapillaryPressureExtension(), const HighCapillaryPressureExtension &high_ext=HighCapillaryPressureExtension())
Hysteretic saturation function (Eqn(1) of Doughty2007) with extensions (page5 and Fig1 of Doughty2008...
Real relativePermeabilityNWHys(Real sl, Real slr, Real sgrdel, Real sgrmax, Real sldel, Real m, Real gamma, Real k_rg_max, Real y0p)
Hysteretic relative permeability for gas.
Real d2EffectiveSaturation(Real p, Real alpha, Real m)
Second derivative of effective saturation wrt porepressure.
Real dEffectiveSaturation(Real p, Real alpha, Real m)
Derivative of effective saturation wrt porepressure.
Real dCapillaryPressure(Real seff, Real alpha, Real m, Real pc_max)
Derivative of capillary pressure wrt effective saturation.
Real capillaryPressureHys(Real sl, Real slmin, Real sgrdel, Real alpha, Real n, const LowCapillaryPressureExtension &low_ext=LowCapillaryPressureExtension(), const HighCapillaryPressureExtension &high_ext=HighCapillaryPressureExtension())
Hysteretic capillary pressure function (Eqn(1) of Doughty2007) with extensions (page5 and Fig1 of Dou...
Real drelativePermeabilityHys(Real sl, Real slr, Real sgrdel, Real sgrmax, Real sldel, Real m, Real upper_liquid_param, Real y0, Real y0p, Real y1, Real y1p)
Derivative of Hysteretic relative permeability for liquid, with respect to liquid saturation.
Real capillaryPressure(Real seff, Real alpha, Real m, Real pc_max)
Capillary pressure as a function of effective saturation.
Real dcapillaryPressureHys(Real sl, Real slmin, Real sgrdel, Real alpha, Real n, const LowCapillaryPressureExtension &low_ext=LowCapillaryPressureExtension(), const HighCapillaryPressureExtension &high_ext=HighCapillaryPressureExtension())
Derivative of capillaryPressureHys with respect to sl.
Real d2CapillaryPressure(Real seff, Real alpha, Real m, Real pc_max)
Second derivative of capillary pressure wrt effective saturation.
Real effectiveSaturation(Real p, Real alpha, Real m)
Effective saturation as a function of porepressure.
Real relativePermeabilityHys(Real sl, Real slr, Real sgrdel, Real sgrmax, Real sldel, Real m, Real upper_liquid_param, Real y0, Real y0p, Real y1, Real y1p)
Hysteretic relative permeability for liquid.
Real d2RelativePermeabilityNW(Real seff, Real m)
Second derivative of relative permeability for a non-wetting phase with respect to effective saturati...
Real dsaturationHys(Real pc, Real slmin, Real sgrdel, Real alpha, Real n, const LowCapillaryPressureExtension &low_ext=LowCapillaryPressureExtension(), const HighCapillaryPressureExtension &high_ext=HighCapillaryPressureExtension())
Derivative of Hysteretic saturation function with respect to pc.
Real d2RelativePermeability(Real seff, Real m)
Second derivative of relative permeability with respect to effective saturation.
Real dRelativePermeabilityNW(Real seff, Real m)
Derivative of relative permeability for a non-wetting phase with respect to effective saturation.
Parameters associated with the extension of the hysteretic wetting capillary pressure function to hig...
ExtensionStrategy strategy
Parameters associated with the extension of the hysteretic capillary pressure function to low saturat...
ExtensionStrategy strategy