https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PropertyReadFile.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 "PropertyReadFile.h"
11#include "MooseRandom.h"
12#include "MooseMesh.h"
13
14#include <fstream>
15
19 "06/30/2021 24:00",
21
24{
26 params.addClassDescription("User Object to read property data from an external file and assign "
27 "it to elements / nodes / subdomains etc.");
28
29 // Data source file(s)
30 params.addParam<std::vector<FileName>>(
31 "prop_file_name",
32 "Name(s) of the property file name. If specifying multiple files, the next file will be read "
33 "at initialization right before every execution");
34 params.addParam<FileName>("prop_file_names_csv",
35 "Name(s) of a CSV file containing the list of the property file names "
36 "as its first column, with no header.");
37
38 // Data organization
39 params.addRequiredParam<unsigned int>("nprop", "Number of tabulated property values");
40 params.addParam<unsigned int>(
41 "nvoronoi", 0, "Number of voronoi tesselations/grains/nearest neighbor regions");
42 params.addDeprecatedParam<unsigned int>(
43 "ngrain", "Number of grains.", "ngrain is deprecated, use nvoronoi instead");
44 params.addParam<unsigned int>("nblock", 0, "Number of blocks");
45 params.addRequiredParam<MooseEnum>("read_type",
46 MooseEnum("element voronoi block node grain"),
47 "Type of property distribution: "
48 "element:by element "
49 "node: by node "
50 "voronoi:nearest neighbor / voronoi grain structure "
51 "block:by mesh block "
52 "grain: deprecated, use voronoi");
53 params.addParam<bool>("use_random_voronoi",
54 false,
55 "Wether to generate random positions for the Voronoi tesselation");
56 params.addParam<unsigned int>("rand_seed", 2000, "random seed");
57 params.addParam<MooseEnum>(
58 "rve_type",
59 MooseEnum("periodic none", "none"),
60 "Periodic or non-periodic grain distribution: Default is non-periodic");
61 params.addParam<bool>(
62 "use_zero_based_block_indexing", true, "Are the blocks numbered starting at zero?");
63
64 // Data reading schedule
65 params.addParam<bool>(
66 "load_first_file_on_construction",
67 true,
68 "Whether to read the first CSV file on construction or on the first execution");
69
70 // Set an execution schedule to what makes sense currently
71 // We do not allow INITIAL because we read the file at construction
72 ExecFlagEnum & exec_enum = params.set<ExecFlagEnum>("execute_on", true);
74 params.setDocString("execute_on", exec_enum.getDocString());
75 // we must read the files as early as possible
76 params.set<bool>("force_preaux") = true;
77
78 return params;
79}
80
82 : GeneralUserObject(parameters),
83 _prop_file_names(getFileNames()),
84 _current_file_index(declareRestartableData<unsigned int>("file_index", 0)),
85 // index of files must be capped if restarting after having read all files
86 _reader(
87 _prop_file_names[std::min(_current_file_index, (unsigned int)_prop_file_names.size() - 1)]),
88 _read_type(getParam<MooseEnum>("read_type").getEnum<ReadTypeEnum>()),
89 _use_random_tesselation(getParam<bool>("use_random_voronoi")),
90 _rand_seed(getParam<unsigned int>("rand_seed")),
91 _rve_type(getParam<MooseEnum>("rve_type")),
92 _block_zero(getParam<bool>("use_zero_based_block_indexing")),
93 _ngrain(isParamValid("ngrain") ? getParam<unsigned int>("ngrain")
94 : getParam<unsigned int>("nvoronoi")),
95 _mesh(_fe_problem.mesh()),
96 _nprop(getParam<unsigned int>("nprop")),
97 _nvoronoi(isParamValid("ngrain") ? getParam<unsigned int>("ngrain")
98 : getParam<unsigned int>("nvoronoi")),
99 _nblock(getParam<unsigned int>("nblock")),
100 _initialize_called_once(declareRestartableData<bool>("initialize_called", false)),
101 _load_on_construction(getParam<bool>("load_first_file_on_construction"))
102{
104 paramError("rand_seed",
105 "Random seeds should only be provided if random tesselation is desired");
106
107 Point mesh_min, mesh_max;
108 for (unsigned int i : make_range(Moose::dim))
109 {
110 mesh_min(i) = _mesh.getMinInDimension(i);
111 mesh_max(i) = _mesh.getMaxInDimension(i);
112 }
113 _bounding_box = MooseUtils::buildBoundingBox(mesh_min, mesh_max);
114
116 readData();
117}
118
119std::vector<FileName>
121{
122 std::vector<FileName> prop_file_names;
123 // Retrieve the property file names
124 if (isParamValid("prop_file_name") && !isParamValid("prop_file_names_csv"))
125 prop_file_names = getParam<std::vector<FileName>>("prop_file_name");
126 else if (isParamValid("prop_file_names_csv") && !isParamValid("prop_file_name"))
127 {
129 getParam<FileName>("prop_file_names_csv"));
131 file_name_reader.read();
132 if (file_name_reader.getData().size())
133 {
134 const auto fdata = file_name_reader.getData(0);
135 for (const auto & fname : fdata)
136 prop_file_names.push_back(fname);
137 }
138 }
139 else
140 paramError("prop_file_name",
141 "The names of the property files must be provided with either 'prop_file_name' "
142 "or 'prop_file_names_csv'. Providing both or none is not supported.");
143 if (prop_file_names.empty())
144 paramError("prop_file_name", "A property file should have been specified.");
145 return prop_file_names;
146}
147
148void
150{
151 // Since we read at construction, no need to re-read the file on first initialize
153 {
155 return;
156 }
157
158 // Set then read new file, only if we have not reached the last file
160 {
162 readData();
163 }
164 else if (_prop_file_names.size() > 1 && _current_file_index == _prop_file_names.size())
165 mooseInfo("Last file specified has been read. The file will no longer be updated.");
166}
167
168void
170{
171 if (_read_type == ReadTypeEnum::ELEMENT && _mesh.getMesh().allow_renumbering())
172 mooseWarning("CSV data is sorted by element, but mesh element renumbering is on, be careful!");
173 if (_read_type == ReadTypeEnum::NODE && _mesh.getMesh().allow_renumbering())
174 mooseWarning("CSV data is sorted by node, but mesh node renumbering is on, be careful!");
175
177 _reader.read();
178
179 unsigned int nobjects = 0;
180
181 switch (_read_type)
182 {
184 nobjects = _mesh.nElem();
185 break;
186
188 nobjects = _mesh.nNodes();
189 break;
190
192 if (_nvoronoi <= 0)
193 paramError("nvoronoi", "Provide non-zero number of voronoi tesselations/grains.");
194 nobjects = _nvoronoi;
195 break;
196
197 // TODO Delete after Grizzly update see idaholab/Grizzly#182
199 if (_nvoronoi <= 0)
200 paramError("ngrain", "Provide non-zero number of voronoi tesselations/grains.");
201 nobjects = _nvoronoi;
202 break;
203
205 if (_nblock <= 0)
206 paramError("nblock", "Provide non-zero number of blocks.");
207 nobjects = _nblock;
208 break;
209 }
210
211 // make sure the data from file has enough rows and columns
212 if (_reader.getData().size() < nobjects)
213 mooseError("Data in ",
215 " does not have enough rows for ",
216 nobjects,
217 " objects.");
218 if (_reader.getData().size() > nobjects)
219 mooseWarning("Data size in ",
221 " is larger than ",
222 nobjects,
223 " objects, some data will not be used.");
224 for (unsigned int i = 0; i < nobjects; i++)
225 if (_reader.getData(i).size() < _nprop)
226 mooseError("Row ",
227 i,
228 " in ",
230 " has number of data less than ",
231 _nprop);
232
235
237}
238
239void
241{
242 _center.resize(_nvoronoi);
243
244 // Generate a random tesselation
246 {
248 for (const auto i : make_range(_nvoronoi))
249 for (const auto j : make_range(Moose::dim))
250 _center[i](j) = _bounding_box.min()(j) +
251 MooseRandom::rand() * (_bounding_box.max() - _bounding_box.min())(j);
252 }
253 // Read tesselation from file
254 else
255 {
256 for (const auto i : make_range(_nvoronoi))
257 for (const auto j : make_range(Moose::dim))
258 _center[i](j) = _reader.getData(i)[j];
259 }
260}
261
262Real
263PropertyReadFile::getData(const Elem * const elem, const unsigned int prop_num) const
264{
265 if (prop_num > _nprop)
267 "nprop", "Property number ", prop_num, " greater than total number of properties ", _nprop);
268
269 Real data = 0.0;
270 switch (_read_type)
271 {
273 data = getElementData(elem, prop_num);
274 break;
275
277 data = getVoronoiData(elem->vertex_average(), prop_num);
278 break;
279
280 // TODO: Delete after Grizzly update
282 data = getVoronoiData(elem->vertex_average(), prop_num);
283 break;
284
286 data = getBlockData(elem, prop_num);
287 break;
288
291 "PropertyReadFile has data sorted by node, it should note be retrieved by element");
292 break;
293 }
294 return data;
295}
296
297Real
298PropertyReadFile::getElementData(const Elem * elem, unsigned int prop_num) const
299{
300 unsigned int jelem = elem->id();
301 if (jelem >= _mesh.nElem())
302 mooseError("Element ID ",
303 jelem,
304 " greater than than total number of element in mesh: ",
305 _mesh.nElem(),
306 ". Elements should be numbered consecutively, and ids should start from 0.");
307 return _reader.getData(jelem)[prop_num];
308}
309
310Real
311PropertyReadFile::getNodeData(const Node * const node, const unsigned int prop_num) const
312{
313 unsigned int jnode = node->id();
314 if (jnode >= _mesh.nNodes())
315 mooseError("Node ID ",
316 jnode,
317 " greater than than total number of nodes in mesh: ",
318 _mesh.nNodes(),
319 ". Nodes should be numbered consecutively, with ids starting from 0.");
320 return _reader.getData(jnode)[prop_num];
321}
322
323Real
324PropertyReadFile::getBlockData(const Elem * elem, unsigned int prop_num) const
325{
326 unsigned int offset = 0;
327 if (!_block_zero)
328 offset = 1;
329
330 unsigned int elem_subdomain_id = elem->subdomain_id();
331 if (elem_subdomain_id >= _nblock + offset)
332 paramError("nblock",
333 "Element block id ",
334 elem_subdomain_id,
335 " greater than than total number of blocks in mesh: ",
336 _nblock,
337 ". Blocks should be numbered consecutively, starting from 0.");
338 return _reader.getData(elem_subdomain_id - offset)[prop_num];
339}
340
341Real
342PropertyReadFile::getVoronoiData(const Point & point, const unsigned int prop_num) const
343{
344 Real min_dist = std::numeric_limits<Real>::max();
345 unsigned int ivoronoi = 0;
346
347 for (const auto i : make_range(_nvoronoi))
348 {
349 Real dist = 0.0;
350 switch (_rve_type)
351 {
352 case 0:
353 // Calculates minimum periodic distance when "periodic" is specified
354 // for rve_type
355 dist = minPeriodicDistance(_center[i], point);
356 break;
357
358 default:
359 // Calculates minimum distance when nothing is specified
360 // for rve_type
361 Point dist_vec = _center[i] - point;
362 dist = dist_vec.norm();
363 }
364
365 if (dist < min_dist)
366 {
367 min_dist = dist;
368 ivoronoi = i;
369 }
370 }
371 return _reader.getData(ivoronoi)[prop_num];
372}
373
374// TODO: this should probably use the built-in min periodic distance!
375Real
376PropertyReadFile::minPeriodicDistance(const Point & c, const Point & p) const
377{
378 Point dist_vec = c - p;
379 Real min_dist = dist_vec.norm();
380
381 Real fac[3] = {-1.0, 0.0, 1.0};
382 for (unsigned int i = 0; i < 3; i++)
383 for (unsigned int j = 0; j < 3; j++)
384 for (unsigned int k = 0; k < 3; k++)
385 {
386 Point p1;
387 p1(0) = p(0) + fac[i] * (_bounding_box.max() - _bounding_box.min())(0);
388 p1(1) = p(1) + fac[j] * (_bounding_box.max() - _bounding_box.min())(1);
389 p1(2) = p(2) + fac[k] * (_bounding_box.max() - _bounding_box.min())(2);
390
391 dist_vec = c - p1;
392 Real dist = dist_vec.norm();
393
394 if (dist < min_dist)
395 min_dist = dist;
396 }
397
398 return min_dist;
399}
void mooseInfo(Args &&... args)
Emit an informational message with the given stringified, concatenated args.
Definition MooseError.h:401
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
Definition MooseError.h:345
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
const ExecFlagType EXEC_INITIAL
Definition Moose.C:30
const ExecFlagType EXEC_LINEAR
Definition Moose.C:31
const ExecFlagType EXEC_NONLINEAR
Definition Moose.C:33
const ExecFlagType EXEC_FINAL
Definition Moose.C:48
registerMooseObject("MooseApp", PropertyReadFile)
registerMooseObjectRenamed("MooseApp", ElementPropertyReadFile, "06/30/2021 24:00", PropertyReadFile)
void ErrorVector unsigned int
A MultiMooseEnum object to hold "execute_on" flags.
void removeAvailableFlags(const ExecFlagType &flag, Args... flags)
Remove flags from being available.
static InputParameters validParams()
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
bool isParamSetByUser(const std::string &name) const
Method returns true if the parameter was set by the user.
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.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
void addDeprecatedParam(const std::string &name, const T &value, const std::string &doc_string, const std::string &deprecation_message)
void setDocString(const std::string &name, const std::string &doc)
Set the doc string of a parameter.
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.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
const InputParameters & parameters() const
Get the parameters of the object.
Definition MooseBase.h:131
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition MooseMesh.C:3549
virtual Real getMaxInDimension(unsigned int component) const
Definition MooseMesh.C:2186
virtual dof_id_type nNodes() const
Calls n_nodes/elem() on the underlying libMesh mesh object.
Definition MooseMesh.C:3176
virtual Real getMinInDimension(unsigned int component) const
Returns the min or max of the requested dimension respectively.
Definition MooseMesh.C:2177
virtual dof_id_type nElem() const
Definition MooseMesh.C:3182
static Real rand()
This method returns the next random number (Real format) from the generator.
Definition MooseRandom.h:50
static void seed(unsigned int seed)
The method seeds the random number generator.
Definition MooseRandom.h:44
Utility class for reading delimited data (e.g., CSV data).
const std::vector< std::vector< T > > & getData() const
Return the rows/columns of data.
void setFileName(const std::string &new_file)
Set the file name, used to change the file to read from We also reset the column/row names as a secon...
void read()
Perform the actual data reading.
Read properties from file - grain, element, node or block Input file syntax: prop1 prop2 etc.
Real getData(const Elem *const elem, const unsigned int prop_num) const
This function retrieves property data for elements.
Real getElementData(const Elem *const elem, const unsigned int prop_num) const
This function retrieves properties for elements, from a file that has element-based data.
const unsigned int _rand_seed
Random seed - used for generating grain centers.
const bool _use_random_tesselation
Parameters for the nearest neighbor / grain interpolation Whether to use a random tesselation for the...
unsigned int & _current_file_index
Index of the file we last read.
Real getVoronoiData(const Point &point, const unsigned int prop_num) const
This function retrieves properties for elements from a file with nearest neighbor / grain based prope...
bool _block_zero
Do the block numbers start with zero or one?
std::vector< FileName > _prop_file_names
Name of file containing property values.
BoundingBox _bounding_box
Bounding box for the mesh.
Real getNodeData(const Node *const node, const unsigned int prop_num) const
This function retrieves properties for nodes, from a file that has node-based data.
MooseUtils::DelimitedFileReader _reader
Use DelimitedFileReader to read and store data from file.
void readData()
This function reads the data from file.
virtual void initVoronoiCenterPoints()
This function generates voronoi tesselation center points Presently random generated.
virtual void initialize()
Called before execute() is ever called so that data can be cleared.
PropertyReadFile(const InputParameters &parameters)
bool & _initialize_called_once
To keep track of initialization to avoid reading the files twice.
Real getBlockData(const Elem *const elem, const unsigned int prop_num) const
This function retrieves properties for elements, from a file that has block-based data.
const ReadTypeEnum _read_type
Type of read - element, grain, or block.
const unsigned int _nblock
Number of blocks (for reading a CSV file with properties ordered by blocks)
const MooseEnum _rve_type
Type of voronoi tesselation/grain structure - non-periodic default.
std::vector< Point > _center
const unsigned int _nvoronoi
Number of grains (for reading a CSV file with properties ordered by grains)
std::vector< FileName > getFileNames()
Retrieve the property file names from the parameters.
static InputParameters validParams()
Real minPeriodicDistance(const Point &, const Point &) const
This function calculates minimum distance between 2 points considering periodicity of the simulation ...
ReadTypeEnum
How data is organized in the CSV file.
const unsigned int _nprop
Class attributes useful for range-checking Number of properties in a row.
const bool _load_on_construction
Whether to read the first CSV file in the constructor or on the first initialization before execution...
MeshBase & mesh
BoundingBox buildBoundingBox(const Point &p1, const Point &p2)
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition Moose.h:165