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::temperature)
71 {
72 return 0.;
73 }
74 if (variable != Variable::capillary_pressure)
75 {
77 "SaturationVanGenuchten::dValue is implemented for derivatives "
78 "with respect to capillary pressure only.");
79 }
80
81 const double p_cap = variable_array.capillary_pressure;
82
83 if (p_cap <= 0)
84 {
85 return 0.;
86 }
87
88 double const p = p_cap / p_b_;
89 double const p_to_n = std::pow(p, n_);
90
91 double const S_eff = std::pow(p_to_n + 1., -m_);
92 double const S = S_eff * S_L_max_ - S_eff * S_L_res_ + S_L_res_;
93
94 if (S < S_L_res_ || S > S_L_max_)
95 {
96 return 0.;
97 }
98
99 double const dS_eff_dp_cap =
100 -m_ * n_ * p_to_n * S_eff / (p_cap * (p_to_n + 1.));
101 return dS_eff_dp_cap * (S_L_max_ - S_L_res_);
102}
103
105 VariableArray const& variable_array, Variable const variable1,
106 Variable const variable2, ParameterLib::SpatialPosition const& /*pos*/,
107 double const /*t*/, double const /*dt*/) const
108{
109 (void)variable1;
110 (void)variable2;
111 assert((variable1 == Variable::capillary_pressure) &&
112 (variable2 == Variable::capillary_pressure) &&
113 "SaturationVanGenuchten::d2Value is implemented for derivatives "
114 "with respect to capillary pressure only.");
115
116 const double p_cap = variable_array.capillary_pressure;
117
118 if (p_cap <= 0)
119 {
120 return 0.;
121 }
122
123 double const p = p_cap / p_b_;
124 double const p_to_n = std::pow(p, n_);
125
126 double const S_eff = std::pow(p_to_n + 1., -m_);
127 double const S = S_eff * S_L_max_ - S_eff * S_L_res_ + S_L_res_;
128
129 if (S < S_L_res_ || S > S_L_max_)
130 {
131 return 0.;
132 }
133
134 double const d2S_eff_dp_cap2 =
135 m_ * n_ * n_ * p_to_n * S_eff * (p_to_n - m_) /
136 ((p_cap * p_to_n + p_cap) * (p_cap * p_to_n + p_cap));
137 return d2S_eff_dp_cap2 * (S_L_max_ - S_L_res_);
138}
139} // 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