OGS
SaturationVanGenuchten.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 pressure_exponent,
18 double const saturation_exponent,
19 double const p_b)
22 m_(pressure_exponent),
23 n_(saturation_exponent),
24 p_b_(p_b)
25{
26 name_ = std::move(name);
27
28 if (!(m_ > 0 && m_ < 1))
29 {
31 "The pressure exponent value m = {:g} of van Genuchten saturation "
32 "model, is out of its range of (0, 1)",
33 m_);
34 }
35
36 if (n_ < 1)
37 {
39 "The saturation exponent value n = {:g} of van Genuchten "
40 "saturation model, is out of its range of [1, +inf)",
41 n_);
42 }
43}
44
46 VariableArray const& variable_array,
47 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
48 double const /*dt*/) const
49{
50 const double p_cap = variable_array.capillary_pressure;
51
52 if (p_cap <= 0)
53 {
54 return S_L_max_;
55 }
56
57 double const p = p_cap / p_b_;
58 double const p_to_n = std::pow(p, n_);
59
60 double const S_eff = std::pow(p_to_n + 1., -m_);
61 double const S = S_eff * S_L_max_ - S_eff * S_L_res_ + S_L_res_;
62 return std::clamp(S, S_L_res_, S_L_max_);
63}
64
66 VariableArray const& variable_array, Variable const variable,
67 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
68 double const /*dt*/) const
69{
70 if (variable != Variable::capillary_pressure)
71 {
73 "SaturationVanGenuchten::dValue is implemented for derivatives "
74 "with respect to capillary pressure only.");
75 }
76
77 const double p_cap = variable_array.capillary_pressure;
78
79 if (p_cap <= 0)
80 {
81 return 0.;
82 }
83
84 double const p = p_cap / p_b_;
85 double const p_to_n = std::pow(p, n_);
86
87 double const S_eff = std::pow(p_to_n + 1., -m_);
88 double const S = S_eff * S_L_max_ - S_eff * S_L_res_ + S_L_res_;
89
90 if (S < S_L_res_ || S > S_L_max_)
91 {
92 return 0.;
93 }
94
95 double const dS_eff_dp_cap =
96 -m_ * n_ * p_to_n * S_eff / (p_cap * (p_to_n + 1.));
97 return dS_eff_dp_cap * (S_L_max_ - S_L_res_);
98}
99
101 VariableArray const& variable_array, Variable const variable1,
102 Variable const variable2, ParameterLib::SpatialPosition const& /*pos*/,
103 double const /*t*/, double const /*dt*/) const
104{
105 (void)variable1;
106 (void)variable2;
107 assert((variable1 == Variable::capillary_pressure) &&
108 (variable2 == Variable::capillary_pressure) &&
109 "SaturationVanGenuchten::d2Value is implemented for derivatives "
110 "with respect to capillary pressure only.");
111
112 const double p_cap = variable_array.capillary_pressure;
113
114 if (p_cap <= 0)
115 {
116 return 0.;
117 }
118
119 double const p = p_cap / p_b_;
120 double const p_to_n = std::pow(p, n_);
121
122 double const S_eff = std::pow(p_to_n + 1., -m_);
123 double const S = S_eff * S_L_max_ - S_eff * S_L_res_ + S_L_res_;
124
125 if (S < S_L_res_ || S > S_L_max_)
126 {
127 return 0.;
128 }
129
130 double const d2S_eff_dp_cap2 =
131 m_ * n_ * n_ * p_to_n * S_eff * (p_to_n - m_) /
132 ((p_cap * p_to_n + p_cap) * (p_cap * p_to_n + p_cap));
133 return d2S_eff_dp_cap2 * (S_L_max_ - S_L_res_);
134}
135} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:19
virtual PropertyDataType value() const
PropertyDataType d2Value(VariableArray const &variable_array, Variable const variable1, Variable const variable2, ParameterLib::SpatialPosition const &, double const, double const) const override
Default implementation: 2nd derivative of any constant property is zero.
PropertyDataType dValue(VariableArray const &variable_array, Variable const variable, ParameterLib::SpatialPosition const &, double const, double const) const override
SaturationVanGenuchten(std::string name, double const residual_liquid_saturation, double const residual_gas_saturation, double const pressure_exponent, double const saturation_exponent, double const p_b)
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