OGS
RelPermBrooksCorey.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 const double residual_liquid_saturation,
15 const double residual_gas_saturation,
16 const double min_relative_permeability,
17 const double exponent)
20 min_relative_permeability_(min_relative_permeability),
21 exponent_(exponent)
22{
23 name_ = std::move(name);
24
25 if (exponent_ <= 0.)
26 {
28 "RelPermBrooksCorey: exponent 'lambda' must be positive, but {} "
29 "was given.",
30 exponent_);
31 }
33 {
35 "RelPermBrooksCorey: residual_liquid_saturation must be "
36 "non-negative, but {} was given.",
38 }
40 {
42 "RelPermBrooksCorey: residual_gas_saturation must be non-negative, "
43 "but {} was given.",
45 }
47 {
49 "RelPermBrooksCorey: residual_liquid_saturation ({}) + "
50 "residual_gas_saturation ({}) must be less than 1 so that the "
51 "effective saturation range is positive.",
53 }
55 {
57 "RelPermBrooksCorey: min_relative_permeability must be in [0, 1], "
58 "but {} was given.",
60 }
61};
62
64 VariableArray const& variable_array,
65 ParameterLib::SpatialPosition const& pos, double const t,
66 double const dt) const
67{
72 auto const s_L = std::visit(
73 [&variable_array, &pos, t, dt](auto&& scale) -> double
74 {
75 return scale->property(PropertyType::saturation)
76 .template value<double>(variable_array, pos, t, dt);
77 },
78 scale_);
79
80 auto const s_L_res = residual_liquid_saturation_;
81 auto const s_L_max = 1. - residual_gas_saturation_;
82
83 auto const lambda = exponent_;
84
85 auto const s_eff = (s_L - s_L_res) / (s_L_max - s_L_res);
86
87 if (s_eff >= 1.0)
88 {
89 // fully saturated medium
90 return 1.0;
91 }
92 if (s_eff <= 0.0)
93 {
94 // dry medium
96 }
97
98 auto const k_rel_LR = std::pow(s_eff, (2. + 3. * lambda) / lambda);
99
100 return std::max(k_rel_LR, min_relative_permeability_);
101}
103 VariableArray const& variable_array, Variable const variable,
104 ParameterLib::SpatialPosition const& pos, double const t,
105 double const dt) const
106{
107 if (variable != Variable::liquid_saturation)
108 {
109 OGS_FATAL(
110 "RelPermBrooksCorey::dValue is implemented for derivatives with "
111 "respect to liquid saturation only.");
112 }
113
118 auto const s_L = std::visit(
119 [&variable_array, &pos, t, dt](auto&& scale) -> double
120 {
121 return scale->property(PropertyType::saturation)
122 .template value<double>(variable_array, pos, t, dt);
123 },
124 scale_);
125
126 auto const s_L_res = residual_liquid_saturation_;
127 auto const s_L_max = 1. - residual_gas_saturation_;
128 auto const lambda = exponent_;
129
130 auto const s_eff = (s_L - s_L_res) / (s_L_max - s_L_res);
131 // Consistency with value(): at s_eff == 1 the value is clamped to the
132 // constant 1.0 (and saturation models clamping S_L at s_L_max put whole
133 // regions exactly on this point), so the derivative there is zero.
134 if ((s_eff < 0.) || (s_eff >= 1.))
135 {
136 return 0.;
137 }
138
139 // Consistency with value(): where the min_relative_permeability clamp is
140 // active (dry range), the relative permeability is constant and its
141 // derivative is zero.
142 auto const k_rel_LR = std::pow(s_eff, (2. + 3. * lambda) / lambda);
143 if (k_rel_LR <= min_relative_permeability_)
144 {
145 return 0.;
146 }
147
148 auto const d_se_d_sL = 1. / (s_L_max - s_L_res);
149 auto const dk_rel_LRdse =
150 (3 * lambda + 2.) / lambda * std::pow(s_eff, 2. / lambda + 2.);
151
152 return dk_rel_LRdse * d_se_d_sL;
153}
154
155} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:10
virtual PropertyDataType value() const
std::variant< Medium *, Phase *, Component * > scale_
RelPermBrooksCorey(std::string name, const double, const double, const double, const double)
PropertyDataType dValue(VariableArray const &variable_array, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
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