https://mooseframework.inl.gov
Loading...
Searching...
No Matches
TabulatedBicubicFluidProperties.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
12#include "MooseUtils.h"
13#include "Conversion.h"
14#include "KDTree.h"
15
16// C++ includes
17#include <fstream>
18#include <ctime>
19
21registerMooseObjectRenamed("FluidPropertiesApp",
23 "01/01/2023 00:00",
25
28{
31 "Fluid properties using bicubic interpolation on tabulated values provided");
32 return params;
33}
34
39
40void
42{
43 // Construct bicubic interpolants from tabulated data
44 std::vector<std::vector<Real>> data_matrix;
45
47 {
48 _property_ipol.resize(_properties.size());
49 for (const auto i : index_range(_property_ipol))
50 {
51 reshapeData2D(_num_p, _num_T, _properties[i], data_matrix);
53 std::make_unique<BicubicInterpolation>(_pressure, _temperature, data_matrix);
54 }
55 }
56
58 {
59 _property_ve_ipol.resize(_properties_ve.size());
60
61 for (const auto i : index_range(_property_ve_ipol))
62 {
63 reshapeData2D(_num_v, _num_e, _properties_ve[i], data_matrix);
65 std::make_unique<BicubicInterpolation>(_specific_volume, _internal_energy, data_matrix);
66 }
67 }
68
69 bool conversion_succeeded = true;
70 unsigned int fail_counter_ve = 0;
71 unsigned int fail_counter_vh = 0;
72 // Create interpolations of (p,T) from (v,e)
74 {
75 // Grids in specific volume and internal energy can be either linear or logarithmic
76 // NOTE: this could have been called already when generating tabulated data
78
79 // initialize vectors for interpolation
80 std::vector<std::vector<Real>> p_from_v_e(_num_v);
81 std::vector<std::vector<Real>> T_from_v_e(_num_v);
82
83 unsigned int num_p_nans_ve = 0, num_T_nans_ve = 0, num_p_out_bounds_ve = 0,
84 num_T_out_bounds_ve = 0;
85
86 for (unsigned int i = 0; i < _num_v; ++i)
87 {
88 Real p_guess = _p_initial_guess;
89 Real T_guess = _T_initial_guess;
90 p_from_v_e[i].resize(_num_e);
91 T_from_v_e[i].resize(_num_e);
92 for (unsigned int j = 0; j < _num_e; ++j)
93 {
94 Real p_ve, T_ve;
95 // Using an input fluid property instead of the tabulation will get more exact inversions
96 if (_fp)
101 p_ve,
102 T_ve,
103 conversion_succeeded);
104 else
105 {
106 // The inversion may step outside of the domain of definition of the interpolations,
107 // which are restricted to the range of the input CSV file
108 const auto old_error_behavior = _OOBBehavior;
112 p_guess,
113 T_guess,
114 p_ve,
115 T_ve,
116 conversion_succeeded);
117 _OOBBehavior = old_error_behavior;
118 // track number of times convergence failed
119 if (!conversion_succeeded)
120 ++fail_counter_ve;
121 }
122
123 // check for NaNs in Newton Method
128 i,
129 p_ve,
130 T_ve,
131 num_p_nans_ve,
132 num_T_nans_ve);
133
134 // replace out of bounds pressure values with pmax or pmin
135 checkOutofBounds(_pressure_min, _pressure_max, p_ve, num_p_out_bounds_ve);
136 // replace out of bounds temperature values with Tmax or Tmin
137 checkOutofBounds(_temperature_min, _temperature_max, T_ve, num_T_out_bounds_ve);
138
139 p_from_v_e[i][j] = p_ve;
140 T_from_v_e[i][j] = T_ve;
141
142 p_guess = p_ve;
143 T_guess = T_ve;
144 }
145 }
146 // output warning if nans or values out of bounds
147 outputWarnings(num_p_nans_ve,
148 num_T_nans_ve,
149 num_p_out_bounds_ve,
150 num_T_out_bounds_ve,
151 fail_counter_ve,
152 _num_e * _num_v,
153 "(v,e)");
154
155 // the bicubic interpolation object are init'ed now
157 std::make_unique<BicubicInterpolation>(_specific_volume, _internal_energy, p_from_v_e);
159 std::make_unique<BicubicInterpolation>(_specific_volume, _internal_energy, T_from_v_e);
160 }
161
162 // Create interpolations of (p,T) from (v,h)
164 {
165 // Grids in specific volume and enthalpy can be either linear or logarithmic
166 // NOTE: the specific volume grid could have been created when generating tabulated data
168
169 // initialize vectors for interpolation
170 std::vector<std::vector<Real>> p_from_v_h(_num_v);
171 std::vector<std::vector<Real>> T_from_v_h(_num_v);
172
173 unsigned int num_p_nans_vh = 0, num_T_nans_vh = 0, num_p_out_bounds_vh = 0,
174 num_T_out_bounds_vh = 0;
175
176 for (unsigned int i = 0; i < _num_v; ++i)
177 {
178 Real p_guess = _p_initial_guess;
179 Real T_guess = _T_initial_guess;
180 p_from_v_h[i].resize(_num_e);
181 T_from_v_h[i].resize(_num_e);
182 for (unsigned int j = 0; j < _num_e; ++j)
183 {
184 Real p_vh, T_vh;
185 // Using an input fluid property instead of the tabulation will get more exact inversions
186 if (_fp)
188 _enthalpy[j],
191 p_vh,
192 T_vh,
193 conversion_succeeded);
194 else
195 {
196 // The inversion may step outside of the domain of definition of the interpolations,
197 // which are restricted to the range of the input CSV file
198 const auto old_error_behavior = _OOBBehavior;
201 _enthalpy[j],
202 p_guess,
203 T_guess,
204 p_vh,
205 T_vh,
206 conversion_succeeded);
207 _OOBBehavior = old_error_behavior;
208 // track number of times convergence failed
209 if (!conversion_succeeded)
210 ++fail_counter_vh;
211 }
212
213 // check for NaNs in Newton Method
218 i,
219 p_vh,
220 T_vh,
221 num_p_nans_vh,
222 num_T_nans_vh);
223
224 // replace out of bounds pressure values with pmax or pmin
225 checkOutofBounds(_pressure_min, _pressure_max, p_vh, num_p_out_bounds_vh);
226 // replace out of bounds temperature values with Tmax or Tmin
227 checkOutofBounds(_temperature_min, _temperature_max, T_vh, num_T_out_bounds_vh);
228
229 p_from_v_h[i][j] = p_vh;
230 T_from_v_h[i][j] = T_vh;
231
232 p_guess = p_vh;
233 T_guess = T_vh;
234 }
235 }
236 // output warnings if nans our values out of bounds
237 outputWarnings(num_p_nans_vh,
238 num_T_nans_vh,
239 num_p_out_bounds_vh,
240 num_T_out_bounds_vh,
241 fail_counter_vh,
242 _num_e * _num_v,
243 "(v,h)");
244
245 // the bicubic interpolation object are init'ed now
247 std::make_unique<BicubicInterpolation>(_specific_volume, _enthalpy, p_from_v_h);
249 std::make_unique<BicubicInterpolation>(_specific_volume, _enthalpy, T_from_v_h);
250 }
251}
252
253void
255 unsigned int ncol,
256 const std::vector<Real> & vec,
257 std::vector<std::vector<Real>> & mat)
258{
259 if (!vec.empty())
260 {
261 mat.resize(nrow);
262 for (unsigned int i = 0; i < nrow; ++i)
263 mat[i].resize(ncol);
264
265 for (unsigned int i = 0; i < nrow; ++i)
266 for (unsigned int j = 0; j < ncol; ++j)
267 mat[i][j] = vec[i * ncol + j];
268 }
269}
270
271void
273 Real max_1,
274 Real min_2,
275 Real max_2,
276 unsigned int i,
277 Real & variable_1,
278 Real & variable_2,
279 unsigned int & num_nans_1,
280 unsigned int & num_nans_2)
281{
282 // replace nan values with pmax or pmin
283 if (std::isnan(variable_1))
284 {
285 if (_specific_volume[i] > ((_v_min + _v_max) / 2))
286 variable_1 = min_1;
287 else if (_specific_volume[i] < ((_v_min + _v_max) / 2))
288 variable_1 = max_1;
289 num_nans_1++;
290 }
291 // replace nan values with Tmax or Tmin
292 if (std::isnan(variable_2))
293 {
294 if (_specific_volume[i] > ((_v_min + _v_max) / 2))
295 variable_2 = max_2;
296 else if (_specific_volume[i] < ((_v_min + _v_max) / 2))
297 variable_2 = min_2;
298 num_nans_2++;
299 }
300}
301
302void
304 Real max,
305 Real & variable,
306 unsigned int & num_out_bounds)
307{
308 if (variable < min)
309 {
310 variable = min;
311 num_out_bounds++;
312 }
313 else if (variable > max)
314 {
315 variable = max;
316 num_out_bounds++;
317 }
318}
319
320void
322 unsigned int num_nans_T,
323 unsigned int num_out_bounds_p,
324 unsigned int num_out_bounds_T,
325 unsigned int convergence_failures,
326 unsigned int number_points,
327 std::string variable_set)
328{
329 // make string variables before mooseWarning
330 std::string while_creating =
331 "While creating (p,T) from " + variable_set + " interpolation tables,\n";
332 std::string warning_message = while_creating;
333 std::string converge_fails = "Inversion to (p,T) from " + variable_set + " failed " +
334 std::to_string(convergence_failures) + " times\n";
335 std::string p_nans = "- " + std::to_string(num_nans_p) + " nans generated out of " +
336 std::to_string(number_points) + " points for pressure\n";
337 std::string T_nans = "- " + std::to_string(num_nans_T) + " nans generated out of " +
338 std::to_string(number_points) + " points for temperature\n";
339 std::string p_oob = "- " + std::to_string(num_out_bounds_p) + " of " +
340 std::to_string(number_points) + " pressure values were out of bounds\n";
341 std::string T_oob = "- " + std::to_string(num_out_bounds_T) + " of " +
342 std::to_string(number_points) + " temperature values were out of bounds\n";
343 std::string outcome = "The pressure and temperature values were replaced with their respective "
344 "min and max values.\n";
345
346 // bounds are different depending on how the object is used
347 std::string source = (_fp ? "from input parameters" : "from tabulation file");
348
349 // if any of these do not exist, do not want to print them
350 if (convergence_failures)
351 warning_message += converge_fails;
352 if (num_nans_p)
353 warning_message += p_nans;
354 if (num_nans_T)
355 warning_message += T_nans;
356 if (num_out_bounds_p)
357 {
358 warning_message += p_oob;
359 warning_message += ("Pressure bounds " + source + ": [" + std::to_string(_pressure_min) + ", " +
360 std::to_string(_pressure_max) + "]\n");
361 }
362 if (num_out_bounds_T)
363 {
364 warning_message += T_oob;
365 warning_message += ("Temperature bounds " + source + ": [" + std::to_string(_temperature_min) +
366 ", " + std::to_string(_temperature_max) + "]\n");
367 }
368 // print warning
369 if (num_nans_p || num_nans_T || num_out_bounds_p || num_out_bounds_T || convergence_failures)
370 mooseWarning(warning_message + outcome);
371}
registerMooseObjectRenamed("FluidPropertiesApp", TabulatedFluidProperties, "01/01/2023 00:00", TabulatedBicubicFluidProperties)
registerMooseObject("FluidPropertiesApp", TabulatedBicubicFluidProperties)
void addClassDescription(const std::string &doc_string)
void mooseWarning(Args &&... args) const
const Real _T_initial_guess
Initial guess for temperature (or temperature used to compute the initial guess)
void p_T_from_v_e(const CppType &v, const CppType &e, Real p0, Real T0, CppType &p, CppType &T, bool &conversion_succeeded) const
Determines (p,T) from (v,e) using Newton Solve in 2D Useful for conversion between different sets of ...
const Real _p_initial_guess
Initial guess for pressure (or pressure used to compute the initial guess)
void p_T_from_v_h(const T &v, const T &h, Real p0, Real T0, T &pressure, T &temperature, bool &conversion_succeeded) const
Determines (p,T) from (v,h) using Newton Solve in 2D Useful for conversion between different sets of ...
Class for fluid properties read from a file.
void checkNaNs(Real min_1, Real max_1, Real min_2, Real max_2, unsigned int i, Real &variable_1, Real &variable_2, unsigned int &num_nans_1, unsigned int &num_nans_2)
If Newton Method jacobian produces NaNs, set variable to min or max depending on situation.
void reshapeData2D(unsigned int nrow, unsigned int ncol, const std::vector< Real > &vec, std::vector< std::vector< Real > > &mat)
Forms a 2D matrix from a single std::vector.
void outputWarnings(unsigned int num_nans_p, unsigned int num_nans_T, unsigned int num_out_bounds_p, unsigned int num_out_bounds_T, unsigned int convergence_failures, unsigned int number_points, std::string variable_set)
TabulatedBicubicFluidProperties(const InputParameters &parameters)
void checkOutofBounds(Real min, Real max, Real &variable, unsigned int &num_out_bounds)
If values go out of user defined range during Newton Method inversion, set variable to min or max dep...
Class for fluid properties read from a tabulation in a file.
std::unique_ptr< BidimensionalInterpolation > _T_from_v_e_ipol
Bi-dimensional interpolation of temperature from (v,e)
unsigned int _num_T
Number of temperature points in the tabulated data.
const SinglePhaseFluidProperties *const _fp
SinglePhaseFluidPropertiesPT UserObject.
std::vector< Real > _internal_energy
Specific internal energy vector.
Real _v_min
Minimum specific volume in tabulated data (can be user-specified)
std::vector< std::vector< Real > > _properties_ve
Tabulated fluid properties in (v,e) (read from file OR computed from _fp)
unsigned int _num_v
Number of specific volume points in the tabulated data.
Real _v_max
Maximum specific volume in tabulated data (can be user-specified)
std::vector< Real > _temperature
Temperature vector.
const bool _create_direct_ve_interpolations
Whether the object has direct (v,e) interpolations (whether created from file or from _fp)
std::unique_ptr< BidimensionalInterpolation > _p_from_v_h_ipol
Bidimensional interpolation of pressure from (v,h)
Real _temperature_max
Maximum temperature in tabulated data.
static InputParameters validParams()
const bool _create_direct_pT_interpolations
Whether the object has direct (p,T) interpolations (whether created from file or from _fp)
std::vector< Real > _enthalpy
Specific enthalpy vector.
void createVHGridVectors()
Create (or reset) the grid vectors for the specific volume and enthalpy interpolation The order of pr...
unsigned int _num_p
Number of pressure points in the tabulated data.
std::vector< std::unique_ptr< BidimensionalInterpolation > > _property_ve_ipol
Vector of bi-dimensional interpolation of fluid properties directly in (v,e)
bool _construct_pT_from_vh
if the lookup table p(v, h) and T(v, h) should be constructed
std::unique_ptr< BidimensionalInterpolation > _p_from_v_e_ipol
Bi-dimensional interpolation of pressure from (v,e)
unsigned int _num_e
Number of internal energy points in tabulated data.
std::vector< Real > _specific_volume
Specific volume vector.
MooseEnum _OOBBehavior
User-selected out-of-bounds behavior.
virtual Real p_from_v_e(Real v, Real e) const override
Derivatives like dc_dv & dc_de are computed using the chain rule dy/dx(p,T) = dy/dp * dp/dx + dy/dT *...
Real _pressure_max
Maximum pressure in tabulated data.
std::vector< std::unique_ptr< BidimensionalInterpolation > > _property_ipol
Vector of bi-dimensional interpolation of fluid properties.
virtual Real T_from_v_e(Real v, Real e) const override
std::unique_ptr< BidimensionalInterpolation > _T_from_v_h_ipol
Bi-dimensional interpolation of temperature from (v,h)
Real _temperature_min
Minimum temperature in tabulated data.
Real _pressure_min
Minimum pressure in tabulated data.
std::vector< std::vector< Real > > _properties
Tabulated fluid properties (read from file OR computed from _fp)
bool _construct_pT_from_ve
if the lookup table p(v, e) and T(v, e) should be constructed
std::vector< Real > _pressure
Pressure vector.