OGS
SaturationVanGenuchtenWithVolumetricStrain.cpp
Go to the documentation of this file.
1
11
12#include <algorithm>
13#include <cmath>
14#include <limits>
15
16#include "BaseLib/Error.h"
18#include "MathLib/MathTools.h"
19
20namespace MaterialPropertyLib
21{
24 std::string name,
25 double const residual_liquid_saturation,
26 double const residual_gas_saturation,
27 double const exponent,
28 double const p_b,
29 double const e_0,
30 double const e_m,
31 double const a,
32 double const d_diff)
34 S_L_max_(1. - residual_gas_saturation),
35 m_(exponent),
36 p_b_(p_b),
37 e_0_(e_0),
38 e_m_(e_m),
39 a_(a),
40 d_diff_(d_diff)
41{
42 name_ = std::move(name);
43
44 if (!(m_ > 0 && m_ < 1))
45 {
46 OGS_FATAL("The exponent value m = {:g}, is out of its range of (0, 1)",
47 m_);
48 }
49}
50
52 VariableArray const& variable_array,
53 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
54 double const /*dt*/) const
55{
56 const double p_cap = variable_array.capillary_pressure;
57
58 if (p_cap <= 0)
59 {
60 return S_L_max_;
61 }
62
63 double const e_vol = variable_array.volumetric_strain;
64
65 double const n = 1. / (1. - m_);
66 double const d_e = -1 * (1 + e_0_) * e_vol / e_0_;
67 double const p_b_M = p_b_ * (1 / d_diff_);
68 double const p = p_cap / p_b_;
69 double const p_to_n = std::pow(p, n);
70 double const S_eff_mi = std::pow(p_to_n + 1., -m_);
71 double const p_M = p_cap / p_b_M;
72 double const p_to_n_M = std::pow(p_M, n);
73 double const S_eff_M = std::pow(p_to_n_M + 1., -m_);
74 double const S_eff =
75 (e_m_ * S_eff_mi + ((e_0_ - e_m_ - (a_ * d_e)) * S_eff_M)) /
76 (e_0_ - (a_ * d_e));
77 double const S = S_eff * S_L_max_ - S_eff * S_L_res_ + S_L_res_;
78
79 return std::clamp(S, S_L_res_, S_L_max_);
80}
81
83 VariableArray const& variable_array, Variable const variable,
84 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
85 double const /*dt*/) const
86{
87 if (variable != Variable::capillary_pressure)
88 {
90 "SaturationVanGenuchtenWithVolumetricStrain::dValue is implemented "
91 "for derivatives with respect to capillary pressure only.");
92 }
93 const double p_cap = variable_array.capillary_pressure;
94
95 if (p_cap <= 0)
96 {
97 return 0.;
98 }
99
100 double const e_vol = variable_array.volumetric_strain;
101
102 double const n = 1. / (1. - m_);
103 double const d_e = -1 * (1 + e_0_) * e_vol / e_0_;
104 double const p_b_M = p_b_ * (1 / d_diff_);
105 double const p = p_cap / p_b_;
106 double const p_to_n = std::pow(p, n);
107 double const S_eff_mi = std::pow(p_to_n + 1., -m_);
108 double const p_M = p_cap / p_b_M;
109 double const p_to_n_M = std::pow(p_M, n);
110 double const S_eff_M = std::pow(p_to_n_M + 1., -m_);
111 double const S_eff =
112 (e_m_ * S_eff_mi + ((e_0_ - e_m_ - (a_ * d_e)) * S_eff_M)) /
113 (e_0_ - (a_ * d_e));
114 double const S = S_eff * S_L_max_ - S_eff * S_L_res_ + S_L_res_;
115
116 if (S < S_L_res_ || S > S_L_max_)
117 {
118 return 0.;
119 }
120
121 double const dS_eff_dp_cap =
122 (-(e_m_)*n * m_ * p_to_n * std::pow(p_to_n + 1., -m_ - 1) -
123 (e_0_ - e_m_ - (a_ * d_e)) * n * m_ * p_to_n_M *
124 std::pow(p_to_n_M + 1., -m_ - 1)) /
125 ((e_0_ - (a_ * d_e)) * p_cap);
126 return dS_eff_dp_cap * (S_L_max_ - S_L_res_);
127}
128} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:26
virtual PropertyDataType value() const
Definition Property.cpp:76
SaturationVanGenuchtenWithVolumetricStrain(std::string name, double const residual_liquid_saturation, double const residual_gas_saturation, double const exponent, double const p_b, double const e_0, double const e_m, double const a, double const d_diff)
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
Definition Property.h:31