forked from idaholab/moose
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
4 changed files
with
282 additions
and
4 deletions.
There are no files selected for viewing
64 changes: 64 additions & 0 deletions
64
framework/include/functormaterials/ParsedFunctorMaterial.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* All rights reserved, see COPYRIGHT for full restrictions | ||
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT | ||
//* | ||
//* Licensed under LGPL 2.1, please see LICENSE for details | ||
//* https://www.gnu.org/licenses/lgpl-2.1.html | ||
|
||
#pragma once | ||
|
||
#include "FunctorMaterial.h" | ||
#include "FunctionParserUtils.h" | ||
|
||
/** | ||
* Computes a functor material from a parsed expression of other functors. | ||
*/ | ||
template <bool is_ad> | ||
class ParsedFunctorMaterialTempl : public FunctorMaterial, public FunctionParserUtils<is_ad> | ||
{ | ||
public: | ||
static InputParameters validParams(); | ||
|
||
ParsedFunctorMaterialTempl(const InputParameters & parameters); | ||
|
||
protected: | ||
usingFunctionParserUtilsMembers(is_ad); | ||
|
||
/** | ||
* Builds the parsed function | ||
*/ | ||
void buildParsedFunction(); | ||
|
||
// TODO: This function was duplicated from Function::getTime. Should it go | ||
// into a common place like FunctorInterface? | ||
/** | ||
* @return The time associated with the requested \p state | ||
*/ | ||
Real getTime(const Moose::StateArg & state) const; | ||
|
||
/// Expression to parse for the new functor material | ||
const std::string & _expression; | ||
|
||
/// Functors to use in the parsed expression | ||
const std::vector<std::string> & _functor_names; | ||
|
||
/// Number of functors | ||
const unsigned int _n_functors; | ||
|
||
/// Symbolic name to use for each functor | ||
std::vector<std::string> _functor_symbols; | ||
|
||
/// Name to give the new functor material property | ||
const std::string & _property_name; | ||
|
||
/// The parsed function | ||
SymFunctionPtr _parsed_function; | ||
|
||
/// Functors | ||
std::vector<const Moose::Functor<GenericReal<is_ad>> *> _functors; | ||
}; | ||
|
||
typedef ParsedFunctorMaterialTempl<false> ParsedFunctorMaterial; | ||
typedef ParsedFunctorMaterialTempl<true> ADParsedFunctorMaterial; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* All rights reserved, see COPYRIGHT for full restrictions | ||
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT | ||
//* | ||
//* Licensed under LGPL 2.1, please see LICENSE for details | ||
//* https://www.gnu.org/licenses/lgpl-2.1.html | ||
|
||
#include "ParsedFunctorMaterial.h" | ||
|
||
registerMooseObject("MooseApp", ParsedFunctorMaterial); | ||
registerMooseObject("MooseApp", ADParsedFunctorMaterial); | ||
|
||
template <bool is_ad> | ||
InputParameters | ||
ParsedFunctorMaterialTempl<is_ad>::validParams() | ||
{ | ||
InputParameters params = FunctorMaterial::validParams(); | ||
params += FunctionParserUtils<is_ad>::validParams(); | ||
|
||
params.addClassDescription( | ||
"Computes a functor material from a parsed expression of other functors."); | ||
|
||
params.addRequiredCustomTypeParam<std::string>( | ||
"expression", "FunctionExpression", "Expression to parse for the new functor material"); | ||
params.addParam<std::vector<std::string>>("functor_names", | ||
"Functors to use in the parsed expression"); | ||
params.addParam<std::vector<std::string>>( | ||
"functor_symbols", | ||
"Symbolic name to use for each functor in 'functor_names' in the parsed expression. If not " | ||
"provided, then the actual functor names must be used in the parsed expression."); | ||
params.addRequiredParam<std::string>("property_name", | ||
"Name to give the new functor material property"); | ||
|
||
return params; | ||
} | ||
|
||
template <bool is_ad> | ||
ParsedFunctorMaterialTempl<is_ad>::ParsedFunctorMaterialTempl(const InputParameters & parameters) | ||
: FunctorMaterial(parameters), | ||
FunctionParserUtils<is_ad>(parameters), | ||
_expression(getParam<std::string>("expression")), | ||
_functor_names(getParam<std::vector<std::string>>("functor_names")), | ||
_n_functors(_functor_names.size()), | ||
_functor_symbols(getParam<std::vector<std::string>>("functor_symbols")), | ||
_property_name(getParam<std::string>("property_name")) | ||
{ | ||
// Check/modify 'functor_symbols' | ||
if (_functor_symbols.size() != _n_functors) | ||
{ | ||
if (_functor_symbols.size() == 0) | ||
_functor_symbols = _functor_names; | ||
else | ||
paramError("functor_symbols", | ||
"The number of entries must be equal to either zero or the number of entries in " | ||
"'functor_names'."); | ||
} | ||
|
||
// Get the functors | ||
_functors.resize(_n_functors); | ||
for (const auto i : index_range(_functor_names)) | ||
_functors[i] = &getFunctor<GenericReal<is_ad>>(_functor_names[i]); | ||
|
||
// Build the parsed function | ||
buildParsedFunction(); | ||
|
||
// Add the functor material property | ||
addFunctorProperty<GenericReal<is_ad>>( | ||
_property_name, | ||
[this](const auto & r, const auto & t) -> GenericReal<is_ad> | ||
{ | ||
// Store the functor values | ||
for (const auto i : index_range(_functors)) | ||
_func_params[i] = (*_functors[i])(r, t); | ||
|
||
// Store the space and time values | ||
// TODO: find some way to extract x,y,z from r. getPoint(r) does not exist yet. | ||
// const auto r_point = getPoint(r); | ||
_func_params[_n_functors] = 0; | ||
#if LIBMESH_DIM > 1 | ||
_func_params[_n_functors + 1] = 0; | ||
#endif | ||
#if LIBMESH_DIM > 2 | ||
_func_params[_n_functors + 2] = 0; | ||
#endif | ||
_func_params[_n_functors + LIBMESH_DIM] = getTime(t); | ||
|
||
// Evaluate the parsed function | ||
return evaluate(_parsed_function, _name); | ||
}); | ||
} | ||
|
||
template <bool is_ad> | ||
void | ||
ParsedFunctorMaterialTempl<is_ad>::buildParsedFunction() | ||
{ | ||
_parsed_function = std::make_shared<SymFunction>(); | ||
|
||
setParserFeatureFlags(_parsed_function); | ||
|
||
// Add constants | ||
_parsed_function->AddConstant("pi", std::acos(Real(-1))); | ||
_parsed_function->AddConstant("e", std::exp(Real(1))); | ||
|
||
// Collect the symbols corresponding to the _func_params values | ||
std::vector<std::string> symbols(_functor_symbols); | ||
std::string symbols_str = Moose::stringify(symbols); | ||
symbols_str += ",x"; | ||
#if LIBMESH_DIM > 1 | ||
symbols_str += ",y"; | ||
#endif | ||
#if LIBMESH_DIM > 2 | ||
symbols_str += ",z"; | ||
#endif | ||
symbols_str += ",t"; | ||
|
||
// Parse the expression | ||
if (_parsed_function->Parse(_expression, symbols_str) >= 0) | ||
mooseError("The expression\n'", | ||
_expression, | ||
"'\nwith symbols\n'", | ||
symbols_str, | ||
"'\ncould not be parsed:\n", | ||
_parsed_function->ErrorMsg()); | ||
|
||
// Resize the values vector | ||
_func_params.resize(_n_functors + LIBMESH_DIM + 1); | ||
|
||
// TODO: Do the optimize stuff | ||
} | ||
|
||
// TODO: Make this some common utility function: duplicated from Function::getTime | ||
template <bool is_ad> | ||
Real | ||
ParsedFunctorMaterialTempl<is_ad>::getTime(const Moose::StateArg & state) const | ||
{ | ||
if (state.iteration_type != Moose::SolutionIterationType::Time) | ||
// If we are any iteration type other than time (e.g. nonlinear), then temporally we are still | ||
// in the present time | ||
return miProblem().time(); | ||
|
||
switch (state.state) | ||
{ | ||
case 0: | ||
return miProblem().time(); | ||
|
||
case 1: | ||
return miProblem().timeOld(); | ||
|
||
default: | ||
mooseError("Unhandled state ", state.state, " in ParsedFunctorMaterial::getTime"); | ||
} | ||
} | ||
|
||
template class ParsedFunctorMaterialTempl<false>; | ||
template class ParsedFunctorMaterialTempl<true>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
test/tests/functormaterials/parsed_functor_material/parsed_functor_material.i
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
[Mesh] | ||
type = GeneratedMesh | ||
dim = 3 | ||
nx = 2 | ||
ny = 2 | ||
nz = 2 | ||
xmin = 0.0 | ||
xmax = 4.0 | ||
ymin = 0.0 | ||
ymax = 6.0 | ||
zmin = 0.0 | ||
zmax = 10.0 | ||
[] | ||
|
||
[Functions] | ||
[fn1] | ||
type = ConstantFunction | ||
value = 5 | ||
[] | ||
[fn2] | ||
type = ConstantFunction | ||
value = 3 | ||
[] | ||
[] | ||
|
||
[FunctorMaterials] | ||
[parsed_fmat] | ||
type = ParsedFunctorMaterial | ||
expression = 'A * B^2 + 2 + pi + e + t + x + y + z' | ||
functor_names = 'fn1 fn2' | ||
functor_symbols = 'A B' | ||
property_name = 'prop1' | ||
[] | ||
[] | ||
|
||
[Postprocessors] | ||
# The value should be: | ||
# 5 + 3^2 + 2 + pi + e + 4 + 3 + 4.5 + 7.5 = 40.85987448204884 | ||
[get_prop1] | ||
type = ElementExtremeFunctorValue | ||
functor = prop1 | ||
value_type = max | ||
[] | ||
[] | ||
|
||
[Problem] | ||
solve = false | ||
[] | ||
|
||
[Executioner] | ||
type = Steady | ||
time = 4.0 | ||
[] | ||
|
||
[Outputs] | ||
csv = true | ||
[] |