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