Line data Source code
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 "ParsedAux.h"
11 :
12 : registerMooseObject("MooseApp", ParsedAux);
13 :
14 : InputParameters
15 17719 : ParsedAux::validParams()
16 : {
17 17719 : InputParameters params = AuxKernel::validParams();
18 17719 : params += FunctionParserUtils<false>::validParams();
19 35438 : params.addClassDescription(
20 : "Sets a field variable value to the evaluation of a parsed expression.");
21 :
22 106314 : params.addRequiredCustomTypeParam<std::string>(
23 : "function", "FunctionExpression", "Parsed function expression to compute");
24 106314 : params.deprecateParam("function", "expression", "02/07/2024");
25 70876 : params.addCoupledVar("args", "Vector of coupled variable names");
26 106314 : params.deprecateCoupledVar("args", "coupled_variables", "02/07/2024");
27 :
28 70876 : params.addParam<std::vector<MaterialPropertyName>>(
29 : "material_properties", {}, "Material properties (Real-valued) in the expression");
30 70876 : params.addParam<std::vector<MaterialPropertyName>>(
31 : "ad_material_properties", {}, "AD material properties (ADReal-valued) in the expression");
32 :
33 53157 : params.addParam<bool>(
34 : "use_xyzt",
35 35438 : false,
36 : "Make coordinate (x,y,z) and time (t) variables available in the function expression.");
37 70876 : params.addParam<std::vector<std::string>>(
38 : "constant_names",
39 : {},
40 : "Vector of constants used in the parsed function (use this for kB etc.)");
41 70876 : params.addParam<std::vector<std::string>>(
42 : "constant_expressions",
43 : {},
44 : "Vector of values for the constants in constant_names (can be an FParser expression)");
45 70876 : params.addParam<std::vector<MooseFunctorName>>(
46 : "functor_names", {}, "Functors to use in the parsed expression");
47 70876 : params.addParam<std::vector<std::string>>(
48 : "functor_symbols",
49 : {},
50 : "Symbolic name to use for each functor in 'functor_names' in the parsed expression. If not "
51 : "provided, then the actual functor names will be used in the parsed expression.");
52 35438 : params.addParam<bool>(
53 : "evaluate_functors_on_qp",
54 35438 : true,
55 : "Whether to evaluate functors using the ElemQpArg/ElemSideQpArg or the ElemArg/FaceArg "
56 : "functor arguments. The behavior of a functor for each argument is implementation-defined by "
57 : "the functor. But for most functors, the former two use the quadrature rule points as "
58 : "evaluation locations, while the latter two use the element centroid/face centroid.");
59 17719 : return params;
60 0 : }
61 :
62 1552 : ParsedAux::ParsedAux(const InputParameters & parameters)
63 : : AuxKernel(parameters),
64 : FunctionParserUtils(parameters),
65 1548 : _function(getParam<std::string>("expression")),
66 3096 : _nargs(coupledComponents("coupled_variables")),
67 3096 : _args(coupledValues("coupled_variables")),
68 3096 : _matprop_names(getParam<std::vector<MaterialPropertyName>>("material_properties")),
69 3096 : _ad_matprop_names(getParam<std::vector<MaterialPropertyName>>("ad_material_properties")),
70 1548 : _n_matprops(_matprop_names.size()),
71 1548 : _n_ad_matprops(_ad_matprop_names.size()),
72 3096 : _use_xyzt(getParam<bool>("use_xyzt")),
73 9288 : _xyzt({"x", "y", "z", "t"}),
74 3096 : _functor_names(getParam<std::vector<MooseFunctorName>>("functor_names")),
75 1548 : _n_functors(_functor_names.size()),
76 3096 : _functor_symbols(getParam<std::vector<std::string>>("functor_symbols")),
77 9292 : _use_qp_functor_arguments(getParam<bool>("evaluate_functors_on_qp"))
78 : {
79 :
80 2253 : for (const auto i : make_range(_nargs))
81 2115 : _coupled_variable_names.push_back(getFieldVar("coupled_variables", i)->name());
82 :
83 : // sanity checks
84 1548 : if (!_functor_symbols.empty() && (_functor_symbols.size() != _n_functors))
85 8 : paramError("functor_symbols", "functor_symbols must be the same length as functor_names.");
86 3686 : if (isNodal() && _use_qp_functor_arguments && isParamSetByUser("evaluate_functors_on_qp"))
87 0 : paramError("evaluate_functors_on_qp", "QPs are not used for computing variable nodal values.");
88 :
89 1544 : validateFunctorSymbols();
90 1536 : validateFunctorNames();
91 : // We need the FaceInfo generated
92 1528 : if (_bnd && !_use_qp_functor_arguments)
93 28 : _subproblem.needFV();
94 :
95 : // build variables argument
96 1528 : std::string variables;
97 :
98 : // coupled field variables
99 2217 : for (const auto i : index_range(_coupled_variable_names))
100 689 : variables += (i == 0 ? "" : ",") + _coupled_variable_names[i];
101 :
102 : // adding functors to the expression
103 1528 : if (_functor_symbols.size())
104 212 : for (const auto & symbol : _functor_symbols)
105 115 : variables += (variables.empty() ? "" : ",") + symbol;
106 : else
107 1487 : for (const auto & name : _functor_names)
108 56 : variables += (variables.empty() ? "" : ",") + name;
109 :
110 : // material properties
111 1556 : for (const auto & matprop : _matprop_names)
112 28 : variables += (variables.empty() ? "" : ",") + matprop;
113 1556 : for (const auto & matprop : _ad_matprop_names)
114 28 : variables += (variables.empty() ? "" : ",") + matprop;
115 1528 : if (isNodal() && (_matprop_names.size() || _ad_matprop_names.size()))
116 0 : mooseError("Material properties cannot be retrieved in a nodal auxkernel. Use a different "
117 : "auxiliary variable family.");
118 :
119 : // positions and time
120 1528 : if (_use_xyzt)
121 4480 : for (auto & v : _xyzt)
122 3584 : variables += (variables.empty() ? "" : ",") + v;
123 :
124 : // Create parsed function
125 1528 : _func_F = std::make_shared<SymFunction>();
126 7632 : parsedFunctionSetup(_func_F,
127 1528 : _function,
128 : variables,
129 : getParam<std::vector<std::string>>("constant_names"),
130 : getParam<std::vector<std::string>>("constant_expressions"),
131 : comm());
132 :
133 : // reserve storage for parameter passing buffer
134 1524 : _func_params.resize(_nargs + _n_functors + _n_matprops + _n_ad_matprops + (_use_xyzt ? 4 : 0));
135 :
136 : // keep pointers to the material properties
137 1552 : for (const auto & name : _matprop_names)
138 28 : _matprops.push_back(&getMaterialProperty<Real>(name));
139 1552 : for (const auto & name : _ad_matprop_names)
140 28 : _ad_matprops.push_back(&getADMaterialProperty<Real>(name));
141 :
142 : // keep pointers to the functors
143 1687 : for (const auto & name : _functor_names)
144 163 : _functors.push_back(&getFunctor<Real>(name));
145 6168 : }
146 :
147 : Real
148 4801866 : ParsedAux::computeValue()
149 : {
150 : // Variables
151 5489237 : for (const auto j : make_range(_nargs))
152 687371 : _func_params[j] = (*_args[j])[_qp];
153 :
154 : // Functors
155 4801866 : const auto & state = determineState();
156 4801866 : if (isNodal())
157 : {
158 1558984 : const Moose::NodeArg node_arg = {_current_node,
159 1558984 : &Moose::NodeArg::undefined_subdomain_connection};
160 1645251 : for (const auto i : index_range(_functors))
161 86267 : _func_params[_nargs + i] = (*_functors[i])(node_arg, state);
162 : }
163 3242882 : else if (_bnd && _use_qp_functor_arguments)
164 : {
165 : const Moose::ElemSideQpArg side_qp_arg = {
166 5208 : _current_elem, _current_side, _qp, _qrule, _q_point[_qp]};
167 10416 : for (const auto i : index_range(_functors))
168 5208 : _func_params[_nargs + i] = (*_functors[i])(side_qp_arg, state);
169 5208 : }
170 3237674 : else if (_bnd)
171 : {
172 5208 : const Moose::FaceArg face_arg = {_mesh.faceInfo(_current_elem, _current_side),
173 : Moose::FV::LimiterType::CentralDifference,
174 : /*elem_is_upwind*/ true,
175 : /*correct skewness*/ true,
176 : /*face_side*/ nullptr,
177 5208 : /*state_limiter*/ nullptr};
178 10416 : for (const auto i : index_range(_functors))
179 5208 : _func_params[_nargs + i] = (*_functors[i])(face_arg, state);
180 : }
181 3232466 : else if (_use_qp_functor_arguments)
182 : {
183 3232466 : const Moose::ElemQpArg qp_arg = {_current_elem, _qp, _qrule, _q_point[_qp]};
184 3232466 : for (const auto i : index_range(_functors))
185 0 : _func_params[_nargs + i] = (*_functors[i])(qp_arg, state);
186 : }
187 : else
188 : {
189 0 : const Moose::ElemArg elem_arg = {_current_elem, /*correct skewness*/ true};
190 0 : for (const auto i : index_range(_functors))
191 0 : _func_params[_nargs + i] = (*_functors[i])(elem_arg, state);
192 : }
193 :
194 : // Material properties
195 5018666 : for (const auto j : make_range(_n_matprops))
196 216800 : _func_params[_nargs + _n_functors + j] = (*_matprops[j])[_qp];
197 5018666 : for (const auto j : make_range(_n_ad_matprops))
198 216800 : _func_params[_nargs + _n_functors + _n_matprops + j] = (*_ad_matprops[j])[_qp].value();
199 :
200 : // Positions and time
201 4801866 : if (_use_xyzt)
202 : {
203 15950048 : for (const auto j : make_range(Moose::dim))
204 11962536 : _func_params[_nargs + _n_functors + _n_matprops + _n_ad_matprops + j] =
205 11962536 : isNodal() ? (*_current_node)(j) : _q_point[_qp](j);
206 3987512 : _func_params[_nargs + _n_functors + _n_matprops + _n_ad_matprops + 3] = _t;
207 : }
208 :
209 14405598 : return evaluate(_func_F);
210 : }
211 :
212 : void
213 1544 : ParsedAux::validateFunctorSymbols()
214 : {
215 1544 : validateGenericVectorNames(_functor_symbols, "functor_symbols");
216 1536 : }
217 :
218 : void
219 1536 : ParsedAux::validateFunctorNames()
220 : {
221 1536 : validateGenericVectorNames(_functor_names, "functor_names");
222 1528 : }
|