OGS
RelPermNonWettingPhaseVanGenuchtenMualem.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#include <limits>
9
10#include "BaseLib/Error.h"
14
15namespace MaterialPropertyLib
16{
17double computeVanGenuchtenMualemValue(const double S_L, const double S_L_r,
18 const double S_L_max, const double m)
19{
20 const double Se = (S_L - S_L_r) / (S_L_max - S_L_r);
21 return std::sqrt(1.0 - Se) * std::pow(1.0 - std::pow(Se, 1.0 / m), 2.0 * m);
22}
23
26 const double S_L_r,
27 const double S_n_r,
28 const double m,
29 const double krel_min,
30 const double a)
31 : S_L_r_(S_L_r),
32 S_L_max_(1. - S_n_r),
33 m_(m),
34 krel_min_(krel_min),
36 a_(a)
37{
38 name_ = std::move(name);
40}
41
43 VariableArray const& variable_array,
44 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
45 double const /*dt*/) const
46{
47 const double S_L =
48 std::clamp(variable_array.liquid_saturation, S_L_r_, S_L_max_);
49
50 const double krel =
52 return std::max(krel_min_, a_ * krel);
53}
54
56 VariableArray const& variable_array, Variable const variable,
57 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
58 double const /*dt*/) const
59{
60 if (variable != Variable::liquid_saturation)
61 {
63 "RelPermNonWettingPhaseVanGenuchtenMualem::dValue is implemented "
64 "for the derivative with respect to liquid saturation only.");
65 }
66
67 const double S_L = variable_array.liquid_saturation;
68 if (S_L < S_L_r_ || S_L > S_L_for_krel_min_)
69 {
70 return 0.0;
71 }
72
73 if (std::fabs(S_L - S_L_max_) < std::numeric_limits<double>::epsilon())
74 {
75 return 0.0;
76 }
77
78 const double Se = (S_L - S_L_r_) / (S_L_max_ - S_L_r_);
79
80 const double val1 = std::sqrt(1.0 - Se);
81 const double val2 = 1.0 - std::pow(Se, 1.0 / m_);
82
83 return a_ *
84 (-0.5 * std::pow(val2, 2.0 * m_) / val1 -
85 2.0 * std::pow(Se, -1.0 + 1.0 / m_) * val1 *
86 std::pow(val2, 2.0 * m_ - 1.0)) /
87 (S_L_max_ - S_L_r_);
88}
89
92{
93 auto f = [this](double S_L) -> double
94 {
95 return computeVanGenuchtenMualemValue(S_L, this->S_L_r_, this->S_L_max_,
96 this->m_) -
97 this->krel_min_;
98 };
99
100 auto root_finder =
102 f, S_L_r_, S_L_max_);
103
104 root_finder.step(1000);
105
106 return root_finder.getResult();
107}
108} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:19
virtual PropertyDataType value() const
RelPermNonWettingPhaseVanGenuchtenMualem(std::string name, const double S_L_r, const double S_n_r, const double m, const double krel_min, const double a)
PropertyDataType dValue(VariableArray const &variable_array, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
double computeVanGenuchtenMualemValue(const double S_L, const double S_L_r, const double S_L_max, const double m)
void checkVanGenuchtenExponentRange(const double m)
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
RegulaFalsi< SubType, Function > makeRegulaFalsi(Function &&f, double const a, double const b)
Definition Root1D.h:130