OGS
CapillaryPressureVanGenuchten.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
6#include <algorithm>
7#include <cmath>
8
10
11namespace MaterialPropertyLib
12{
14 std::string name,
15 double const residual_liquid_saturation,
16 double const residual_gas_saturation,
17 double const exponent,
18 double const p_b,
19 double const maximum_capillary_pressure)
22 m_(exponent),
23 p_b_(p_b),
24 p_cap_max_(maximum_capillary_pressure)
25{
26 name_ = std::move(name);
27
29 {
31 "Van Genuchten capillary pressure model: The residual liquid "
32 "saturation value S_L_res = {:g} is out of admissible range [0, "
33 "1].",
34 S_L_res_);
35 }
37 {
39 "Van Genuchten capillary pressure model: The maximum liquid "
40 "saturation value S_L_max = {:g} is out of admissible range [0, "
41 "1].",
42 S_L_max_);
43 }
44 if (S_L_res_ >= S_L_max_)
45 {
47 "Van Genuchten capillary pressure model: The maximum liquid "
48 "saturation S_L_max = {:g} must not be less or equal to the "
49 "residual liquid saturion S_L_res = {:g}.",
51 }
52 if (!(m_ > 0 && m_ < 1))
53 {
55 "Van Genuchten capillary pressure model: The exponent value m = "
56 "{:g} is out of of admissible range (0, 1).",
57 m_);
58 }
59 if (p_b_ <= 0)
60 {
62 "Van Genuchten capillary pressure model: The pressure scaling "
63 "value p_b = {:g} must be positive.",
64 p_b_);
65 }
66 if (p_cap_max_ < 0)
67 {
69 "Van Genuchten capillary pressure model: The maximum capillary "
70 "pressure value p_cap_max = {:g} must be non-negative.",
72 }
73}
74
76 VariableArray const& variable_array,
77 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
78 double const /*dt*/) const
79{
80 double const S_L = variable_array.liquid_saturation;
81
82 if (S_L <= S_L_res_)
83 {
84 return p_cap_max_;
85 }
86
87 if (S_L >= S_L_max_)
88 {
89 return 0.;
90 }
91
92 double const S_eff = (S_L - S_L_res_) / (S_L_max_ - S_L_res_);
93 assert(0 <= S_eff && S_eff <= 1);
94
95 double const p_cap =
96 p_b_ * std::pow(std::pow(S_eff, -1.0 / m_) - 1.0, 1.0 - m_);
97 assert(p_cap > 0);
98 return std::min(p_cap, p_cap_max_);
99}
100
102 VariableArray const& variable_array, Variable const variable,
103 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
104 double const /*dt*/) const
105{
106 if (variable != Variable::liquid_saturation)
107 {
108 OGS_FATAL(
109 "CapillaryPressureVanGenuchten::dValue is implemented for "
110 "derivatives with respect to liquid saturation only.");
111 }
112
113 double const S_L = variable_array.liquid_saturation;
114
115 if (S_L <= S_L_res_)
116 {
117 return 0.;
118 }
119
120 if (S_L >= S_L_max_)
121 {
122 return 0.;
123 }
124
125 double const S_eff = (S_L - S_L_res_) / (S_L_max_ - S_L_res_);
126
127 assert(0 < S_eff && S_eff < 1.0);
128
129 double const val1 = std::pow(S_eff, -1.0 / m_);
130 double const p_cap = p_b_ * std::pow(val1 - 1.0, 1.0 - m_);
131 if (p_cap >= p_cap_max_)
132 {
133 return 0.;
134 }
135
136 double const val2 = std::pow(val1 - 1.0, -m_);
137 return p_b_ * (m_ - 1.0) * val1 * val2 / (m_ * (S_L - S_L_res_));
138}
139} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:19
double const S_L_res_
Residual saturation of liquid phase.
PropertyDataType dValue(VariableArray const &variable_array, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
double const S_L_max_
Maximum saturation of liquid phase.
CapillaryPressureVanGenuchten(std::string name, double const residual_liquid_saturation, double const residual_gas_saturation, double const exponent, double const p_b, double const maximum_capillary_pressure)
virtual PropertyDataType value() const
std::variant< double, Eigen::Matrix< double, 2, 1 >, Eigen::Matrix< double, 3, 1 >, Eigen::Matrix< double, 2, 2 >, Eigen::Matrix< double, 3, 3 >, Eigen::Matrix< double, 4, 1 >, Eigen::Matrix< double, 6, 1 >, Eigen::MatrixXd > PropertyDataType