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