OGS
SoilThermalConductivitySomerton.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"
19 #include "MaterialLib/MPL/Medium.h"
24 #include "MathLib/KelvinVector.h"
25 #include "MathLib/MathTools.h"
27 #include "ParameterLib/Parameter.h"
29 
30 namespace MaterialPropertyLib
31 {
32 //
33 // For 1D problems:
34 //
35 template <>
37  std::string name,
38  ParameterLib::Parameter<double> const& dry_thermal_conductivity,
39  ParameterLib::Parameter<double> const& wet_thermal_conductivity,
40  ParameterLib::CoordinateSystem const* const local_coordinate_system)
41  : dry_thermal_conductivity_(dry_thermal_conductivity),
42  wet_thermal_conductivity_(wet_thermal_conductivity),
43  local_coordinate_system_(local_coordinate_system)
44 {
45  name_ = std::move(name);
46 
48  double const t = std::numeric_limits<double>::quiet_NaN();
49 
50  double const lambda_try = dry_thermal_conductivity_(t, pos)[0];
51  double const lambda_wet = wet_thermal_conductivity_(t, pos)[0];
52 
53  if (lambda_try > lambda_wet)
54  {
55  OGS_FATAL(
56  "In 'SoilThermalConductivitySomerton', "
57  "dry_thermal_conductivity of '{:g}' is larger than "
58  "wet_thermal_conductivity of '{:g}'.",
59  lambda_try, lambda_wet);
60  }
61 }
62 template <>
64  VariableArray const& variable_array,
65  ParameterLib::SpatialPosition const& pos, double const t,
66  double const /*dt*/) const
67 {
68  double const S_L = std::get<double>(
69  variable_array[static_cast<int>(Variable::liquid_saturation)]);
70 
71  if (S_L <= 0.0)
72  {
73  return dry_thermal_conductivity_(t, pos)[0];
74  }
75 
76  if (S_L > 1.0)
77  {
78  return wet_thermal_conductivity_(t, pos)[0];
79  }
80 
81  double const lambda_dry = dry_thermal_conductivity_(t, pos)[0];
82 
83  return lambda_dry +
84  std::sqrt(S_L) * (wet_thermal_conductivity_(t, pos)[0] - lambda_dry);
85 }
86 
87 template <>
89  VariableArray const& variable_array, Variable const variable,
90  ParameterLib::SpatialPosition const& pos, double const t,
91  double const /*dt*/) const
92 {
93  if (variable != Variable::liquid_saturation)
94  {
95  OGS_FATAL(
96  "SoilThermalConductivitySomerton::dValue is implemented for "
97  "derivatives with respect to liquid saturation only.");
98  }
99 
100  double const S_L = std::get<double>(
101  variable_array[static_cast<int>(Variable::liquid_saturation)]);
102 
103  if (S_L <= 0.0 || S_L > 1.0)
104  {
105  return 0.0;
106  }
107 
108  double const lambda_dry = dry_thermal_conductivity_(t, pos)[0];
109  double const lambda_wet = wet_thermal_conductivity_(t, pos)[0];
110 
111  return 0.5 * (lambda_wet - lambda_dry) / std::sqrt(S_L);
112 }
113 
114 //
115 // For 2D and 3D problems:
116 //
117 template <int GlobalDimension>
120  std::string name,
121  ParameterLib::Parameter<double> const& dry_thermal_conductivity,
122  ParameterLib::Parameter<double> const& wet_thermal_conductivity,
123  ParameterLib::CoordinateSystem const* const local_coordinate_system)
124  : dry_thermal_conductivity_(dry_thermal_conductivity),
125  wet_thermal_conductivity_(wet_thermal_conductivity),
126  local_coordinate_system_(local_coordinate_system)
127 {
128  name_ = std::move(name);
129 
131  double const t = std::numeric_limits<double>::quiet_NaN();
132 
133  auto const lambda_try = dry_thermal_conductivity_(t, pos);
134  auto const lambda_wet = wet_thermal_conductivity_(t, pos);
135 
136  if (lambda_try.size() != lambda_wet.size())
137  {
138  OGS_FATAL(
139  "In 'SoilThermalConductivitySomerton' input data, the data size of "
140  "dry_thermal_conductivity of '{:d}' is different from that of "
141  "dry_thermal_conductivity of '{:d}'.",
142  lambda_try.size(), lambda_wet.size());
143  }
144 
145  for (std::size_t i = 0; i < lambda_try.size(); i++)
146  {
147  if (lambda_try[i] > lambda_wet[i])
148  {
149  OGS_FATAL(
150  "In 'SoilThermalConductivitySomerton', "
151  "dry_thermal_conductivity of '{:g}' is larger than "
152  "wet_thermal_conductivity of '{:g}'.",
153  lambda_try[i], lambda_wet[i]);
154  }
155  }
156 }
157 
158 template <int GlobalDimension>
160  VariableArray const& variable_array,
161  ParameterLib::SpatialPosition const& pos, double const t,
162  double const /*dt*/) const
163 {
164  double const S_L = std::get<double>(
165  variable_array[static_cast<int>(Variable::liquid_saturation)]);
166 
167  // (S_L <= 0.0)
168  std::vector<double> lambda_data = dry_thermal_conductivity_(t, pos);
169 
170  if (S_L > 1.0)
171  {
172  lambda_data = wet_thermal_conductivity_(t, pos);
173  }
174 
175  if (S_L > 0.0 && S_L <= 1.0)
176  {
177  auto const lambda_wet_data = wet_thermal_conductivity_(t, pos);
178 
179  for (std::size_t i = 0; i < lambda_data.size(); i++)
180  {
181  lambda_data[i] +=
182  std::sqrt(S_L) * (lambda_wet_data[i] - lambda_data[i]);
183  }
184  }
185 
186  // Local coordinate transformation is only applied for the case that the
187  // initial intrinsic permeability is given with orthotropic assumption.
188  if (local_coordinate_system_ && (lambda_data.size() == GlobalDimension))
189  {
190  Eigen::Matrix<double, GlobalDimension, GlobalDimension> const e =
191  local_coordinate_system_->transformation<GlobalDimension>(pos);
192  Eigen::Matrix<double, GlobalDimension, GlobalDimension> k =
193  Eigen::Matrix<double, GlobalDimension, GlobalDimension>::Zero();
194 
195  for (int i = 0; i < GlobalDimension; ++i)
196  {
197  Eigen::Matrix<double, GlobalDimension, GlobalDimension> const
198  ei_otimes_ei = e.col(i) * e.col(i).transpose();
199 
200  k += lambda_data[i] * ei_otimes_ei;
201  }
202  return k;
203  }
204 
205  return fromVector(lambda_data);
206 }
207 
208 template <int GlobalDimension>
210  VariableArray const& variable_array, Variable const variable,
211  ParameterLib::SpatialPosition const& pos, double const t,
212  double const /*dt*/) const
213 {
214  if (variable != Variable::liquid_saturation)
215  {
216  OGS_FATAL(
217  "SoilThermalConductivitySomerton::dValue is implemented for "
218  "derivatives with respect to liquid saturation only.");
219  }
220 
221  double const S_L = std::get<double>(
222  variable_array[static_cast<int>(Variable::liquid_saturation)]);
223 
224  if (S_L <= 0.0 || S_L > 1.0)
225  {
226  Eigen::Matrix<double, GlobalDimension, GlobalDimension> zero =
227  Eigen::Matrix<double, GlobalDimension, GlobalDimension>::Zero();
228  return zero;
229  }
230 
231  auto const lambda_dry_data = dry_thermal_conductivity_(t, pos);
232  auto const lambda_wet_data = wet_thermal_conductivity_(t, pos);
233 
234  std::vector<double> derivative_data;
235  derivative_data.reserve(lambda_dry_data.size());
236  for (std::size_t i = 0; i < lambda_dry_data.size(); i++)
237  {
238  derivative_data.emplace_back(
239  0.5 * (lambda_wet_data[i] - lambda_dry_data[i]) / std::sqrt(S_L));
240  }
241 
242  // Local coordinate transformation is only applied for the case that the
243  // initial intrinsic permeability is given with orthotropic assumption.
244  if (local_coordinate_system_ && (derivative_data.size() == GlobalDimension))
245  {
246  Eigen::Matrix<double, GlobalDimension, GlobalDimension> const e =
247  local_coordinate_system_->transformation<GlobalDimension>(pos);
248  Eigen::Matrix<double, GlobalDimension, GlobalDimension> k =
249  Eigen::Matrix<double, GlobalDimension, GlobalDimension>::Zero();
250 
251  for (int i = 0; i < GlobalDimension; ++i)
252  {
253  Eigen::Matrix<double, GlobalDimension, GlobalDimension> const
254  ei_otimes_ei = e.col(i) * e.col(i).transpose();
255 
256  k += derivative_data[i] * ei_otimes_ei;
257  }
258  return k;
259  }
260 
261  return fromVector(derivative_data);
262 }
263 
266 
267 } // namespace MaterialPropertyLib
268 // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition: Error.h:26
virtual PropertyDataType value() const
Definition: Property.cpp:72
A saturation dependent thermal conductivity model for soil.
ParameterLib::Parameter< double > const & dry_thermal_conductivity_
Thermal conductivity of soil at the dry state.
ParameterLib::Parameter< double > const & wet_thermal_conductivity_
Thermal conductivity of soil at the fully water saturated state.
SoilThermalConductivitySomerton(std::string name, ParameterLib::Parameter< double > const &dry_thermal_conductivity, ParameterLib::Parameter< double > const &wet_thermal_conductivity, ParameterLib::CoordinateSystem const *const local_coordinate_system)
PropertyDataType dValue(VariableArray const &variable_array, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
PropertyDataType fromVector(std::vector< double > const &values)
Definition: Property.cpp:23
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 > > PropertyDataType
Definition: Property.h:35
std::array< VariableType, static_cast< int >(Variable::number_of_variables)> VariableArray
Definition: VariableType.h:108