https://mooseframework.inl.gov
PiecewiseBilinear.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 
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  _xaxis(getParam<int>("xaxis")),
47  _yaxis(getParam<int>("yaxis")),
48  _data_file_name(getParam<FileName>("data_file")),
49  _axis(getParam<int>("axis")),
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  using std::sqrt;
136  const auto r = sqrt(rx + ry);
137  retVal = _bilinear_interp->sample(r, t);
138  }
139  else if (_axisValid)
140  retVal = _bilinear_interp->sample(p(_axis), t);
141  else if (_yaxisValid && !_radial)
142  {
143  if (_xaxisValid)
144  retVal = _bilinear_interp->sample(p(_xaxis), p(_yaxis));
145  else
146  retVal = _bilinear_interp->sample(t, p(_yaxis));
147  }
148  else
149  retVal = _bilinear_interp->sample(p(_xaxis), t);
150 
151  return retVal * _scale_factor;
152 }
153 
154 void
155 PiecewiseBilinear::parse(const std::string & data_file_name,
156  std::vector<Real> & x,
157  std::vector<Real> & y,
158  ColumnMajorMatrix & z,
159  const std::string & object_name)
160 {
161  std::ifstream file(data_file_name.c_str());
162  if (!file.good())
163  ::mooseError(object_name, " : Error opening file '", data_file_name, "'.");
164 
165  std::size_t num_lines = 0;
166  std::size_t num_cols = libMesh::invalid_uint;
167  std::vector<Real> data;
168 
169  std::string line;
170  std::vector<Real> line_data;
171  while (std::getline(file, line))
172  {
173  num_lines++;
174  if (!MooseUtils::tokenizeAndConvert<double>(line, line_data, ", "))
175  ::mooseError(object_name, " : Error parsing file '", data_file_name, "' on line ", num_lines);
176 
177  data.insert(data.end(), line_data.begin(), line_data.end());
178 
179  if (num_cols == libMesh::invalid_uint)
180  num_cols = line_data.size();
181  else if (line_data.size() != num_cols + 1)
182  ::mooseError(object_name,
183  " : Read ",
184  line_data.size(),
185  " columns of data but expected ",
186  num_cols + 1,
187  " columns in line ",
188  num_lines);
189  }
190 
191  x.resize(num_cols);
192  y.resize(num_lines - 1);
193  z.reshape(num_lines - 1, num_cols);
194  std::size_t offset = 0;
195 
196  // Extract the first line's data (the x axis data)
197  for (unsigned int j = 0; j < num_cols; ++j)
198  x[j] = data[offset++];
199 
200  for (unsigned int i = 0; i < num_lines - 1; ++i)
201  {
202  // Extract the y axis entry for this line
203  y[i] = data[offset++];
204 
205  // Extract the function values for this row in the matrix
206  for (unsigned int j = 0; j < num_cols; ++j)
207  z(i, j) = data[offset++];
208  }
209 
210  if (data.size() != offset)
211  ::mooseError(object_name, " : Inconsistency in data read from '", data_file_name, "'.");
212 }
Base class for function objects.
Definition: Function.h:29
const unsigned int invalid_uint
const std::string & _name
The name of this class.
Definition: MooseBase.h:363
static InputParameters validParams()
registerMooseObject("MooseApp", PiecewiseBilinear)
void reshape(const unsigned int rows, const unsigned int cols)
Change the shape of the tensor.
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseBase.h:131
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...
DualNumber< Real, DNDerivativeType, true > ADReal
Definition: ADRealForward.h:42
T valueInternal(T t, const P &p) const
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:103
virtual Real value(Real t, const Point &pt) const override
This function will return a value based on the first input argument only.
std::unique_ptr< BilinearInterpolation > _bilinear_interp
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
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 and optionally a file path to the top-level block p...
Definition: MooseBase.h:271
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 optional parameter and a documentation string to the InputParameters object...
const Real _scale_factor
virtual ~PiecewiseBilinear()
static InputParameters validParams()
Class constructor.
Definition: Function.C:16
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.