www.mooseframework.org
ParsedMaterialHelper.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 "ParsedMaterialHelper.h"
11 
12 #include "libmesh/quadrature.h"
13 
14 template <bool is_ad>
17 {
20  params.addClassDescription("Parsed Function Material.");
21  params.addParam<bool>("error_on_missing_material_properties",
22  true,
23  "Throw an error if any explicitly requested material property does not "
24  "exist. Otherwise assume it to be zero.");
25  MultiMooseEnum extra_symbols("x y z t dt");
26  params.addParam<MultiMooseEnum>(
27  "extra_symbols",
28  extra_symbols,
29  "Special symbols, like point coordinates, time, and timestep size.");
30  return params;
31 }
32 
33 template <bool is_ad>
35  VariableNameMappingMode map_mode)
36  : FunctionMaterialBase<is_ad>(parameters),
37  FunctionParserUtils<is_ad>(parameters),
38  _symbol_names(_nargs),
39  _extra_symbols(
40  this->template getParam<MultiMooseEnum>("extra_symbols").template getEnum<ExtraSymbols>()),
41  _tol(0),
42  _map_mode(map_mode),
43  _error_on_missing_material_properties(
44  this->template getParam<bool>("error_on_missing_material_properties"))
45 {
46 }
47 
48 template <bool is_ad>
49 void
50 ParsedMaterialHelper<is_ad>::functionParse(const std::string & function_expression)
51 {
52  const std::vector<std::string> empty_string_vector;
53  functionParse(function_expression, empty_string_vector, empty_string_vector);
54 }
55 
56 template <bool is_ad>
57 void
58 ParsedMaterialHelper<is_ad>::functionParse(const std::string & function_expression,
59  const std::vector<std::string> & constant_names,
60  const std::vector<std::string> & constant_expressions)
61 {
62  const std::vector<std::string> empty_string_vector;
63  const std::vector<Real> empty_real_vector;
64  functionParse(function_expression,
65  constant_names,
66  constant_expressions,
67  empty_string_vector,
68  empty_string_vector,
69  empty_real_vector);
70 }
71 
72 template <bool is_ad>
73 void
74 ParsedMaterialHelper<is_ad>::functionParse(const std::string & function_expression,
75  const std::vector<std::string> & constant_names,
76  const std::vector<std::string> & constant_expressions,
77  const std::vector<std::string> & mat_prop_expressions,
78  const std::vector<std::string> & tol_names,
79  const std::vector<Real> & tol_values)
80 {
81  const std::vector<PostprocessorName> empty_pp_name_vector;
82  functionParse(function_expression,
83  constant_names,
84  constant_expressions,
85  mat_prop_expressions,
86  empty_pp_name_vector,
87  tol_names,
88  tol_values);
89 }
90 
91 template <bool is_ad>
92 void
94  const std::string & function_expression,
95  const std::vector<std::string> & constant_names,
96  const std::vector<std::string> & constant_expressions,
97  const std::vector<std::string> & mat_prop_expressions,
98  const std::vector<PostprocessorName> & postprocessor_names,
99  const std::vector<std::string> & tol_names,
100  const std::vector<Real> & tol_values)
101 {
102  // build base function object
103  _func_F = std::make_shared<SymFunction>();
104 
105  // set FParser internal feature flags
106  setParserFeatureFlags(_func_F);
107 
108  // initialize constants
109  addFParserConstants(_func_F, constant_names, constant_expressions);
110 
111  // add further constants coming from default value coupling
112  if (_map_mode == VariableNameMappingMode::USE_PARAM_NAMES)
113  for (const auto & acd : _arg_constant_defaults)
114  if (!_func_F->AddConstant(acd, this->_pars.defaultCoupledValue(acd)))
115  mooseError("Invalid constant name in parsed function object");
116 
117  // set variable names based on map_mode
118  switch (_map_mode)
119  {
120  case VariableNameMappingMode::USE_MOOSE_NAMES:
121  for (unsigned int i = 0; i < _nargs; ++i)
122  _symbol_names[i] = _arg_names[i];
123  break;
124 
125  case VariableNameMappingMode::USE_PARAM_NAMES:
126  for (unsigned i = 0; i < _nargs; ++i)
127  {
128  if (_arg_param_numbers[i] < 0)
129  _symbol_names[i] = _arg_param_names[i];
130  else
131  _symbol_names[i] = _arg_param_names[i] + std::to_string(_arg_param_numbers[i]);
132  }
133  break;
134 
135  default:
136  mooseError("Unknown variable mapping mode.");
137  }
138 
139  // tolerance vectors
140  if (tol_names.size() != tol_values.size())
141  mooseError("The parameter vectors tol_names and tol_values must have equal length.");
142 
143  // set tolerances
144  _tol.resize(_nargs);
145  for (const auto i : make_range(_nargs))
146  {
147  _tol[i] = -1.0;
148 
149  // for every argument look through the entire tolerance vector to find a match
150  for (const auto j : index_range(tol_names))
151  if (_symbol_names[i] == tol_names[j])
152  {
153  _tol[i] = tol_values[j];
154  break;
155  }
156  }
157 
158  // get all material properties
159  unsigned int nmat_props = mat_prop_expressions.size();
160  for (const auto i : make_range(nmat_props))
161  {
162  // parse the material property parameter entry into a FunctionMaterialPropertyDescriptor
163  _mat_prop_descriptors.emplace_back(
164  mat_prop_expressions[i], this, _error_on_missing_material_properties);
165 
166  // get the fparser symbol name for the new material property
167  _symbol_names.push_back(_mat_prop_descriptors.back().getSymbolName());
168  }
169 
170  // get all coupled postprocessors
171  for (const auto & pp : postprocessor_names)
172  {
173  _postprocessor_values.push_back(&this->getPostprocessorValueByName(pp));
174  _symbol_names.push_back(pp);
175  }
176 
177  // get all extra symbols
178  for (const auto symbol : _extra_symbols)
179  switch (symbol)
180  {
181  case ExtraSymbols::x:
182  _symbol_names.push_back("x");
183  break;
184  case ExtraSymbols::y:
185  _symbol_names.push_back("y");
186  break;
187  case ExtraSymbols::z:
188  _symbol_names.push_back("z");
189  break;
190  case ExtraSymbols::t:
191  _symbol_names.push_back("t");
192  break;
193  case ExtraSymbols::dt:
194  _symbol_names.push_back("dt");
195  break;
196  }
197 
198  // build 'variables' argument for fparser
199  std::string variables = Moose::stringify(_symbol_names);
200 
201  // build the base function
202  if (_func_F->Parse(function_expression, variables) >= 0)
203  mooseError("Invalid function\n",
204  function_expression,
205  '\n',
206  variables,
207  "\nin ParsedMaterialHelper.\n",
208  _func_F->ErrorMsg());
209 
210  // create parameter passing buffer
211  _func_params.resize(_nargs + nmat_props + _postprocessor_values.size() + _extra_symbols.size());
212 
213  // perform next steps (either optimize or take derivatives and then optimize)
214 
215  // let rank 0 do the work first to populate caches
216  if (_communicator.rank() != 0)
217  _communicator.barrier();
218 
219  functionsPostParse();
220 
221  // wait for ranks > 0 to catch up
222  if (_communicator.rank() == 0)
223  _communicator.barrier();
224 }
225 
226 template <bool is_ad>
227 void
229 {
230  functionsOptimize(_func_F);
231 
232  // force a value update to get the property at least once and register it for the dependencies
233  for (auto & mpd : _mat_prop_descriptors)
234  mpd.value();
235 }
236 
237 template <bool is_ad>
238 void
240 {
241  computeQpProperties();
242 }
243 
244 template <bool is_ad>
245 void
247 {
248  // fill the parameter vector, apply tolerances
249  for (unsigned int i = 0; i < _nargs; ++i)
250  {
251  if (_tol[i] < 0.0)
252  _func_params[i] = (*_args[i])[_qp];
253  else
254  {
255  auto a = (*_args[i])[_qp];
256  _func_params[i] = a < _tol[i] ? _tol[i] : (a > 1.0 - _tol[i] ? 1.0 - _tol[i] : a);
257  }
258  }
259 
260  // insert material property values
261  for (const auto i : index_range(_mat_prop_descriptors))
262  _func_params[i + _nargs] = _mat_prop_descriptors[i].value(_qp);
263 
264  // insert postprocessor values
265  auto npps = _postprocessor_values.size();
266  for (MooseIndex(_postprocessor_values) i = 0; i < npps; ++i)
267  _func_params[i + _nargs + _mat_prop_descriptors.size()] = *_postprocessor_values[i];
268 
269  // insert extra symbol values
270  for (const auto i : index_range(_extra_symbols))
271  {
272  const auto j = _nargs + _mat_prop_descriptors.size() + _postprocessor_values.size() + i;
273  switch (_extra_symbols[i])
274  {
275  case ExtraSymbols::x:
276  _func_params[j] = _q_point[_qp](0);
277  break;
278  case ExtraSymbols::y:
279  _func_params[j] = _q_point[_qp](1);
280  break;
281  case ExtraSymbols::z:
282  _func_params[j] = _q_point[_qp](2);
283  break;
284  case ExtraSymbols::t:
285  _func_params[j] = _t;
286  break;
287  case ExtraSymbols::dt:
288  _func_params[j] = _dt;
289  break;
290  }
291  }
292  // set function value
293  if (_prop_F)
294  (*_prop_F)[_qp] = evaluate(_func_F, _name);
295 }
296 
297 // explicit instantiation
298 template class ParsedMaterialHelper<false>;
299 template class ParsedMaterialHelper<true>;
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284
void computeQpProperties() override
Users must override this method.
Material base class, central to all Materials that provide a Function as a material property value...
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
static InputParameters validParams()
static InputParameters validParams()
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
T evaluate(Real, const Point &)
The general evaluation method is not defined.
void initQpStatefulProperties() override
Initialize stateful properties at quadrature points.
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:62
Helper class to perform the parsing and optimization of the function expression.
IntRange< T > make_range(T beg, T end)
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...
static InputParameters validParams()
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...
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
auto index_range(const T &sizable)
ParsedMaterialHelper(const InputParameters &parameters, VariableNameMappingMode map_mode)
virtual void functionsPostParse()
void functionParse(const std::string &function_expression)