OGS
SaturationWeightedThermalConductivity.cpp
Go to the documentation of this file.
1
13
14#include <cmath>
15#include <limits>
16#include <vector>
17
18#include "BaseLib/Error.h"
21#include "MathLib/MathTools.h"
24
25namespace MaterialPropertyLib
26{
27
28template <MeanType MeanType>
29double computeAverage(const double /*S*/, double const /*k_dry*/,
30 double const /*k_wet*/) = delete;
31
32template <MeanType MeanType>
33double computeDAverage(const double /*S*/, double const /*k_dry*/,
34 double const /*k_wet*/) = delete;
35
36// specialization
37template <>
39 double const k_dry,
40 double const k_wet)
41{
42 return k_dry * (1.0 - S) + k_wet * S;
43}
44
45template <>
47 double const k_dry,
48 double const k_wet)
49{
50 return k_wet - k_dry;
51}
52
53template <>
55 double const k_dry,
56 double const k_wet)
57{
58 return k_dry + std::sqrt(S) * (k_wet - k_dry);
59}
60
61template <>
63 double const k_dry,
64 double const k_wet)
65{
66 return 0.5 * (k_wet - k_dry) / std::sqrt(S);
67}
68
69template <>
70double computeAverage<MeanType::GEOMETRIC>(const double S, double const k_dry,
71 double const k_wet)
72{
73 return k_dry * std::pow(k_wet / k_dry, S);
74}
75
76template <>
77double computeDAverage<MeanType::GEOMETRIC>(const double S, double const k_dry,
78 double const k_wet)
79{
80 return k_dry * std::pow(k_wet / k_dry, S) * std::log(k_wet / k_dry);
81}
82
83template <MeanType MeanType, int GlobalDimension>
86 std::string name,
87 ParameterLib::Parameter<double> const& dry_thermal_conductivity,
88 ParameterLib::Parameter<double> const& wet_thermal_conductivity)
89 : dry_thermal_conductivity_(dry_thermal_conductivity),
90 wet_thermal_conductivity_(wet_thermal_conductivity)
91{
92 name_ = std::move(name);
93
95 double const t = std::numeric_limits<double>::quiet_NaN();
96
97 auto const lambda_dry = dry_thermal_conductivity_(t, pos);
98 auto const lambda_wet = wet_thermal_conductivity_(t, pos);
99
100 if (lambda_dry.size() != lambda_wet.size())
101 {
102 OGS_FATAL(
103 "In 'SaturationWeightedThermalConductivity' input data, the data "
104 "size of "
105 "dry_thermal_conductivity of '{:d}' is different from that of "
106 "dry_thermal_conductivity of '{:d}'.",
107 lambda_dry.size(), lambda_wet.size());
108 }
109
110 for (std::size_t i = 0; i < lambda_dry.size(); i++)
111 {
112 if (lambda_dry[i] > lambda_wet[i])
113 {
114 OGS_FATAL(
115 "In 'SaturationWeightedThermalConductivity', "
116 "dry_thermal_conductivity of '{:g}' is larger than "
117 "wet_thermal_conductivity of '{:g}'.",
118 lambda_dry[i], lambda_wet[i]);
119 }
120 }
121 if constexpr (MeanType == MeanType::GEOMETRIC)
122 {
123 if (lambda_dry.size() != 1 && lambda_dry.size() != GlobalDimension)
124 {
125 OGS_FATAL(
126 "The saturation weighted geometric mean"
127 "is not implemented for arbitrary anisotropic thermal "
128 "conductivities and requires to be in diagonal shape.");
129 }
130 }
131}
132
133template <MeanType MeanType, int GlobalDimension>
136 VariableArray const& variable_array,
137 ParameterLib::SpatialPosition const& pos, double const t,
138 double const /*dt*/) const
139{
140 double const S_L = variable_array.liquid_saturation;
141
142 // (S_L <= 0.0)
143 std::vector<double> lambda_data = dry_thermal_conductivity_(t, pos);
144
145 if (S_L >= 1.0)
146 {
147 lambda_data = wet_thermal_conductivity_(t, pos);
148 }
149
150 else if (S_L > 0.0 && S_L <= 1.0)
151 {
152 for (std::size_t i = 0; i < lambda_data.size(); i++)
153 {
154 lambda_data[i] = computeAverage<MeanType>(
155 S_L, lambda_data[i], wet_thermal_conductivity_(t, pos)[i]);
156 }
157 }
158
159 return fromVector(lambda_data);
160}
161
162template <MeanType MeanType, int GlobalDimension>
165 VariableArray const& variable_array, Variable const variable,
166 ParameterLib::SpatialPosition const& pos, double const t,
167 double const /*dt*/) const
168{
169 if (variable != Variable::liquid_saturation)
170 {
171 OGS_FATAL(
172 "SaturationWeightedThermalConductivity::dValue is implemented for "
173 "derivatives with respect to liquid saturation only.");
174 }
175
176 double const S_L = variable_array.liquid_saturation;
177
178 auto const lambda_dry_data = dry_thermal_conductivity_(t, pos);
179
180 std::vector<double> derivative_data(lambda_dry_data.size(), 0.0);
181 if (S_L <= 0.0 || S_L > 1.0)
182 {
183 return fromVector(derivative_data);
184 }
185 for (std::size_t i = 0; i < lambda_dry_data.size(); i++)
186 {
187 derivative_data[i] = computeDAverage<MeanType>(
188 S_L, lambda_dry_data[i], wet_thermal_conductivity_(t, pos)[i]);
189 }
190 return fromVector(derivative_data);
191}
192
208
209} // namespace MaterialPropertyLib
210// namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:26
virtual PropertyDataType value() const
Definition Property.cpp:76
Saturation dependent thermal conductivity model for soil.
SaturationWeightedThermalConductivity(std::string name, ParameterLib::Parameter< double > const &dry_thermal_conductivity, ParameterLib::Parameter< double > const &wet_thermal_conductivity)
ParameterLib::Parameter< double > const & wet_thermal_conductivity_
Thermal conductivity of soil at the fully water saturated state.
ParameterLib::Parameter< double > const & dry_thermal_conductivity_
Thermal conductivity of soil at the dry state.
PropertyDataType dValue(VariableArray const &variable_array, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
double computeAverage< MeanType::GEOMETRIC >(const double S, double const k_dry, double const k_wet)
double computeAverage< MeanType::ARITHMETIC_LINEAR >(const double S, double const k_dry, double const k_wet)
PropertyDataType fromVector(std::vector< double > const &values)
Definition Property.cpp:23
double computeDAverage< MeanType::GEOMETRIC >(const double S, double const k_dry, double const k_wet)
double computeDAverage< MeanType::ARITHMETIC_LINEAR >(const double, double const k_dry, double const k_wet)
double computeDAverage< MeanType::ARITHMETIC_SQUAREROOT >(const double S, double const k_dry, double const k_wet)
double computeDAverage(const double, double const, double const)=delete
double computeAverage< MeanType::ARITHMETIC_SQUAREROOT >(const double S, double const k_dry, double const k_wet)
double computeAverage(const double, double const, double const)=delete
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