www.mooseframework.org
PiecewiseBilinear.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
10 #include "PiecewiseBilinear.h"
11 #include "ColumnMajorMatrix.h"
12 #include "BilinearInterpolation.h"
13 #include "MooseUtils.h"
14 
15 #include <fstream>
16 
18 
21 {
23  params.addParam<FileName>(
24  "data_file", "", "File holding csv data for use with PiecewiseBilinear");
25  params.addParam<std::vector<Real>>("x", "The x abscissa values");
26  params.addParam<std::vector<Real>>("y", "The y abscissa values");
27  params.addParam<std::vector<Real>>("z", "The ordinate values");
28  params.addParam<int>("axis", -1, "The axis used (0, 1, or 2 for x, y, or z).");
29  params.addParam<int>(
30  "xaxis", -1, "The coordinate used for x-axis data (0, 1, or 2 for x, y, or z).");
31  params.addParam<int>(
32  "yaxis", -1, "The coordinate used for y-axis data (0, 1, or 2 for x, y, or z).");
33  params.addParam<Real>(
34  "scale_factor", 1.0, "Scale factor to be applied to the axis, yaxis, or xaxis values");
35  params.addParam<bool>("radial",
36  false,
37  "Set to true if you want to interpolate along a radius "
38  "rather that along a specific axis, and note that you "
39  "have to define xaxis and yaxis in the input file");
40  params.addClassDescription("Interpolates values from a csv file");
41  return params;
42 }
43 
45  : Function(parameters),
46  _data_file_name(getParam<FileName>("data_file")),
47  _axis(getParam<int>("axis")),
48  _yaxis(getParam<int>("yaxis")),
49  _xaxis(getParam<int>("xaxis")),
50  _axisValid(_axis > -1 && _axis < 3),
51  _yaxisValid(_yaxis > -1 && _yaxis < 3),
52  _xaxisValid(_xaxis > -1 && _xaxis < 3),
53  _scale_factor(getParam<Real>("scale_factor")),
54  _radial(getParam<bool>("radial"))
55 {
56 
57  if (!_axisValid && !_yaxisValid && !_xaxisValid)
58  mooseError("In PiecewiseBilinear ",
59  _name,
60  ": None of axis, yaxis, or xaxis properly defined. Allowable range is 0-2");
61 
63  mooseError("In PiecewiseBilinear ", _name, ": Cannot define axis with either yaxis or xaxis");
64 
65  if (_radial && (!_yaxisValid || !_xaxisValid))
66  mooseError(
67  "In PiecewiseBilinear ", _name, ": yaxis and xaxis must be defined when radial = true");
68 
69  std::vector<Real> x;
70  std::vector<Real> y;
72  std::vector<Real> z_vec;
73 
74  if (!_data_file_name.empty())
75  {
78  mooseError("In PiecewiseBilinear: Cannot specify 'data_file' and 'x', 'y', or 'z' together.");
79  else
80  parse(_data_file_name, x, y, z, name());
81  }
82 
83  else if (!(parameters.isParamValid("x") && parameters.isParamValid("y") &&
85  mooseError("In PiecewiseBilinear: 'x' and 'y' and 'z' must be specified if any one is "
86  "specified or no 'data_file' is specified.");
87 
88  else
89  {
90  x = getParam<std::vector<Real>>("x");
91  y = getParam<std::vector<Real>>("y");
92  z_vec = getParam<std::vector<Real>>("z");
93 
94  // check that size of z = (size of x)*(size of y)
95  if (z_vec.size() != x.size() * y.size())
96  mooseError("In PiecewiseBilinear: Size of z should be the size of x times the size of y.");
97 
98  // reshape and populate z matrix
99  z.reshape(y.size(), x.size());
100  int idx = 0;
101  for (unsigned int i = 0; i < y.size(); i++)
102  for (unsigned int j = 0; j < x.size(); j++)
103  {
104  z(i, j) = z_vec[idx];
105  idx += 1;
106  }
107  }
108 
109  _bilinear_interp = std::make_unique<BilinearInterpolation>(x, y, z);
110 }
111 
113 
114 Real
115 PiecewiseBilinear::value(Real t, const Point & p) const
116 {
117  return valueInternal(t, p);
118 }
119 
120 ADReal
121 PiecewiseBilinear::value(const ADReal & t, const ADPoint & p) const
122 {
123  return valueInternal(t, p);
124 }
125 
126 template <typename T, typename P>
127 T
128 PiecewiseBilinear::valueInternal(T t, const P & p) const
129 {
130  T retVal = 0.0;
131  if (_yaxisValid && _xaxisValid && _radial)
132  {
133  const auto rx = p(_xaxis) * p(_xaxis);
134  const auto ry = p(_yaxis) * p(_yaxis);
135  const auto r = std::sqrt(rx + ry);
136  retVal = _bilinear_interp->sample(r, t);
137  }
138  else if (_axisValid)
139  retVal = _bilinear_interp->sample(p(_axis), t);
140  else if (_yaxisValid && !_radial)
141  {
142  if (_xaxisValid)
143  retVal = _bilinear_interp->sample(p(_xaxis), p(_yaxis));
144  else
145  retVal = _bilinear_interp->sample(t, p(_yaxis));
146  }
147  else
148  retVal = _bilinear_interp->sample(p(_xaxis), t);
149 
150  return retVal * _scale_factor;
151 }
152 
153 void
154 PiecewiseBilinear::parse(const std::string & data_file_name,
155  std::vector<Real> & x,
156  std::vector<Real> & y,
157  ColumnMajorMatrix & z,
158  const std::string & object_name)
159 {
160  std::ifstream file(data_file_name.c_str());
161  if (!file.good())
162  ::mooseError(object_name, " : Error opening file '", data_file_name, "'.");
163 
164  std::size_t num_lines = 0;
165  std::size_t num_cols = libMesh::invalid_uint;
166  std::vector<Real> data;
167 
168  std::string line;
169  std::vector<Real> line_data;
170  while (std::getline(file, line))
171  {
172  num_lines++;
173  if (!MooseUtils::tokenizeAndConvert<double>(line, line_data, ", "))
174  ::mooseError(object_name, " : Error parsing file '", data_file_name, "' on line ", num_lines);
175 
176  data.insert(data.end(), line_data.begin(), line_data.end());
177 
178  if (num_cols == libMesh::invalid_uint)
179  num_cols = line_data.size();
180  else if (line_data.size() != num_cols + 1)
181  ::mooseError(object_name,
182  " : Read ",
183  line_data.size(),
184  " columns of data but expected ",
185  num_cols + 1,
186  " columns in line ",
187  num_lines);
188  }
189 
190  x.resize(num_cols);
191  y.resize(num_lines - 1);
192  z.reshape(num_lines - 1, num_cols);
193  std::size_t offset = 0;
194 
195  // Extract the first line's data (the x axis data)
196  for (unsigned int j = 0; j < num_cols; ++j)
197  x[j] = data[offset++];
198 
199  for (unsigned int i = 0; i < num_lines - 1; ++i)
200  {
201  // Extract the y axis entry for this line
202  y[i] = data[offset++];
203 
204  // Extract the function values for this row in the matrix
205  for (unsigned int j = 0; j < num_cols; ++j)
206  z(i, j) = data[offset++];
207  }
208 
209  if (data.size() != offset)
210  ::mooseError(object_name, " : Inconsistency in data read from '", data_file_name, "'.");
211 }
Base class for function objects.
Definition: Function.h:37
const unsigned int invalid_uint
const std::string & _name
The name of this class, reference to value stored in InputParameters.
Definition: MooseBase.h:75
static InputParameters validParams()
registerMooseObject("MooseApp", PiecewiseBilinear)
void reshape(const unsigned int rows, const unsigned int cols)
Change the shape of the tensor.
static void parse(const std::string &data_file_name, std::vector< Real > &x, std::vector< Real > &y, ColumnMajorMatrix &z, const std::string &object_name)
Parse a text/CSV file to fill two-dimensional data.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
ADRealEigenVector< T, D, asd > sqrt(const ADRealEigenVector< T, D, asd > &)
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:56
T valueInternal(T t, const P &p) const
virtual Real value(Real t, const Point &pt) const override
This function will return a value based on the first input argument only.
DualReal ADReal
Definition: ADRealForward.h:14
std::unique_ptr< BilinearInterpolation > _bilinear_interp
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
PiecewiseBilinear reads from a file the information necessary to build the vectors x and y and the Co...
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
const InputParameters & parameters() const
Get the parameters of the object.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
const Real _scale_factor
virtual ~PiecewiseBilinear()
static InputParameters validParams()
Class constructor.
Definition: Function.C:15
const std::string _data_file_name
PiecewiseBilinear(const InputParameters &parameters)
void ErrorVector unsigned int
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.