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 
14 #include <fstream>
15 
17 
18 template <>
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(x, y, z);
81  }
82 
83  else if (!(parameters.isParamValid("x") && parameters.isParamValid("y") &&
85  mooseError(
86  "In PiecewiseBilinear: 'x' and 'y' and 'z' must be specified if any one 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 = libmesh_make_unique<BilinearInterpolation>(x, y, z);
110 }
111 
113 
114 Real
115 PiecewiseBilinear::value(Real t, const Point & p)
116 {
117  Real retVal(0);
118  if (_yaxisValid && _xaxisValid && _radial)
119  {
120  Real rx = p(_xaxis) * p(_xaxis);
121  Real ry = p(_yaxis) * p(_yaxis);
122  Real r = std::sqrt(rx + ry);
123  retVal = _bilinear_interp->sample(r, t);
124  }
125  else if (_axisValid)
126  retVal = _bilinear_interp->sample(p(_axis), t);
127  else if (_yaxisValid && !_radial)
128  {
129  if (_xaxisValid)
130  retVal = _bilinear_interp->sample(p(_xaxis), p(_yaxis));
131  else
132  retVal = _bilinear_interp->sample(t, p(_yaxis));
133  }
134  else
135  retVal = _bilinear_interp->sample(p(_xaxis), t);
136 
137  return retVal * _scale_factor;
138 }
139 
140 void
141 PiecewiseBilinear::parse(std::vector<Real> & x, std::vector<Real> & y, ColumnMajorMatrix & z)
142 {
143  std::ifstream file(_data_file_name.c_str());
144  if (!file.good())
145  mooseError("In PiecewiseBilinear ", _name, ": Error opening file '" + _data_file_name + "'.");
146  std::string line;
147  unsigned int linenum = 0;
148  unsigned int itemnum = 0;
149  unsigned int num_cols = 0;
150  std::vector<Real> data;
151 
152  while (getline(file, line))
153  {
154  linenum++;
155  std::istringstream linestream(line);
156  std::string item;
157  itemnum = 0;
158 
159  while (getline(linestream, item, ','))
160  {
161  itemnum++;
162  std::istringstream i(item);
163  Real d;
164  i >> d;
165  data.push_back(d);
166  }
167 
168  if (linenum == 1)
169  num_cols = itemnum;
170  else if (num_cols + 1 != itemnum)
171  mooseError("In PiecewiseBilinear ",
172  _name,
173  ": Read ",
174  itemnum,
175  " columns of data but expected ",
176  num_cols + 1,
177  " columns while reading line ",
178  linenum,
179  " of '",
181  "'.");
182  }
183 
184  x.resize(itemnum - 1);
185  y.resize(linenum - 1);
186  z.reshape(linenum - 1, itemnum - 1);
187  unsigned int offset(0);
188  // Extract the first line's data (the x axis data)
189  for (unsigned int j = 0; j < itemnum - 1; ++j)
190  {
191  x[j] = data[offset];
192  ++offset;
193  }
194  for (unsigned int i = 0; i < linenum - 1; ++i)
195  {
196  // Extract the y axis entry for this line
197  y[i] = data[offset];
198  ++offset;
199 
200  // Extract the function values for this row in the matrix
201  for (unsigned int j = 0; j < itemnum - 1; ++j)
202  {
203  z(i, j) = data[offset];
204  ++offset;
205  }
206  }
207 
208  if (data.size() != offset)
209  mooseError("ERROR! Inconsistency in data read from '" + _data_file_name +
210  "' for PiecewiseBilinear function.");
211 }
Base class for function objects.
Definition: Function.h:40
InputParameters validParams< PiecewiseBilinear >()
registerMooseObject("MooseApp", PiecewiseBilinear)
void reshape(const unsigned int rows, const unsigned int cols)
Change the shape of the tensor.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void mooseError(Args &&... args) const
Definition: MooseObject.h:147
static PetscErrorCode Vec x
void parse(std::vector< Real > &x, std::vector< Real > &y, ColumnMajorMatrix &z)
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseObject.h:65
virtual Real value(Real t, const Point &pt) override
This function will return a value based on the first input argument only.
std::unique_ptr< BilinearInterpolation > _bilinear_interp
const std::string & _name
The name of this object, reference to value stored in InputParameters.
Definition: MooseObject.h:183
PiecewiseBilinear reads from a file the information necessary to build the vectors x and y and the Co...
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
virtual ~PiecewiseBilinear()
InputParameters validParams< Function >()
Definition: Function.C:14
const std::string _data_file_name
PiecewiseBilinear(const InputParameters &parameters)
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.