LCOV - code coverage report
Current view: top level - src/auxkernels - ParsedAux.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 99787a Lines: 107 114 93.9 %
Date: 2025-10-14 20:01:24 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          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 : }

Generated by: LCOV version 1.14