OGS
WaterThermalConductivityIAPWS.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
8#include "BaseLib/Error.h"
10
11namespace MaterialPropertyLib
12{
13// Li and Lij are coefficients from Tables 1 and 2 (Daucik and Dooley, 2011)
14static const double Li[5] = {2.443221e-3, 1.323095e-2, 6.770357e-3,
15 -3.454586e-3, 4.096266e-4};
16static const double Lij[5][6] = {
17 {1.60397357, -0.646013523, 0.111443906, 0.102997357, -0.0504123634,
18 0.00609859258},
19 {2.33771842, -2.78843778, 1.53616167, -0.463045512, 0.0832827019,
20 -0.00719201245},
21 {2.19650529, -4.54580785, 3.55777244, -1.40944978, 0.275418278,
22 -0.0205938816},
23 {-1.21051378, 1.60812989, -0.621178141, 0.0716373224, 0, 0},
24 {-2.7203370, 4.57586331, -3.18369245, 1.1168348, -0.19268305, 0.012913842}};
25
26static double computeBarLambda0Factor(const double barT);
27
28static std::array<double, 5> computeSeriesFactorTForLambda1(const double barT);
29static std::array<double, 6> computeSeriesFactorRhoForLambda1(
30 const double bar_rho);
31static double computeBarLambda1Factor(
32 const std::array<double, 5>& series_factorT,
33 const std::array<double, 6>& series_factorRho);
34
35static double computedBarLambda_dbarT(const double barT, double bar_rho);
36static double computedBarLambda_dbarRho(const double barT, double bar_rho);
37
39 VariableArray const& variable_array,
40 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
41 double const /*dt*/) const
42{
43 const double bar_T = variable_array.temperature / ref_T_;
44 const double bar_rho = variable_array.density / ref_rho_;
45
46 const double lambda0 = std::sqrt(bar_T) / computeBarLambda0Factor(bar_T);
47
48 const auto& series_factorT = computeSeriesFactorTForLambda1(bar_T);
49 const auto& series_factorRho = computeSeriesFactorRhoForLambda1(bar_rho);
50 const double lambda1 = std::exp(
51 bar_rho * computeBarLambda1Factor(series_factorT, series_factorRho));
52
53 return lambda0 * lambda1 * ref_lambda_;
54}
55
57 VariableArray const& variable_array, Variable const variable,
58 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
59 double const /*dt*/) const
60{
61 const double bar_T = variable_array.temperature / ref_T_;
62 const double bar_rho = variable_array.density / ref_rho_;
63
64 switch (variable)
65 {
67 return ref_lambda_ * computedBarLambda_dbarT(bar_T, bar_rho) /
68 ref_T_;
70 return ref_lambda_ * computedBarLambda_dbarRho(bar_T, bar_rho) /
72 default:
74 "WaterThermalConductivityIAPWS::dValue is implemented for "
75 "derivatives with respect to temperature and liquid density "
76 "only.");
77 }
78}
79
80double computeBarLambda0Factor(const double barT)
81{
82 double sum_val = 0.;
83 double barT_i = 1.;
84 for (double value : Li)
85 {
86 sum_val += (value / barT_i);
87 barT_i *= barT;
88 }
89 return sum_val;
90}
91
92std::array<double, 5> computeSeriesFactorTForLambda1(const double barT)
93{
94 std::array<double, 5> series_factorT;
95 series_factorT[0] = 1.;
96 const double barT_fac = 1 / barT - 1.0;
97 for (int i = 1; i < 5; i++)
98 {
99 series_factorT[i] = series_factorT[i - 1] * barT_fac;
100 }
101
102 return series_factorT;
103}
104
105std::array<double, 6> computeSeriesFactorRhoForLambda1(const double bar_rho)
106{
107 std::array<double, 6> series_factorRho;
108 series_factorRho[0] = 1.;
109 for (int i = 1; i < 6; i++)
110 {
111 series_factorRho[i] = series_factorRho[i - 1] * (bar_rho - 1.0);
112 }
113
114 return series_factorRho;
115}
116
117double computeBarLambda1Factor(const std::array<double, 5>& series_factorT,
118 const std::array<double, 6>& series_factorRho)
119{
120 double sum_val = 0.;
121 for (int i = 0; i < 5; i++)
122 {
123 double sum_val_j = 0;
124 for (int j = 0; j < 6; j++)
125 {
126 sum_val_j += Lij[i][j] * series_factorRho[j];
127 }
128 sum_val += series_factorT[i] * sum_val_j;
129 }
130
131 return sum_val;
132}
133
134double computedBarLambda_dbarT(const double barT, double bar_rho)
135{
136 const double lambda0_factor = computeBarLambda0Factor(barT);
137 const double sqrt_barT = std::sqrt(barT);
138
139 double dlambda0_factor_dbarT = 0.0;
140 double barT_i = barT * barT;
141 for (int i = 1; i < 5; i++)
142 {
143 dlambda0_factor_dbarT -= static_cast<double>(i) * (Li[i] / barT_i);
144 barT_i *= barT;
145 }
146
147 const double dbar_lambda0_dbarT =
148 0.5 / (lambda0_factor * sqrt_barT) -
149 sqrt_barT * dlambda0_factor_dbarT / (lambda0_factor * lambda0_factor);
150
151 const auto& series_factorT = computeSeriesFactorTForLambda1(barT);
152 const auto& series_factorRho = computeSeriesFactorRhoForLambda1(bar_rho);
153
154 double dlambda1_factor_dbarT = 0.0;
155 for (int i = 1; i < 5; i++)
156 {
157 double sum_val_j = 0;
158 for (int j = 0; j < 6; j++)
159 {
160 sum_val_j += Lij[i][j] * series_factorRho[j];
161 }
162 dlambda1_factor_dbarT -= static_cast<double>(i) *
163 series_factorT[i - 1] * sum_val_j /
164 (barT * barT);
165 }
166
167 const double lambda1_factor =
168 computeBarLambda1Factor(series_factorT, series_factorRho);
169 const double dbar_lambda1_dbarT =
170 bar_rho * std::exp(bar_rho * lambda1_factor) * dlambda1_factor_dbarT;
171
172 return dbar_lambda0_dbarT * std::exp(bar_rho * lambda1_factor) +
173 dbar_lambda1_dbarT * sqrt_barT / lambda0_factor;
174}
175
176double computedBarLambda_dbarRho(const double barT, double bar_rho)
177{
178 const auto& series_factorT = computeSeriesFactorTForLambda1(barT);
179 const auto& series_factorRho = computeSeriesFactorRhoForLambda1(bar_rho);
180
181 double dlambda1_factor_dbar_rho = 0.0;
182 for (int i = 0; i < 5; i++)
183 {
184 double sum_val_j = 0;
185 for (int j = 1; j < 6; j++)
186 {
187 sum_val_j +=
188 static_cast<double>(j) * Lij[i][j] * series_factorRho[j - 1];
189 }
190 dlambda1_factor_dbar_rho += series_factorT[i] * sum_val_j;
191 }
192
193 const double lambda0 = std::sqrt(barT) / computeBarLambda0Factor(barT);
194
195 const double lambda1_factor =
196 computeBarLambda1Factor(series_factorT, series_factorRho);
197 return lambda0 * std::exp(bar_rho * lambda1_factor) *
198 (lambda1_factor + bar_rho * dlambda1_factor_dbar_rho);
199}
200
201} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:19
virtual PropertyDataType value() const
static constexpr double ref_lambda_
reference thermal conductivity in W.K^-1.m^-1
static constexpr double ref_T_
reference temperature in K
PropertyDataType dValue(VariableArray const &variable_array, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
static constexpr double ref_rho_
reference density in kg/m^3
static double computeBarLambda1Factor(const std::array< double, 5 > &series_factorT, const std::array< double, 6 > &series_factorRho)
static std::array< double, 6 > computeSeriesFactorRhoForLambda1(const double bar_rho)
static double computedBarLambda_dbarT(const double barT, double bar_rho)
static double computeBarLambda0Factor(const double barT)
static std::array< double, 5 > computeSeriesFactorTForLambda1(const double barT)
static const double Lij[5][6]
static double computedBarLambda_dbarRho(const double barT, double bar_rho)
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