https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | List of all members
EquilibriumConstantInterpolator Class Reference

Fit the equilibrium constant values read from the thermodynamic databse at specified temperature values with one of three types of fits: More...

#include <EquilibriumConstantInterpolator.h>

Inheritance diagram for EquilibriumConstantInterpolator:
[legend]

Public Member Functions

 EquilibriumConstantInterpolator (const std::vector< Real > &temperature, const std::vector< Real > &logk, const std::string type, const Real no_value=500.0)
 
virtual Real sample (Real T) override
 
ADReal sample (const ADReal &T)
 
Real sampleDerivative (Real T)
 Sample derivative of function at temperature T.
 
virtual void generate ()
 
unsigned int getSampleSize ()
 
const std::vector< Real > & getCoefficients ()
 
void setVariables (const std::vector< Real > &x, const std::vector< Real > &y)
 

Protected Types

enum class  FitTypeEnum { FOURTHORDER , MAIERKELLY , LINEAR , PIECEWISELINEAR }
 Functional form of fit. More...
 

Protected Member Functions

virtual void fillMatrix () override
 
void doLeastSquares ()
 

Protected Attributes

enum EquilibriumConstantInterpolator::FitTypeEnum _fit_type
 
std::unique_ptr< LinearInterpolation_linear_interp
 helper object to perform the linear interpolation of the function data
 
std::vector< Real > _x
 
std::vector< Real > _y
 
std::vector< Real > _matrix
 
std::vector< Real > _coeffs
 
unsigned int _num_coeff
 

Detailed Description

Fit the equilibrium constant values read from the thermodynamic databse at specified temperature values with one of three types of fits:

(1) a fourth-order polynomial fit (for GWB databses)

log(K)= a_0 + a_1 T + a_2 T^2 + a_3 T^3 + a_4 T^4

(2) a Maier-Kelly type fit (for EQ3/6 databases)

log(K)= a_0 ln(T) + a_1 + a_2 T + a_3 / T + a_4 / T^2

(3) a piecewise linear function (for testing purposes) defined by the (temperature, logk) values, with no extrapolation (if T<T_min then the first data value is used, while if T>T_max then the last data value is used)

where T is the temperature in C.

Note: at least five data points must be provided to generate a fit of type (1) or (2), while at least one data point must be provided to generate a piecewise linear function. If fewer data points exist (where 500.0000 represents no value), then a linear fit is used.

The type of fit is specified during construction using the type parameter. The value of "no value" used in the database is provided using the optional no_value parameter. The default value of 500 is used if this parameter is not specified.

Definition at line 43 of file EquilibriumConstantInterpolator.h.

Member Enumeration Documentation

◆ FitTypeEnum

Functional form of fit.

Enumerator
FOURTHORDER 
MAIERKELLY 
LINEAR 
PIECEWISELINEAR 

Definition at line 65 of file EquilibriumConstantInterpolator.h.

Constructor & Destructor Documentation

◆ EquilibriumConstantInterpolator()

EquilibriumConstantInterpolator::EquilibriumConstantInterpolator ( const std::vector< Real > &  temperature,
const std::vector< Real > &  logk,
const std::string  type,
const Real  no_value = 500.0 
)

Definition at line 16 of file EquilibriumConstantInterpolator.C.

22{
23 // The number of temperature points and logk points must be equal
24 if (temperature.size() != logk.size())
25 mooseError("The temperature and logk data sets must be equal in length in "
26 "EquilibriumConstantInterpolator");
27
28 // A value of 500.0 in logk signifies 'no value', so should not be used in the fit
29 std::vector<Real> useful_temperature, useful_logk;
30 for (unsigned int i = 0; i < temperature.size(); ++i)
31 if (!MooseUtils::absoluteFuzzyEqual(logk[i], no_value))
32 {
33 useful_temperature.push_back(temperature[i]);
34 useful_logk.push_back(logk[i]);
35 }
36
37 LeastSquaresFitBase::setVariables(useful_temperature, useful_logk);
38
39 // Set the type of fit
40 if (type == "fourth-order")
42 else if (type == "maier-kelly")
44 else if (type == "piecewise-linear")
45 {
47 try
48 {
49 _linear_interp = std::make_unique<LinearInterpolation>(useful_temperature, useful_logk);
50 }
51 catch (std::domain_error & e)
52 {
53 mooseError("EquilibriumConstantInterpolation: ", e.what());
54 }
55 }
56 else
57 mooseError("Type ", type, " is not supported in EquilibriumConstantInterpolator");
58
59 // Set the number of coefficients for the fit
60 if (useful_temperature.size() >= 5)
61 _num_coeff = 5;
62 else if (useful_temperature.size() >= 1 && _fit_type == FitTypeEnum::PIECEWISELINEAR)
63 _num_coeff = 2;
64 else
65 {
66 _num_coeff = 2;
68 }
69
70 // If the type is Maier-Kelly and the first temperature point is zero, suggest that
71 // the user should use a fourth-order polynomial
72 if (MooseUtils::absoluteFuzzyEqual(useful_temperature[0], 0.0) && type == "maier-kelly")
73 mooseError("A Maier-Kelly fit cannot be used when the temperature points include 0. Use a "
74 "fourth-order fit instead");
75}
void mooseError(Args &&... args)
std::unique_ptr< LinearInterpolation > _linear_interp
helper object to perform the linear interpolation of the function data
unsigned int _num_coeff
void setVariables(const std::vector< Real > &x, const std::vector< Real > &y)

Member Function Documentation

◆ fillMatrix()

void EquilibriumConstantInterpolator::fillMatrix ( )
overrideprotectedvirtual

Implements LeastSquaresFitBase.

Definition at line 78 of file EquilibriumConstantInterpolator.C.

79{
80 const unsigned int num_rows = _x.size();
81 const unsigned int num_cols = _num_coeff;
82 _matrix.resize(num_rows * num_cols);
83
84 // Type of function depends on fit type
85 switch (_fit_type)
86 {
88 {
89 for (unsigned int row = 0; row < num_rows; ++row)
90 {
91 _matrix[row] = 1.0;
92 _matrix[num_rows + row] = _x[row];
93 _matrix[(2 * num_rows) + row] = Utility::pow<2>(_x[row]);
94 _matrix[(3 * num_rows) + row] = Utility::pow<3>(_x[row]);
95 _matrix[(4 * num_rows) + row] = Utility::pow<4>(_x[row]);
96 }
97 break;
98 }
99
101 {
102 for (unsigned int row = 0; row < num_rows; ++row)
103 {
104 _matrix[row] = std::log(_x[row]);
105 _matrix[num_rows + row] = 1.0;
106 _matrix[(2 * num_rows) + row] = _x[row];
107 _matrix[(3 * num_rows) + row] = 1.0 / _x[row];
108 _matrix[(4 * num_rows) + row] = 1.0 / Utility::pow<2>(_x[row]);
109 }
110 break;
111 }
112
114 break; // _matrix is not used in piecewiselinear
115
116 default: // FitTypeEnum::LINEAR
117 {
118 for (unsigned int row = 0; row < num_rows; ++row)
119 {
120 _matrix[row] = 1.0;
121 _matrix[num_rows + row] = _x[row];
122 }
123 break;
124 }
125 }
126}
std::vector< Real > _x
std::vector< Real > _matrix

◆ sample() [1/2]

ADReal EquilibriumConstantInterpolator::sample ( const ADReal T)

Definition at line 171 of file EquilibriumConstantInterpolator.C.

172{
173 using std::log;
174 switch (_fit_type)
175 {
177 return _coeffs[0] + _coeffs[1] * T + _coeffs[2] * Utility::pow<2>(T) +
178 _coeffs[3] * Utility::pow<3>(T) + _coeffs[4] * Utility::pow<4>(T);
179
181 return _coeffs[0] * log(T) + _coeffs[1] + _coeffs[2] * T + _coeffs[3] / T +
182 _coeffs[4] / Utility::pow<2>(T);
183
185 return _coeffs[0] + _coeffs[1] * T;
186
187 default:
188 mooseError("Dual cannot be used for specified fit type in EquilibriumConstantInterpolator");
189 }
190}
const double T
std::vector< Real > _coeffs
auto log(const T &)

◆ sample() [2/2]

Real EquilibriumConstantInterpolator::sample ( Real  T)
overridevirtual

Implements LeastSquaresFitBase.

Definition at line 129 of file EquilibriumConstantInterpolator.C.

130{
131 switch (_fit_type)
132 {
134 return _coeffs[0] + _coeffs[1] * T + _coeffs[2] * Utility::pow<2>(T) +
135 _coeffs[3] * Utility::pow<3>(T) + _coeffs[4] * Utility::pow<4>(T);
136
138 return _coeffs[0] * std::log(T) + _coeffs[1] + _coeffs[2] * T + _coeffs[3] / T +
139 _coeffs[4] / Utility::pow<2>(T);
140
142 return _linear_interp->sample(T);
143
144 default: // FitTypeEnum::LINEAR
145 return _coeffs[0] + _coeffs[1] * T;
146 }
147}

Referenced by GeochemicalSystem::buildTemperatureDependentQuantities(), GeochemicalModelInterrogator::outputActivity(), GeochemicalModelInterrogator::outputReaction(), GeochemistryActivityCoefficientsDebyeHuckel::setInternalParameters(), GeochemicalModelInterrogator::solveForT(), TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), and TEST().

◆ sampleDerivative()

Real EquilibriumConstantInterpolator::sampleDerivative ( Real  T)

Sample derivative of function at temperature T.

Parameters
Ttemperature
Returns
derivative of fit wrt T

Definition at line 150 of file EquilibriumConstantInterpolator.C.

151{
152 switch (_fit_type)
153 {
155 return _coeffs[1] + 2.0 * _coeffs[2] * T + 3.0 * _coeffs[3] * Utility::pow<2>(T) +
156 4.0 * _coeffs[4] * Utility::pow<3>(T);
157
159 return _coeffs[0] / T + _coeffs[2] - _coeffs[3] / Utility::pow<2>(T) -
160 2.0 * _coeffs[4] / Utility::pow<3>(T);
161
163 return _linear_interp->sampleDerivative(T);
164
165 default: // FitTypeEnum::LINEAR:
166 return _coeffs[1];
167 }
168}

Referenced by GeochemicalModelInterrogator::solveForT(), TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), and TEST().

Member Data Documentation

◆ _fit_type

enum EquilibriumConstantInterpolator::FitTypeEnum EquilibriumConstantInterpolator::_fit_type
protected

◆ _linear_interp

std::unique_ptr<LinearInterpolation> EquilibriumConstantInterpolator::_linear_interp
protected

helper object to perform the linear interpolation of the function data

Definition at line 74 of file EquilibriumConstantInterpolator.h.

Referenced by EquilibriumConstantInterpolator(), sample(), and sampleDerivative().


The documentation for this class was generated from the following files: