www.mooseframework.org
Piecewise.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 "Piecewise.h"
16 #include "DelimitedFileReader.h"
17 
18 #include <fstream>
19 
20 template <>
23 {
25  params.addParam<std::vector<Real>>("xy_data",
26  "All function data, supplied in abscissa, ordinate pairs");
27  params.addParam<std::vector<Real>>("x", "The abscissa values");
28  params.addParam<std::vector<Real>>("y", "The ordinate values");
29  params.addParam<FileName>("data_file", "File holding csv data for use with Piecewise");
30  params.addParam<unsigned int>("x_index_in_file", 0, "The abscissa index in the data file");
31  params.addParam<unsigned int>("y_index_in_file", 1, "The ordinate index in the data file");
32  params.addParam<bool>(
33  "xy_in_file_only", true, "If the data file only contains abscissa and ordinate data");
34 
35  MooseEnum format("columns=0 rows=1", "rows");
36  params.addParam<MooseEnum>(
37  "format", format, "Format of csv data file that is in either in columns or rows");
38  params.addParam<Real>("scale_factor", 1.0, "Scale factor to be applied to the ordinate values");
39 
40  MooseEnum axis("x=0 y=1 z=2 0=3 1=4 2=5");
41  axis.deprecate("0", "x");
42  axis.deprecate("1", "y");
43  axis.deprecate("2", "z");
44  params.addParam<MooseEnum>(
45  "axis", axis, "The axis used (x, y, or z) if this is to be a function of position");
46  return params;
47 }
48 
50  : Function(parameters), _scale_factor(getParam<Real>("scale_factor")), _has_axis(false)
51 {
52  std::pair<std::vector<Real>, std::vector<Real>> xy;
53 
54  if (isParamValid("data_file"))
55  xy = buildFromFile();
56 
57  else if (isParamValid("x") || isParamValid("y"))
58  xy = buildFromXandY();
59 
60  else if (isParamValid("xy_data"))
61  xy = buildFromXY();
62 
63  else
64  mooseError("In Piecewise ",
65  _name,
66  ": Either 'data_file', 'x' and 'y', or 'xy_data' must be specified.");
67 
68  setData(xy.first, xy.second);
69 }
70 
71 void
72 Piecewise::setData(const std::vector<Real> & x, const std::vector<Real> & y)
73 {
74  // Size mismatch error
75  if (x.size() != y.size())
76  mooseError("In Piecewise ", _name, ": Lengths of x and y data do not match.");
77 
78  try
79  {
80  _linear_interp = libmesh_make_unique<LinearInterpolation>(x, y);
81  }
82  catch (std::domain_error & e)
83  {
84  mooseError("In Piecewise ", _name, ": ", e.what());
85  }
86 
87  if (isParamValid("axis"))
88  {
89  const MooseEnum & axis = getParam<MooseEnum>("axis");
90  switch (axis)
91  {
92  case 0:
93  case 1:
94  case 2:
95  _axis = axis;
96  break;
97  case 3:
98  case 4:
99  case 5:
100  _axis = axis - 3;
101  break;
102  }
103  _has_axis = true;
104  }
105 }
106 
107 Real
109 {
110  return _linear_interp->getSampleSize();
111 }
112 
113 Real
115 {
116  return _linear_interp->domain(i);
117 }
118 
119 Real
121 {
122  return _linear_interp->range(i);
123 }
124 
125 std::pair<std::vector<Real>, std::vector<Real>>
127 {
128  // Input parameters
129  const FileName & data_file_name = getParam<FileName>("data_file");
130  const MooseEnum & format = getParam<MooseEnum>("format");
131  unsigned int x_index = getParam<unsigned int>("x_index_in_file");
132  unsigned int y_index = getParam<unsigned int>("y_index_in_file");
133  bool xy_only = getParam<bool>("xy_in_file_only");
134 
135  // Check that other forms of input are not set.
136  if (isParamValid("x") || isParamValid("y") || isParamValid("xy_data"))
137  mooseError("In Piecewise ",
138  _name,
139  ": Cannot specify 'data_file' and 'x', 'y', or 'xy_data' together.");
140 
141  if (x_index == y_index)
142  mooseError("In Piecewise ",
143  _name,
144  ": 'x_index_in_file' and 'y_index_in_file' are set to the same value.");
145 
146  // Read the data from CSV file
147  MooseUtils::DelimitedFileReader reader(data_file_name, &_communicator);
149  reader.setComment("#");
150  reader.read();
151  const std::vector<std::vector<double>> & data = reader.getData();
152 
153  // Check the data format
154  if (x_index >= data.size())
155  mooseError("In Piecewise ",
156  _name,
157  ": The 'x_index_in_file' is out-of-range of the available data in '",
158  data_file_name,
159  "', which contains ",
160  data.size(),
161  " ",
162  format,
163  " of data.");
164 
165  if (y_index >= data.size())
166  mooseError("In Piecewise ",
167  _name,
168  ": The 'y_index_in_file' is out-of-range of the available data in '",
169  data_file_name,
170  "', which contains ",
171  data.size(),
172  " ",
173  format,
174  " of data.");
175 
176  if (data.size() > 2 && xy_only)
177  mooseError("In Piecewise ",
178  _name,
179  ": Read more than two ",
180  format,
181  " of data from file '",
182  data_file_name,
183  "'. Did you mean to use \"format = ",
184  format == "columns" ? "rows" : "columns",
185  "\" or set \"xy_in_file_only\" to false?");
186 
187  // Update the input vectors to contained the desired data
188  return std::make_pair(reader.getData(x_index), reader.getData(y_index));
189 }
190 
191 std::pair<std::vector<Real>, std::vector<Real>>
193 {
194  if (!isParamValid("x") || !isParamValid("y"))
195  mooseError(
196  "In Piecewise ", _name, ": Both 'x' and 'y' must be specified if either one is specified.");
197 
198  if (isParamValid("xy_data"))
199  mooseError("In Piecewise ", _name, ": Cannot specify 'x', 'y', and 'xy_data' together.");
200 
201  return std::make_pair(getParam<std::vector<Real>>("x"), getParam<std::vector<Real>>("y"));
202 }
203 
204 std::pair<std::vector<Real>, std::vector<Real>>
206 {
207  std::vector<Real> xy = getParam<std::vector<Real>>("xy_data");
208  unsigned int xy_size = xy.size();
209  if (xy_size % 2 != 0)
210  mooseError(
211  "In Piecewise ", _name, ": Length of data provided in 'xy_data' must be a multiple of 2.");
212 
213  unsigned int data_size = xy_size / 2;
214  std::vector<Real> x;
215  std::vector<Real> y;
216  x.reserve(data_size);
217  y.reserve(data_size);
218  for (unsigned int i = 0; i < xy_size; i += 2)
219  {
220  x.push_back(xy[i]);
221  y.push_back(xy[i + 1]);
222  }
223  return std::make_pair(x, y);
224 }
void read()
Perform the actual data reading.
Base class for function objects.
Definition: Function.h:46
Utility class for reading delimited data (e.g., CSV data).
void setComment(const std::string &value)
int _axis
Definition: Piecewise.h:63
bool _has_axis
Definition: Piecewise.h:64
const std::vector< std::vector< double > > & getData() const
Return the rows/columns of data.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
static PetscErrorCode Vec x
std::pair< std::vector< Real >, std::vector< Real > > buildFromXY()
Builds data from &#39;xy_data&#39; parameter.
Definition: Piecewise.C:205
void setData(const std::vector< Real > &x, const std::vector< Real > &y)
Provides a means for explicitly setting the x and y data.
Definition: Piecewise.C:72
std::pair< std::vector< Real >, std::vector< Real > > buildFromXandY()
Builds data from &#39;x&#39; and &#39;y&#39; parameters.
Definition: Piecewise.C:192
InputParameters validParams< Piecewise >()
Definition: Piecewise.C:22
void setFormatFlag(FormatFlag value)
virtual Real domain(int i)
Definition: Piecewise.C:114
std::unique_ptr< LinearInterpolation > _linear_interp
Definition: Piecewise.h:62
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:37
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseObject.h:67
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition: MooseObject.h:122
virtual Real range(int i)
Definition: Piecewise.C:120
const std::string & _name
The name of this object, reference to value stored in InputParameters.
Definition: MooseObject.h:114
std::pair< std::vector< Real >, std::vector< Real > > buildFromFile()
Reads data from supplied CSV file.
Definition: Piecewise.C:126
Piecewise(const InputParameters &parameters)
Definition: Piecewise.C:49
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...
void mooseError(Args &&...args) const
Definition: MooseObject.h:80
InputParameters validParams< Function >()
Definition: Function.C:19
virtual Real functionSize()
Definition: Piecewise.C:108