https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ParsedODEKernel.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 "ParsedODEKernel.h"
11
12// MOOSE includes
13#include "MooseVariableScalar.h"
14#include "SystemBase.h"
15#include "MooseApp.h"
16
17#include "libmesh/fparser_ad.hh"
18
20
23{
26 params.addClassDescription("Parsed expression ODE kernel.");
27
28 params.addRequiredCustomTypeParam<std::string>(
29 "expression", "FunctionExpression", "function expression");
30 params.addCoupledVar("coupled_variables", "Scalar variables coupled in the parsed expression.");
31 params.addParam<std::vector<std::string>>(
32 "constant_names", {}, "Vector of constants used in the parsed expression");
33 params.addParam<std::vector<std::string>>(
34 "constant_expressions",
35 {},
36 "Vector of values for the constants in constant_names (can be an FParser expression)");
37 params.addParam<std::vector<PostprocessorName>>(
38 "postprocessors", {}, "Vector of postprocessor names used in the function expression");
39
40 return params;
41}
42
44 : ODEKernel(parameters),
45 FunctionParserUtils(parameters),
46 _function(getParam<std::string>("expression")),
47 _nargs(isCoupledScalar("coupled_variables") ? coupledScalarComponents("coupled_variables") : 0),
48 _args(_nargs),
49 _arg_names(_nargs),
50 _func_dFdarg(_nargs),
51 _number_of_nl_variables(_sys.nVariables()),
52 _arg_index(_number_of_nl_variables, -1)
53{
54 // build variables argument (start with variable the kernel is operating on)
55 std::string variables = _var.name();
56
57 // add additional coupled variables
58 for (unsigned int i = 0; i < _nargs; ++i)
59 {
60 _arg_names[i] = getScalarVar("coupled_variables", i)->name();
61 variables += "," + _arg_names[i];
62 _args[i] = &coupledScalarValue("coupled_variables", i);
63
64 // populate number -> arg index lookup table skipping aux variables
65 unsigned int number = coupledScalar("coupled_variables", i);
66 if (number < _number_of_nl_variables)
67 _arg_index[number] = i;
68 }
69
70 // add postprocessors
71 auto pp_names = getParam<std::vector<PostprocessorName>>("postprocessors");
72 _pp.resize(pp_names.size());
73 for (unsigned int i = 0; i < pp_names.size(); ++i)
74 {
75 variables += "," + pp_names[i];
76 _pp[i] = &getPostprocessorValueByName(pp_names[i]);
77 }
78
79 // Note: we do not use the FunctionParsedUtils::parsedFunctionSetup because we are building
80 // multiple expressions, and we can share the MPI barriers by keeping the code here.
81 // base function object
82 _func_F = std::make_shared<SymFunction>();
83
84 // set FParser interneal feature flags
86
87 // add the constant expressions
89 getParam<std::vector<std::string>>("constant_names"),
90 getParam<std::vector<std::string>>("constant_expressions"));
91
92 // parse function
93 if (_func_F->Parse(_function, variables) >= 0)
94 mooseError("Invalid function\n",
96 "\nin ParsedODEKernel ",
97 name(),
98 ".\n",
99 _func_F->ErrorMsg());
100
101 // on-diagonal derivative
102 _func_dFdu = std::make_shared<SymFunction>(*_func_F);
103
104 // let rank 0 do the work first (diff and JIT) to populate caches
105 if (_communicator.rank() != 0)
107
108 if (_func_dFdu->AutoDiff(_var.name()) != -1)
109 mooseError("Failed to take first derivative w.r.t. ", _var.name());
110
111 // off-diagonal derivatives
112 for (unsigned int i = 0; i < _nargs; ++i)
113 {
114 _func_dFdarg[i] = std::make_shared<SymFunction>(*_func_F);
115
116 if (_func_dFdarg[i]->AutoDiff(_arg_names[i]) != -1)
117 mooseError("Failed to take first derivative w.r.t. ", _arg_names[i]);
118 }
119
120 // optimize
122 {
123 _func_F->Optimize();
124 _func_dFdu->Optimize();
125 for (unsigned int i = 0; i < _nargs; ++i)
126 _func_dFdarg[i]->Optimize();
127 }
128
129 // just-in-time compile
130 if (_enable_jit)
131 {
132 _func_F->JITCompile();
133 _func_dFdu->JITCompile();
134 for (unsigned int i = 0; i < _nargs; ++i)
135 _func_dFdarg[i]->JITCompile();
136 }
137
138 // wait for ranks > 0 to catch up
139 if (_communicator.rank() == 0)
141
142 // reserve storage for parameter passing buffer
143 _func_params.resize(1 + _nargs + _pp.size());
144}
145
146void
148{
149 _func_params[0] = _u[_i];
150
151 for (unsigned int j = 0; j < _nargs; ++j)
152 _func_params[j + 1] = (*_args[j])[_i];
153 for (unsigned int j = 0; j < _pp.size(); ++j)
154 _func_params[j + 1 + _nargs] = *_pp[j];
155}
156
157Real
163
164Real
170
171Real
173{
174 int i = _arg_index[jvar];
175 if (i < 0)
176 return 0.0;
177
178 updateParams();
179 return evaluate(_func_dFdarg[i]);
180}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
registerMooseObject("MooseApp", ParsedODEKernel)
std::vector< GenericReal< is_ad > > _func_params
Array to stage the parameters passed to the functions when calling Eval.
void addFParserConstants(SymFunctionPtr &parser, const std::vector< std::string > &constant_names, const std::vector< std::string > &constant_expressions) const
add constants (which can be complex expressions) to the parser object
void setParserFeatureFlags(SymFunctionPtr &) const
apply input parameters to internal feature flags of the parser object
GenericReal< is_ad > evaluate(SymFunctionPtr &, const std::string &object_name="")
Evaluate FParser object and check EvalError.
static InputParameters validParams()
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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 addRequiredCustomTypeParam(const std::string &name, const std::string &custom_type, const std::string &doc_string)
These methods add an option parameter and with a customer type to the InputParameters object.
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.
void addCoupledVar(const std::string &name, const std::string &doc_string)
This method adds a coupled variable name pair.
const std::string & name() const
Get the name of the class.
Definition MooseBase.h:103
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition MooseBase.h:406
static InputParameters validParams()
Definition ODEKernel.C:18
Parsed ODE function kernel.
virtual Real computeQpResidual() override
virtual Real computeQpOffDiagJacobianScalar(unsigned int jvar) override
std::string _function
function expression
const unsigned int _number_of_nl_variables
number of non-linear variables in the problem
SymFunctionPtr _func_dFdu
std::vector< unsigned int > _arg_index
Vector to look up the internal coupled variable index into arg* through the libMesh variable number.
SymFunctionPtr _func_F
function parser object for the residual and on-diagonal Jacobian
std::vector< std::string > _arg_names
virtual Real computeQpJacobian() override
unsigned int _nargs
coupled variables
std::vector< SymFunctionPtr > _func_dFdarg
function parser objects for the Jacobian
static InputParameters validParams()
ParsedODEKernel(const InputParameters &parameters)
std::vector< const VariableValue * > _args
std::vector< const PostprocessorValue * > _pp
coupled postprocessors
virtual const PostprocessorValue & getPostprocessorValueByName(const PostprocessorName &name) const
Retrieve the value of the Postprocessor.
const VariableValue & coupledScalarValue(const std::string &var_name, unsigned int comp=0) const
Returns value of a scalar coupled variable.
unsigned int coupledScalar(const std::string &var_name, unsigned int comp=0) const
Returns the index for a scalar coupled variable by name.
const MooseVariableScalar * getScalarVar(const std::string &var_name, unsigned int comp) const
Extract pointer to a scalar coupled variable.
MooseVariableScalar & _var
Scalar variable.
const VariableValue & _u
The current solution (old solution if explicit)
processor_id_type rank() const
const Parallel::Communicator & _communicator