OGS
RelPermVanGenuchten.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 min_relative_permeability_liquid,
18 double const exponent)
21 k_rel_min_(min_relative_permeability_liquid),
22 m_(exponent)
23{
24 name_ = std::move(name);
25
26 if (!(m_ > 0 && m_ < 1))
27 {
29 "The exponent value m = {:g} of van Genuchten relative "
30 "permeability model, is out of its range of (0, 1)",
31 m_);
32 }
33}
34
36 VariableArray const& variable_array,
37 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
38 double const /*dt*/) const
39{
40 double const S_L =
41 std::clamp(variable_array.liquid_saturation, S_L_res_, S_L_max_);
42
43 double const S_eff = (S_L - S_L_res_) / (S_L_max_ - S_L_res_);
44 double const v = 1. - std::pow(1. - std::pow(S_eff, 1. / m_), m_);
45 double const k_rel = std::sqrt(S_eff) * v * v;
46 return std::max(k_rel_min_, k_rel);
47}
48
50 VariableArray const& variable_array, Variable const variable,
51 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
52 double const /*dt*/) const
53{
54 if (variable != Variable::liquid_saturation)
55 {
57 "RelativePermeabilityVanGenuchten::dValue is implemented for "
58 "derivatives with respect to liquid saturation only.");
59 }
60
61 double const S_L =
62 std::clamp(variable_array.liquid_saturation, S_L_res_, S_L_max_);
63
64 double const S_eff = (S_L - S_L_res_) / (S_L_max_ - S_L_res_);
65 if (S_eff <= 0) // prevent division by zero
66 {
67 return 0.;
68 }
69
70 if (S_eff >= 1) // prevent taking root of zero
71 {
72 return 0.;
73 }
74
75 double const S_eff_to_1_over_m = std::pow(S_eff, 1. / m_);
76 double const v = 1. - std::pow(1. - S_eff_to_1_over_m, m_);
77 double const sqrt_S_eff = std::sqrt(S_eff);
78 double const k_rel = sqrt_S_eff * v * v;
79
80 if (k_rel < k_rel_min_)
81 {
82 return 0.;
83 }
84
85 return (0.5 * v * v / sqrt_S_eff +
86 2. * sqrt_S_eff * v * std::pow(1. - S_eff_to_1_over_m, m_ - 1.) *
87 S_eff_to_1_over_m / S_eff) /
89}
90
91} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:19
virtual PropertyDataType value() const
RelPermVanGenuchten(std::string name, double const residual_liquid_saturation, double const residual_gas_saturation, double const min_relative_permeability_liquid, double const exponent)
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