www.mooseframework.org
FunctionParserUtils.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 "FunctionParserUtils.h"
11 
12 // MOOSE includes
13 #include "InputParameters.h"
14 
15 template <>
18 {
20 
21  params.addParam<bool>(
22  "enable_jit",
23 #ifdef LIBMESH_HAVE_FPARSER_JIT
24  true,
25 #else
26  false,
27 #endif
28  "Enable just-in-time compilation of function expressions for faster evaluation");
29  params.addParamNamesToGroup("enable_jit", "Advanced");
30  params.addParam<bool>(
31  "enable_ad_cache", true, "Enable cacheing of function derivatives for faster startup time");
32  params.addParam<bool>(
33  "enable_auto_optimize", true, "Enable automatic immediate optimization of derivatives");
34  params.addParam<bool>(
35  "disable_fpoptimizer", false, "Disable the function parser algebraic optimizer");
36  params.addParam<bool>(
37  "fail_on_evalerror",
38  false,
39  "Fail fatally if a function evaluation returns an error code (otherwise just pass on NaN)");
40  params.addParamNamesToGroup("enable_ad_cache", "Advanced");
41  params.addParamNamesToGroup("enable_auto_optimize", "Advanced");
42  params.addParamNamesToGroup("disable_fpoptimizer", "Advanced");
43  params.addParamNamesToGroup("fail_on_evalerror", "Advanced");
44 
45  return params;
46 }
47 
48 const char * FunctionParserUtils::_eval_error_msg[] = {
49  "Unknown",
50  "Division by zero",
51  "Square root of a negative value",
52  "Logarithm of negative value",
53  "Trigonometric error (asin or acos of illegal value)",
54  "Maximum recursion level reached"};
55 
57  : _enable_jit(parameters.isParamValid("enable_jit") && parameters.get<bool>("enable_jit")),
58  _enable_ad_cache(parameters.get<bool>("enable_ad_cache")),
59  _disable_fpoptimizer(parameters.get<bool>("disable_fpoptimizer")),
60  _enable_auto_optimize(parameters.get<bool>("enable_auto_optimize") && !_disable_fpoptimizer),
61  _fail_on_evalerror(parameters.get<bool>("fail_on_evalerror")),
62  _nan(std::numeric_limits<Real>::quiet_NaN())
63 {
64 #ifndef LIBMESH_HAVE_FPARSER_JIT
65  if (_enable_jit)
66  {
67  mooseWarning("Tried to enable FParser JIT but libmesh does not have it compiled in.");
68  _enable_jit = false;
69  }
70 #endif
71 }
72 
73 void
75 {
76  parser->SetADFlags(ADFunction::ADCacheDerivatives, _enable_ad_cache);
77  parser->SetADFlags(ADFunction::ADAutoOptimize, _enable_auto_optimize);
78 }
79 
80 Real
82 {
83  // null pointer is a shortcut for vanishing derivatives, see functionsOptimize()
84  if (parser == NULL)
85  return 0.0;
86 
87  // evaluate expression
88  Real result = parser->Eval(_func_params.data());
89 
90  // fetch fparser evaluation error
91  int error_code = parser->EvalError();
92 
93  // no error
94  if (error_code == 0)
95  return result;
96 
97  // hard fail or return not a number
99  mooseError("DerivativeParsedMaterial function evaluation encountered an error: ",
100  _eval_error_msg[(error_code < 0 || error_code > 5) ? 0 : error_code]);
101 
102  return _nan;
103 }
104 
105 void
107  const std::vector<std::string> & constant_names,
108  const std::vector<std::string> & constant_expressions)
109 {
110  // check constant vectors
111  unsigned int nconst = constant_expressions.size();
112  if (nconst != constant_names.size())
113  mooseError("The parameter vectors constant_names and constant_values must have equal length.");
114 
115  // previously evaluated constant_expressions may be used in following constant_expressions
116  std::vector<Real> constant_values(nconst);
117 
118  for (unsigned int i = 0; i < nconst; ++i)
119  {
120  ADFunctionPtr expression = ADFunctionPtr(new ADFunction());
121 
122  // set FParser internal feature flags
123  setParserFeatureFlags(expression);
124 
125  // add previously evaluated constants
126  for (unsigned int j = 0; j < i; ++j)
127  if (!expression->AddConstant(constant_names[j], constant_values[j]))
128  mooseError("Invalid constant name in ParsedMaterialHelper");
129 
130  // build the temporary comnstant expression function
131  if (expression->Parse(constant_expressions[i], "") >= 0)
132  mooseError("Invalid constant expression\n",
133  constant_expressions[i],
134  "\n in parsed function object.\n",
135  expression->ErrorMsg());
136 
137  constant_values[i] = expression->Eval(NULL);
138 
139  if (!parser->AddConstant(constant_names[i], constant_values[i]))
140  mooseError("Invalid constant name in parsed function object");
141  }
142 }
static const char * _eval_error_msg[]
table of FParser eval error codes
Real evaluate(ADFunctionPtr &)
Evaluate FParser object and check EvalError.
void addFParserConstants(ADFunctionPtr &parser, const std::vector< std::string > &constant_names, const std::vector< std::string > &constant_expressions)
add constants (which can be complex expressions) to the parser object
FunctionParserADBase< Real > ADFunction
Shorthand for an autodiff function parser object.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:207
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
Definition: MooseError.h:219
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
std::shared_ptr< ADFunction > ADFunctionPtr
Shorthand for an smart pointer to an autodiff function parser object.
FunctionParserUtils(const InputParameters &parameters)
InputParameters emptyInputParameters()
const Real _nan
appropriate not a number value to return
InputParameters validParams< FunctionParserUtils >()
std::vector< Real > _func_params
Array to stage the parameters passed to the functions when calling Eval.
void setParserFeatureFlags(ADFunctionPtr &)
apply input paramters to internal feature flags of the parser object
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 addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...