https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ParsedOptimizationFunction.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
11
12// MOOSE includes
13#include "MooseUtils.h"
14
16
19{
22 "Function used for optimization that uses a parsed expression with parameter dependence.");
23
24 params.addRequiredCustomTypeParam<std::string>(
25 "expression", "FunctionExpression", "The user defined function.");
26 params.addRequiredParam<std::vector<std::string>>(
27 "param_symbol_names", "Names of parameters in 'expression' being optimized.");
29 "param_vector_name", "Reporter or VectorPostprocessor vector containing parameter values.");
30 params.addParam<std::vector<std::string>>(
31 "constant_symbol_names",
32 std::vector<std::string>(),
33 "Variables (excluding t,x,y,z) that are bound to the values provided by the corresponding "
34 "items in the symbol_values vector.");
35 params.addParam<std::vector<Real>>(
36 "constant_symbol_values", std::vector<Real>(), "Constant numeric values for vars.");
37 return params;
38}
39
41 : OptimizationFunction(parameters),
43 _expression(getParam<std::string>("expression")),
44 _param_names(getParam<std::vector<std::string>>("param_symbol_names")),
45 _params(getReporterValue<std::vector<Real>>("param_vector_name")),
46 _symbol_names(getParam<std::vector<std::string>>("constant_symbol_names")),
47 _symbol_values(getParam<std::vector<Real>>("constant_symbol_values"))
48{
49 if (_symbol_names.size() != _symbol_values.size())
50 paramError("symbol_names", "Number of vars must match the number of vals for a ", type(), "!");
51
52 // Loop through the variables assigned by the user and give an error if x,y,z,t are used
53 std::string msg = "The variables \"x, y, z, and t\" in the ParsedFunction are pre-declared for "
54 "use and must not be declared.";
55 for (const auto & var : _param_names)
56 if (var.find_first_of("xyzt") != std::string::npos && var.size() == 1)
57 paramError("param_names", msg);
58 for (const auto & var : _symbol_names)
59 if (var.find_first_of("xyzt") != std::string::npos && var.size() == 1)
60 paramError("symbol_names", msg);
61
62 // Create parser
63 _parser = std::make_unique<FunctionParserADBase<Real>>();
64
65 // Add basic and user-defined constants
66 _parser->AddConstant("NaN", std::numeric_limits<Real>::quiet_NaN());
67 _parser->AddConstant("pi", libMesh::pi);
68 _parser->AddConstant("e", std::exp(1.0));
69 for (const auto & i : index_range(_symbol_names))
70 _parser->AddConstant(_symbol_names[i], _symbol_values[i]);
71
72 // Join xyzt and parameters to give to FParser as variables
73 std::vector<std::string> all_vars = {"x", "y", "z", "t"};
74 all_vars.insert(all_vars.end(), _param_names.begin(), _param_names.end());
75
76 // Parse expression and error if something goes wrong
77 if (_parser->Parse(_expression, MooseUtils::join(all_vars, ",")) != -1)
78 paramError("expression", "Unable to parse expression\n", _parser->ErrorMsg());
79 _parser->SetADFlags(FunctionParserADBase<Real>::ADAutoOptimize);
80 _parser->Optimize();
81
82 // Add parsers for each derivative we are taking, including xyzt
83 _derivative_parsers.resize(all_vars.size());
84 for (const auto & i : index_range(all_vars))
85 {
86 _derivative_parsers[i] = std::make_unique<FunctionParserADBase<Real>>(*_parser);
87 if (_derivative_parsers[i]->AutoDiff(all_vars[i]) != -1)
88 paramError("expression",
89 "Unable to take derivative with respect to ",
90 all_vars[i],
91 "\n",
92 _derivative_parsers[i]->ErrorMsg());
93 }
94}
95
96Real
97ParsedOptimizationFunction::value(Real t, const Point & p) const
98{
99 return evaluateExpression(*_parser, t, p);
100}
101
102RealGradient
103ParsedOptimizationFunction::gradient(Real t, const Point & p) const
104{
105 RealGradient result;
106 result(0) = evaluateExpression(*_derivative_parsers[0], t, p, "gradient");
107 result(1) = evaluateExpression(*_derivative_parsers[1], t, p, "gradient");
108 result(2) = evaluateExpression(*_derivative_parsers[2], t, p, "gradient");
109 return result;
110}
111
112Real
114{
115 return evaluateExpression(*_derivative_parsers[3], t, p, "time derivative");
116}
117
118std::vector<Real>
120{
121 std::vector<Real> result(_param_names.size());
122 for (const auto & i : index_range(result))
123 result[i] =
124 evaluateExpression(*_derivative_parsers[4 + i], t, p, _param_names[i] + " derivative");
125 return result;
126}
127
128Real
129ParsedOptimizationFunction::evaluateExpression(FunctionParserADBase<Real> & parser,
130 Real t,
131 const Point & p,
132 std::string name) const
133{
134 if (_params.size() != _param_names.size())
135 paramError("param_vector_name",
136 "Size of vector (",
137 _params.size(),
138 ") does not match number of specified 'param_names' (",
139 _param_names.size(),
140 ").");
141
142 std::vector<Real> parser_var_values(4 + _param_names.size());
143 parser_var_values[0] = p(0);
144 parser_var_values[1] = p(1);
145 parser_var_values[2] = p(2);
146 parser_var_values[3] = t;
147 for (const auto & i : index_range(_param_names))
148 parser_var_values[4 + i] = _params[i];
149
150 Real result = parser.Eval(parser_var_values.data());
151
152 auto err = parser.EvalError();
153 if (err)
154 {
155 std::string msg = "Error evaluating function " + name + "\n";
156 switch (err)
157 {
158 case 1:
159 msg += "Division by zero";
160 break;
161 case 2:
162 msg += "Square Root error (negative value)";
163 break;
164 case 3:
165 msg += "Log error (negative value)";
166 break;
167 case 4:
168 msg += "Trigonometric error (asin or acos of illegal value)";
169 break;
170 case 5:
171 msg += "Maximum recursion level reached";
172 break;
173 }
174
175 paramError("expression", msg);
176 }
177
178 return result;
179}
const Real p
registerMooseObject("OptimizationApp", ParsedOptimizationFunction)
const std::string name
Definition Setup.h:21
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addRequiredCustomTypeParam(const std::string &name, const std::string &custom_type, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
const std::string & type() const
const std::string & name() const
void paramError(const std::string &param, Args... args) const
Base class for functions used in inverse optimization The parameterDerivative function is used in adj...
static InputParameters validParams()
Real evaluateExpression(FunctionParserADBase< Real > &parser, Real t, const Point &p, std::string name="") const
Function to evaluate an inputted parser.
const std::vector< Real > & _symbol_values
Values passed by the user, they may be Reals for Postprocessors.
std::unique_ptr< FunctionParserADBase< Real > > _parser
Pointer to parsed function object.
const std::vector< std::string > & _param_names
Parameters passed to FParser.
virtual RealGradient gradient(Real t, const Point &p) const override
std::vector< std::unique_ptr< FunctionParserADBase< Real > > > _derivative_parsers
Pointers to parsed function objects representing derivative (first four are xyzt)
const std::vector< Real > & _params
Vector containing parameter values.
const std::vector< std::string > & _symbol_names
Variables passed to FParser.
const std::string & _expression
Function expression passed to FParser.
ParsedOptimizationFunction(const InputParameters &parameters)
virtual Real value(Real t, const Point &p) const override
virtual std::vector< Real > parameterGradient(Real t, const Point &p) const override
virtual Real timeDerivative(Real t, const Point &p) const override
static InputParameters validParams()
const Real pi