www.mooseframework.org
PiecewiseBilinear.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* DO NOT MODIFY THIS HEADER */
3 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
4 /* */
5 /* (c) 2010 Battelle Energy Alliance, LLC */
6 /* ALL RIGHTS RESERVED */
7 /* */
8 /* Prepared by Battelle Energy Alliance, LLC */
9 /* Under Contract No. DE-AC07-05ID14517 */
10 /* With the U. S. Department of Energy */
11 /* */
12 /* See COPYRIGHT for full restrictions */
13 /****************************************************************/
14 
15 #include "PiecewiseBilinear.h"
16 #include "ColumnMajorMatrix.h"
17 #include "BilinearInterpolation.h"
18 
19 #include <fstream>
20 
21 template <>
24 {
26  params.addParam<FileName>(
27  "data_file", "", "File holding csv data for use with PiecewiseBilinear");
28  params.addParam<std::vector<Real>>("x", "The x abscissa values");
29  params.addParam<std::vector<Real>>("y", "The y abscissa values");
30  params.addParam<std::vector<Real>>("z", "The ordinate values");
31  params.addParam<int>("axis", -1, "The axis used (0, 1, or 2 for x, y, or z).");
32  params.addParam<int>(
33  "xaxis", -1, "The coordinate used for x-axis data (0, 1, or 2 for x, y, or z).");
34  params.addParam<int>(
35  "yaxis", -1, "The coordinate used for y-axis data (0, 1, or 2 for x, y, or z).");
36  params.addParam<Real>(
37  "scale_factor", 1.0, "Scale factor to be applied to the axis, yaxis, or xaxis values");
38  params.addParam<bool>("radial",
39  false,
40  "Set to true if you want to interpolate along a radius "
41  "rather that along a specific axis, and note that you "
42  "have to define xaxis and yaxis in the input file");
43  params.addClassDescription("Interpolates values from a csv file");
44  return params;
45 }
46 
48  : Function(parameters),
49  _data_file_name(getParam<FileName>("data_file")),
50  _axis(getParam<int>("axis")),
51  _yaxis(getParam<int>("yaxis")),
52  _xaxis(getParam<int>("xaxis")),
53  _axisValid(_axis > -1 && _axis < 3),
54  _yaxisValid(_yaxis > -1 && _yaxis < 3),
55  _xaxisValid(_xaxis > -1 && _xaxis < 3),
56  _scale_factor(getParam<Real>("scale_factor")),
57  _radial(getParam<bool>("radial"))
58 {
59 
60  if (!_axisValid && !_yaxisValid && !_xaxisValid)
61  mooseError("In PiecewiseBilinear ",
62  _name,
63  ": None of axis, yaxis, or xaxis properly defined. Allowable range is 0-2");
64 
66  mooseError("In PiecewiseBilinear ", _name, ": Cannot define axis with either yaxis or xaxis");
67 
68  if (_radial && (!_yaxisValid || !_xaxisValid))
69  mooseError(
70  "In PiecewiseBilinear ", _name, ": yaxis and xaxis must be defined when radial = true");
71 
72  std::vector<Real> x;
73  std::vector<Real> y;
75  std::vector<Real> z_vec;
76 
77  if (!_data_file_name.empty())
78  {
79  if (parameters.isParamValid("x") || parameters.isParamValid("y") ||
80  parameters.isParamValid("z"))
81  mooseError("In PiecewiseBilinear: Cannot specify 'data_file' and 'x', 'y', or 'z' together.");
82  else
83  parse(x, y, z);
84  }
85 
86  else if (!(parameters.isParamValid("x") && parameters.isParamValid("y") &&
87  parameters.isParamValid("z")))
88  mooseError(
89  "In PiecewiseBilinear: 'x' and 'y' and 'z' must be specified if any one is specified.");
90 
91  else
92  {
93  x = getParam<std::vector<Real>>("x");
94  y = getParam<std::vector<Real>>("y");
95  z_vec = getParam<std::vector<Real>>("z");
96 
97  // check that size of z = (size of x)*(size of y)
98  if (z_vec.size() != x.size() * y.size())
99  mooseError("In PiecewiseBilinear: Size of z should be the size of x times the size of y.");
100 
101  // reshape and populate z matrix
102  z.reshape(y.size(), x.size());
103  int idx = 0;
104  for (unsigned int i = 0; i < y.size(); i++)
105  for (unsigned int j = 0; j < x.size(); j++)
106  {
107  z(i, j) = z_vec[idx];
108  idx += 1;
109  }
110  }
111 
112  _bilinear_interp = libmesh_make_unique<BilinearInterpolation>(x, y, z);
113 }
114 
116 
117 Real
118 PiecewiseBilinear::value(Real t, const Point & p)
119 {
120  Real retVal(0);
121  if (_yaxisValid && _xaxisValid && _radial)
122  {
123  Real rx = p(_xaxis) * p(_xaxis);
124  Real ry = p(_yaxis) * p(_yaxis);
125  Real r = std::sqrt(rx + ry);
126  retVal = _bilinear_interp->sample(r, t);
127  }
128  else if (_axisValid)
129  retVal = _bilinear_interp->sample(p(_axis), t);
130  else if (_yaxisValid && !_radial)
131  {
132  if (_xaxisValid)
133  retVal = _bilinear_interp->sample(p(_xaxis), p(_yaxis));
134  else
135  retVal = _bilinear_interp->sample(t, p(_yaxis));
136  }
137  else
138  retVal = _bilinear_interp->sample(p(_xaxis), t);
139 
140  return retVal * _scale_factor;
141 }
142 
143 void
144 PiecewiseBilinear::parse(std::vector<Real> & x, std::vector<Real> & y, ColumnMajorMatrix & z)
145 {
146  std::ifstream file(_data_file_name.c_str());
147  if (!file.good())
148  mooseError("In PiecewiseBilinear ", _name, ": Error opening file '" + _data_file_name + "'.");
149  std::string line;
150  unsigned int linenum = 0;
151  unsigned int itemnum = 0;
152  unsigned int num_cols = 0;
153  std::vector<Real> data;
154 
155  while (getline(file, line))
156  {
157  linenum++;
158  std::istringstream linestream(line);
159  std::string item;
160  itemnum = 0;
161 
162  while (getline(linestream, item, ','))
163  {
164  itemnum++;
165  std::istringstream i(item);
166  Real d;
167  i >> d;
168  data.push_back(d);
169  }
170 
171  if (linenum == 1)
172  num_cols = itemnum;
173  else if (num_cols + 1 != itemnum)
174  mooseError("In PiecewiseBilinear ",
175  _name,
176  ": Read ",
177  itemnum,
178  " columns of data but expected ",
179  num_cols + 1,
180  " columns while reading line ",
181  linenum,
182  " of '",
184  "'.");
185  }
186 
187  x.resize(itemnum - 1);
188  y.resize(linenum - 1);
189  z.reshape(linenum - 1, itemnum - 1);
190  unsigned int offset(0);
191  // Extract the first line's data (the x axis data)
192  for (unsigned int j = 0; j < itemnum - 1; ++j)
193  {
194  x[j] = data[offset];
195  ++offset;
196  }
197  for (unsigned int i = 0; i < linenum - 1; ++i)
198  {
199  // Extract the y axis entry for this line
200  y[i] = data[offset];
201  ++offset;
202 
203  // Extract the function values for this row in the matrix
204  for (unsigned int j = 0; j < itemnum - 1; ++j)
205  {
206  z(i, j) = data[offset];
207  ++offset;
208  }
209  }
210 
211  if (data.size() != offset)
212  mooseError("ERROR! Inconsistency in data read from '" + _data_file_name +
213  "' for PiecewiseBilinear function.");
214 }
Base class for function objects.
Definition: Function.h:46
InputParameters validParams< PiecewiseBilinear >()
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
static PetscErrorCode Vec x
This class defines a Tensor that can change its shape.
void parse(std::vector< Real > &x, std::vector< Real > &y, ColumnMajorMatrix &z)
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.
virtual Real value(Real t, const Point &pt) override
This function will return a value based on the first input argument only.
void reshape(const unsigned int rows, const unsigned int cols)
Change the shape of the tensor.
std::unique_ptr< BilinearInterpolation > _bilinear_interp
const std::string & _name
The name of this object, reference to value stored in InputParameters.
Definition: MooseObject.h:114
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...
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
void mooseError(Args &&...args) const
Definition: MooseObject.h:80
virtual ~PiecewiseBilinear()
InputParameters validParams< Function >()
Definition: Function.C:19
const std::string _data_file_name
PiecewiseBilinear(const InputParameters &parameters)