https://mooseframework.inl.gov
Loading...
Searching...
No Matches
HelmholtzFluidProperties.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
11#include "BrentsMethod.h"
12#include "libmesh/utility.h"
13
16{
18 params.addClassDescription("Base class for Helmholtz free energy fluid EOS");
19 return params;
20}
21
26
27Real
28HelmholtzFluidProperties::rho_from_p_T(Real pressure, Real temperature) const
29{
30 Real density;
31 // Initial estimate of a bracketing interval for the density
32 Real lower_density = 1.0e-2;
33 Real upper_density = 100.0;
34
35 // The density is found by finding the zero of the pressure
36 auto pressure_diff = [&pressure, &temperature, this](Real x)
37 { return this->p_from_rho_T(x, temperature) - pressure; };
38
39 BrentsMethod::bracket(pressure_diff, lower_density, upper_density);
40 density = BrentsMethod::root(pressure_diff, lower_density, upper_density);
41
42 return density;
43}
44
45void
47 Real pressure, Real temperature, Real & rho, Real & drho_dp, Real & drho_dT) const
48{
49 rho = this->rho_from_p_T(pressure, temperature);
50
51 // Scale the density and temperature
52 const Real delta = rho / criticalDensity();
53 const Real tau = criticalTemperature() / temperature;
54 const Real da_dd = dalpha_ddelta(delta, tau);
55 const Real d2a_dd2 = d2alpha_ddelta2(delta, tau);
56
57 drho_dp = molarMass() / (_R * temperature * delta * (2.0 * da_dd + delta * d2a_dd2));
58 drho_dT = rho * (tau * d2alpha_ddeltatau(delta, tau) - da_dd) / temperature /
59 (2.0 * da_dd + delta * d2a_dd2);
60}
61
62Real
63HelmholtzFluidProperties::e_from_p_T(Real pressure, Real temperature) const
64{
65 // Require density first
66 const Real density = rho_from_p_T(pressure, temperature);
67 // Scale the input density and temperature
68 const Real delta = density / criticalDensity();
69 const Real tau = criticalTemperature() / temperature;
70
71 return _R * temperature * tau * dalpha_dtau(delta, tau) / molarMass();
72}
73
74void
76 Real pressure, Real temperature, Real & e, Real & de_dp, Real & de_dT) const
77{
78 e = this->e_from_p_T(pressure, temperature);
79
80 // Require density first
81 const Real density = rho_from_p_T(pressure, temperature);
82 // Scale the input density and temperature
83 const Real delta = density / criticalDensity();
84 const Real tau = criticalTemperature() / temperature;
85
86 const Real da_dd = dalpha_ddelta(delta, tau);
87 const Real d2a_dd2 = d2alpha_ddelta2(delta, tau);
88 const Real d2a_ddt = d2alpha_ddeltatau(delta, tau);
89
90 de_dp = tau * d2a_ddt / (density * (2.0 * da_dd + delta * d2a_dd2));
91 de_dT = -_R *
92 (delta * tau * d2a_ddt * (da_dd - tau * d2a_ddt) / (2.0 * da_dd + delta * d2a_dd2) +
93 tau * tau * d2alpha_dtau2(delta, tau)) /
94 molarMass();
95}
96
97Real
98HelmholtzFluidProperties::c_from_p_T(Real pressure, Real temperature) const
99{
100 // Require density first
101 const Real density = rho_from_p_T(pressure, temperature);
102 // Scale the input density and temperature
103 const Real delta = density / criticalDensity();
104 const Real tau = criticalTemperature() / temperature;
105
106 const Real da_dd = dalpha_ddelta(delta, tau);
107
108 Real w = 2.0 * delta * da_dd + delta * delta * d2alpha_ddelta2(delta, tau);
109 w -= Utility::pow<2>(delta * da_dd - delta * tau * d2alpha_ddeltatau(delta, tau)) /
110 (tau * tau * d2alpha_dtau2(delta, tau));
111
112 return std::sqrt(_R * temperature * w / molarMass());
113}
114
115Real
116HelmholtzFluidProperties::cp_from_p_T(Real pressure, Real temperature) const
117{
118 // Require density first
119 const Real density = rho_from_p_T(pressure, temperature);
120 // Scale the input density and temperature
121 const Real delta = density / criticalDensity();
122 const Real tau = criticalTemperature() / temperature;
123
124 const Real da_dd = dalpha_ddelta(delta, tau);
125
126 const Real cp = _R *
127 (-tau * tau * d2alpha_dtau2(delta, tau) +
128 Utility::pow<2>(delta * da_dd - delta * tau * d2alpha_ddeltatau(delta, tau)) /
129 (2.0 * delta * da_dd + delta * delta * d2alpha_ddelta2(delta, tau))) /
130 molarMass();
131
132 return cp;
133}
134
135Real
136HelmholtzFluidProperties::cv_from_p_T(Real pressure, Real temperature) const
137{
138 // Require density first
139 const Real density = rho_from_p_T(pressure, temperature);
140 // Scale the input density and temperature
141 const Real delta = density / criticalDensity();
142 const Real tau = criticalTemperature() / temperature;
143
144 return -_R * tau * tau * d2alpha_dtau2(delta, tau) / molarMass();
145}
146
147Real
148HelmholtzFluidProperties::s_from_p_T(Real pressure, Real temperature) const
149{
150 // Require density first
151 const Real density = rho_from_p_T(pressure, temperature);
152 // Scale the input density and temperature
153 const Real delta = density / criticalDensity();
154 const Real tau = criticalTemperature() / temperature;
155
156 return _R * (tau * dalpha_dtau(delta, tau) - alpha(delta, tau)) / molarMass();
157}
158
159void
161 Real pressure, Real temperature, Real & s, Real & ds_dp, Real & ds_dT) const
162{
163 s = this->s_from_p_T(pressure, temperature);
164
165 // Require density first
166 const Real density = rho_from_p_T(pressure, temperature);
167 // Scale the input density and temperature
168 const Real delta = density / criticalDensity();
169 const Real tau = criticalTemperature() / temperature;
170
171 const Real da_dd = dalpha_ddelta(delta, tau);
172 const Real da_dt = dalpha_dtau(delta, tau);
173 const Real d2a_dd2 = d2alpha_ddelta2(delta, tau);
174 const Real d2a_dt2 = d2alpha_dtau2(delta, tau);
175 const Real d2a_ddt = d2alpha_ddeltatau(delta, tau);
176
177 ds_dp = tau * (d2a_ddt - da_dd) / (density * temperature * (2.0 * da_dd + delta * d2a_dd2));
178 ds_dT = -_R * tau * (da_dt - alpha(delta, tau) + tau * (d2a_dt2 - da_dt)) /
179 (molarMass() * temperature);
180}
181
182Real
183HelmholtzFluidProperties::h_from_p_T(Real pressure, Real temperature) const
184{
185 // Require density first
186 const Real density = rho_from_p_T(pressure, temperature);
187 // Scale the input density and temperature
188 const Real delta = density / criticalDensity();
189 const Real tau = criticalTemperature() / temperature;
190
191 return _R * temperature * (tau * dalpha_dtau(delta, tau) + delta * dalpha_ddelta(delta, tau)) /
192 molarMass();
193}
194
195void
197 Real pressure, Real temperature, Real & h, Real & dh_dp, Real & dh_dT) const
198{
199 h = this->h_from_p_T(pressure, temperature);
200
201 // Require density first
202 const Real density = rho_from_p_T(pressure, temperature);
203 // Scale the input density and temperature
204 const Real delta = density / criticalDensity();
205 const Real tau = criticalTemperature() / temperature;
206
207 const Real da_dd = dalpha_ddelta(delta, tau);
208 const Real d2a_dd2 = d2alpha_ddelta2(delta, tau);
209 const Real d2a_ddt = d2alpha_ddeltatau(delta, tau);
210
211 dh_dp = (da_dd + delta * d2a_dd2 + tau * d2a_ddt) / (density * (2.0 * da_dd + delta * d2a_dd2));
212 dh_dT = _R *
213 (delta * da_dd * (1.0 - tau * d2a_ddt / da_dd) * (1.0 - tau * d2a_ddt / da_dd) /
214 (2.0 + delta * d2a_dd2 / da_dd) -
215 tau * tau * d2alpha_dtau2(delta, tau)) /
216 molarMass();
217}
218
219Real
220HelmholtzFluidProperties::T_from_p_h(Real pressure, Real enthalpy) const
221{
222 auto lambda = [&](Real pressure, Real current_T, Real & new_h, Real & dh_dp, Real & dh_dT)
223 { h_from_p_T(pressure, current_T, new_h, dh_dp, dh_dT); };
225 pressure, enthalpy, _T_initial_guess, _tolerance, lambda, name() + "::T_from_p_h")
226 .first;
227 // check for nans
228 if (std::isnan(T))
229 mooseError("Conversion from enthalpy (h = ",
230 enthalpy,
231 ") and pressure (p = ",
232 pressure,
233 ") to temperature failed to converge.");
234 return T;
235}
236
237Real
238HelmholtzFluidProperties::p_from_rho_T(Real density, Real temperature) const
239{
240 // Scale the input density and temperature
241 const Real delta = density / criticalDensity();
242 const Real tau = criticalTemperature() / temperature;
243
244 return _R * density * temperature * delta * dalpha_ddelta(delta, tau) / molarMass();
245}
const std::vector< double > x
const double rho
static const Real _R
Universal gas constant (J/mol/K)
virtual Real d2alpha_ddelta2(Real delta, Real tau) const =0
Second derivative of Helmholtz free energy wrt delta.
virtual Real c_from_p_T(Real pressure, Real temperature) const override
HelmholtzFluidProperties(const InputParameters &parameters)
static InputParameters validParams()
virtual Real dalpha_dtau(Real delta, Real tau) const =0
Derivative of Helmholtz free energy wrt tau.
virtual Real d2alpha_ddeltatau(Real delta, Real tau) const =0
Second derivative of Helmholtz free energy wrt delta and tau.
virtual Real e_from_p_T(Real pressure, Real temperature) const override
virtual Real d2alpha_dtau2(Real delta, Real tau) const =0
Second derivative of Helmholtz free energy wrt tau.
virtual Real s_from_p_T(Real pressure, Real temperature) const override
virtual Real cp_from_p_T(Real pressure, Real temperature) const override
virtual Real dalpha_ddelta(Real delta, Real tau) const =0
Derivative of Helmholtz free energy wrt delta.
virtual Real rho_from_p_T(Real pressure, Real temperature) const override
virtual Real T_from_p_h(Real pressure, Real enthalpy) const override
virtual Real cv_from_p_T(Real pressure, Real temperature) const override
virtual Real p_from_rho_T(Real rho, Real T) const
Pressure as a function of density and temperature.
virtual Real alpha(Real delta, Real tau) const =0
Helmholtz free energy.
virtual Real h_from_p_T(Real pressure, Real temperature) const override
void addClassDescription(const std::string &doc_string)
const std::string & name() const
void mooseError(Args &&... args) const
Common class for single phase fluid properties.
const Real _T_initial_guess
Initial guess for temperature (or temperature used to compute the initial guess)
static InputParameters validParams()
const Real _tolerance
Newton's method may be used to convert between variable sets.
virtual Real criticalDensity() const
Critical density.
virtual Real molarMass() const
Molar mass [kg/mol].
e e e e s T T T T T rho v v T e h
virtual Real criticalTemperature() const
Critical temperature.
Real root(std::function< Real(Real)> const &f, Real x1, Real x2, Real tol=1.0e-12)
Finds the root of a function using Brent's method.
void bracket(std::function< Real(Real)> const &f, Real &x1, Real &x2)
Function to bracket a root of a given function.
std::pair< T, T > NewtonSolve(const T &x, const T &y, const Real z_initial_guess, const Real tolerance, const Functor &y_from_x_z, const std::string &caller_name, const unsigned int max_its=100, const bool verbose=false)
NewtonSolve does a 1D Newton Solve to solve the equation y = f(x, z) for variable z.