OGS
WaterViscosityIAPWS.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{
13static const double Hi[4] = {1.67752, 2.20462, 0.6366564, -0.241605};
14static const double Hij[6][7] = {
15 {0.520094, 0.222531, -0.281378, 0.161913, -0.0325372, 0, 0},
16 {0.0850895, 0.999115, -0.906851, 0.257399, 0, 0, 0},
17 {-1.08374, 1.88797, -0.772479, 0, 0, 0, 0},
18 {-0.289555, 1.26613, -0.489837, 0, 0.0698452, 0, -0.00435673},
19 {0, 0, -0.25704, 0, 0, 0.00872102, 0},
20 {0, 0.120573, 0, 0, 0, 0, -0.000593264}};
21
22static double computeBarMu0Factor(const double barT);
23
24static std::array<double, 6> computeSeriesFactorTForMu1(const double barT);
25static std::array<double, 7> computeSeriesFactorRhoForMu1(const double bar_rho);
26static double computeBarMu1Factor(
27 const std::array<double, 6>& series_factorT,
28 const std::array<double, 7>& series_factorRho);
29
30static double computedBarMu_dbarT(const double barT, double bar_rho);
31static double computedBarMu_dbarRho(const double barT, double bar_rho);
32
34 VariableArray const& variable_array,
35 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
36 double const /*dt*/) const
37{
38 const double bar_T = variable_array.temperature / ref_T_;
39 const double bar_rho = variable_array.density / ref_rho_;
40
41 const double mu0 = 100. * std::sqrt(bar_T) / computeBarMu0Factor(bar_T);
42
43 const auto& series_factorT = computeSeriesFactorTForMu1(bar_T);
44 const auto& series_factorRho = computeSeriesFactorRhoForMu1(bar_rho);
45 const double mu1 = std::exp(
46 bar_rho * computeBarMu1Factor(series_factorT, series_factorRho));
47
48 return mu0 * mu1 * ref_mu_;
49}
50
52 VariableArray const& variable_array, Variable const variable,
53 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
54 double const /*dt*/) const
55{
56 const double bar_T = variable_array.temperature / ref_T_;
57 const double bar_rho = variable_array.density / ref_rho_;
58
59 switch (variable)
60 {
62 return ref_mu_ * computedBarMu_dbarT(bar_T, bar_rho) / ref_T_;
64 return ref_mu_ * computedBarMu_dbarRho(bar_T, bar_rho) / ref_rho_;
65 default:
67 "WaterViscosityIAPWS::dValue is implemented for "
68 "derivatives with respect to temperature and liquid density "
69 "only.");
70 }
71}
72
73double computeBarMu0Factor(const double barT)
74{
75 double sum_val = 0.;
76 double barT_i = 1.;
77 for (double value : Hi)
78 {
79 sum_val += (value / barT_i);
80 barT_i *= barT;
81 }
82 return sum_val;
83}
84
85std::array<double, 6> computeSeriesFactorTForMu1(const double barT)
86{
87 std::array<double, 6> series_factorT;
88 series_factorT[0] = 1.;
89 const double barT_fac = 1 / barT - 1.0;
90 for (int i = 1; i < 6; i++)
91 {
92 series_factorT[i] = series_factorT[i - 1] * barT_fac;
93 }
94
95 return series_factorT;
96}
97
98std::array<double, 7> computeSeriesFactorRhoForMu1(const double bar_rho)
99{
100 std::array<double, 7> series_factorRho;
101 series_factorRho[0] = 1.;
102 for (int i = 1; i < 7; i++)
103 {
104 series_factorRho[i] = series_factorRho[i - 1] * (bar_rho - 1.0);
105 }
106
107 return series_factorRho;
108}
109
110double computeBarMu1Factor(const std::array<double, 6>& series_factorT,
111 const std::array<double, 7>& series_factorRho)
112{
113 double sum_val = 0.;
114 for (int i = 0; i < 6; i++)
115 {
116 double sum_val_j = 0;
117 for (int j = 0; j < 7; j++)
118 {
119 sum_val_j += Hij[i][j] * series_factorRho[j];
120 }
121 sum_val += series_factorT[i] * sum_val_j;
122 }
123
124 return sum_val;
125}
126
127double computedBarMu_dbarT(const double barT, double bar_rho)
128{
129 const double mu0_factor = computeBarMu0Factor(barT);
130 const double sqrt_barT = std::sqrt(barT);
131
132 double dmu0_factor_dbarT = 0.0;
133 double barT_i = barT * barT;
134 for (int i = 1; i < 4; i++)
135 {
136 dmu0_factor_dbarT -= static_cast<double>(i) * (Hi[i] / barT_i);
137 barT_i *= barT;
138 }
139
140 const double dbar_mu0_dbarT =
141 50. / (mu0_factor * sqrt_barT) -
142 100. * sqrt_barT * dmu0_factor_dbarT / (mu0_factor * mu0_factor);
143
144 const auto& series_factorT = computeSeriesFactorTForMu1(barT);
145 const auto& series_factorRho = computeSeriesFactorRhoForMu1(bar_rho);
146
147 double dmu1_factor_dbarT = 0.0;
148 for (int i = 1; i < 6; i++)
149 {
150 double sum_val_j = 0;
151 for (int j = 0; j < 7; j++)
152 {
153 sum_val_j += Hij[i][j] * series_factorRho[j];
154 }
155 dmu1_factor_dbarT -= static_cast<double>(i) * series_factorT[i - 1] *
156 sum_val_j / (barT * barT);
157 }
158
159 const double mu1_factor =
160 computeBarMu1Factor(series_factorT, series_factorRho);
161 const double dbar_mu1_dbarT =
162 bar_rho * std::exp(bar_rho * mu1_factor) * dmu1_factor_dbarT;
163
164 return dbar_mu0_dbarT * std::exp(bar_rho * mu1_factor) +
165 dbar_mu1_dbarT * 100. * sqrt_barT / mu0_factor;
166}
167
168double computedBarMu_dbarRho(const double barT, double bar_rho)
169{
170 const auto& series_factorT = computeSeriesFactorTForMu1(barT);
171 const auto& series_factorRho = computeSeriesFactorRhoForMu1(bar_rho);
172
173 double dmu1_factor_dbar_rho = 0.0;
174 for (int i = 0; i < 6; i++)
175 {
176 double sum_val_j = 0;
177 for (int j = 1; j < 7; j++)
178 {
179 sum_val_j +=
180 static_cast<double>(j) * Hij[i][j] * series_factorRho[j - 1];
181 }
182 dmu1_factor_dbar_rho += series_factorT[i] * sum_val_j;
183 }
184
185 const double mu0 = 100. * std::sqrt(barT) / computeBarMu0Factor(barT);
186
187 const double mu1_factor =
188 computeBarMu1Factor(series_factorT, series_factorRho);
189 return mu0 * std::exp(bar_rho * mu1_factor) *
190 (mu1_factor + bar_rho * dmu1_factor_dbar_rho);
191}
192
193} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:19
virtual PropertyDataType value() const
static constexpr double ref_mu_
reference viscosity in Pa.s
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_T_
reference temperature in K
static constexpr double ref_rho_
reference density in kg/m^3
static double computeBarMu0Factor(const double barT)
static const double Hi[4]
static double computedBarMu_dbarT(const double barT, double bar_rho)
static std::array< double, 7 > computeSeriesFactorRhoForMu1(const double bar_rho)
static const double Hij[6][7]
static double computeBarMu1Factor(const std::array< double, 6 > &series_factorT, const std::array< double, 7 > &series_factorRho)
static double computedBarMu_dbarRho(const double barT, double bar_rho)
static std::array< double, 6 > computeSeriesFactorTForMu1(const double barT)
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