LCOV - code coverage report
Current view: top level - src/parser - ParameterRegistration.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 223 229 97.4 %
Date: 2026-05-29 20:35:17 Functions: 268 589 45.5 %
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 "ParameterRegistration.h"
      11             : 
      12             : #include "ParameterRegistry.h"
      13             : #include "MooseTypes.h"
      14             : #include "ReporterName.h"
      15             : #include "MooseEnum.h"
      16             : #include "MultiMooseEnum.h"
      17             : #include "ExecFlagEnum.h"
      18             : 
      19             : namespace Moose::ParameterRegistration
      20             : {
      21             : 
      22             : template <>
      23             : void
      24      195492 : setScalarValue(bool & value, const hit::Field & field)
      25             : {
      26             :   // Handles non-quoted values
      27             :   try
      28             :   {
      29      195492 :     value = field.boolVal();
      30             :   }
      31             :   // Handles quoted values
      32         109 :   catch (hit::Error &)
      33             :   {
      34         218 :     const auto strval = field.param<std::string>();
      35         109 :     if (strval == "1")
      36           2 :       value = true;
      37         107 :     else if (strval == "0")
      38           2 :       value = false;
      39         105 :     else if (!hit::toBool(strval, &value))
      40           4 :       throw std::invalid_argument("invalid boolean syntax for parameter: " + field.path() + "='" +
      41           6 :                                   strval + "'");
      42         111 :   }
      43      195490 : }
      44             : 
      45             : /*******************************************************************************/
      46             : /* This contains the initialization time registration of all of the base       */
      47             : /* parameter types that are registered for use in the Builder for MOOSE.       */
      48             : /*******************************************************************************/
      49             : 
      50             : namespace detail
      51             : {
      52             : 
      53             : static Moose::ParameterRegistry & registry = Moose::ParameterRegistry::get();
      54             : 
      55             : /*******************************************************************************/
      56             : /* Derivative string registration                                              */
      57             : /*                                                                             */
      58             : /* Registers for scalars, vectors, double vectors, and triple vectors          */
      59             : /*                                                                             */
      60             : /* See MooseDerivativeStringClass macro usage in MooseTypes.h                  */
      61             : /* Please keep the ordering consistent                                         */
      62             : /*******************************************************************************/
      63             : 
      64             : // Special cases that aren't included: CLIArgString
      65       10015 : registerParameter(FileName);
      66        1199 : registerParameter(FileNameNoExtension);
      67           0 : registerParameter(RelativeFileName);
      68          41 : registerParameter(DataFileName);
      69        8139 : registerParameter(MeshFileName);
      70          45 : registerParameter(MatrixFileName);
      71           0 : registerParameter(OutFileBase);
      72      181395 : registerParameter(NonlinearVariableName);
      73        4221 : registerParameter(LinearVariableName);
      74           0 : registerParameter(SolverVariableName);
      75       44204 : registerParameter(AuxVariableName);
      76       95609 : registerParameter(VariableName);
      77      139125 : registerParameter(BoundaryName);
      78       50854 : registerParameter(SubdomainName);
      79        9875 : registerParameter(PostprocessorName);
      80        1566 : registerParameter(VectorPostprocessorName);
      81        1269 : registerParameter(MeshDivisionName);
      82       45113 : registerParameter(FunctionName);
      83          12 : registerParameter(DistributionName);
      84         287 : registerParameter(SamplerName);
      85        5718 : registerParameter(UserObjectName);
      86         571 : registerParameter(InterpolationMethodName);
      87         506 : registerParameter(IndicatorName);
      88        1947 : registerParameter(MarkerName);
      89       14729 : registerParameter(MultiAppName);
      90        6622 : registerParameter(OutputName);
      91       13088 : registerParameter(MaterialPropertyName);
      92       17523 : registerParameter(MooseFunctorName);
      93         128 : registerParameter(MaterialName);
      94        6530 : registerParameter(TagName);
      95       26997 : registerParameter(MeshGeneratorName);
      96        1057 : registerParameter(ExtraElementIDName);
      97        2768 : registerParameter(ReporterValueName);
      98         252 : registerParameter(ComponentName);
      99          99 : registerParameter(PhysicsName);
     100         977 : registerParameter(PositionsName);
     101          75 : registerParameter(TimesName);
     102          33 : registerParameter(ExecutorName);
     103        1017 : registerParameter(ParsedFunctionExpression);
     104         970 : registerParameter(NonlinearSystemName);
     105        1360 : registerParameter(ConvergenceName);
     106        2042 : registerParameter(LinearSystemName);
     107        2569 : registerParameter(SolverSystemName);
     108             : #ifdef MOOSE_MFEM_ENABLED
     109        3088 : registerParameter(MFEMScalarCoefficientName);
     110         761 : registerParameter(MFEMVectorCoefficientName);
     111           0 : registerParameter(MFEMMatrixCoefficientName);
     112        3211 : registerParameter(MFEMFESpaceName);
     113         808 : registerParameter(MFEMSolverName);
     114             : #endif
     115             : 
     116             : /*******************************************************************************/
     117             : /* Native type registration                                                    */
     118             : /*                                                                             */
     119             : /* Registers for scalars, vectors, double vectors, and triple vectors          */
     120             : /*******************************************************************************/
     121             : 
     122      279467 : registerParameter(double);
     123      703374 : registerParameter(std::string);
     124        1742 : registerParameter(short int);
     125        3902 : registerParameter(int);
     126          80 : registerParameter(long int);
     127       15054 : registerParameter(unsigned short);
     128      168010 : registerParameter(unsigned int);
     129        3524 : registerParameter(unsigned long);
     130           4 : registerParameter(unsigned long long);
     131             : 
     132             : /*******************************************************************************/
     133             : /* Bool registration                                                           */
     134             : /*******************************************************************************/
     135             : 
     136      195492 : registerScalarParameter(bool);
     137        1925 : registerVectorParameter(bool);
     138             : 
     139             : /*******************************************************************************/
     140             : /* Helpers used across types                                                   */
     141             : /*******************************************************************************/
     142             : 
     143             : /// Helper for converting a string to a ReporterName, which requires splitting
     144             : /// the string at the '/' delimiter
     145        3208 : const auto convert_reporter_name = [](const std::string & val,
     146             :                                       const hit::Field & field) -> ReporterName
     147             : {
     148        3208 :   const auto names = MooseUtils::rsplit(val, "/", 2);
     149        3208 :   if (names.size() != 2)
     150           8 :     throw std::invalid_argument("invalid syntax in ReporterName parameter " + field.fullpath() +
     151          12 :                                 ": supplied name '" + val + "' must contain the '/' delimiter");
     152        6408 :   return {names[0], names[1]};
     153        3208 : };
     154             : 
     155             : /*******************************************************************************/
     156             : /* Component-typed scalar registration                                         */
     157             : /*******************************************************************************/
     158             : 
     159             : /// Helper for setting a scalar component value (one with 3 real values)
     160       29321 : const auto set_scalar_component_value = [](auto & value, const hit::Field & field)
     161             : {
     162       58642 :   const auto vec = field.param<std::vector<double>>();
     163       29321 :   if (vec.size() != LIBMESH_DIM)
     164           2 :     throw std::invalid_argument("wrong number of values in " + MooseUtils::prettyCppType(&value) +
     165             :                                 " parameter '" + field.fullpath() + "': was given " +
     166             :                                 std::to_string(vec.size()) + " component(s) but should have " +
     167             :                                 std::to_string(LIBMESH_DIM));
     168             : 
     169      117276 :   for (const auto d : make_range(LIBMESH_DIM))
     170       87957 :     value(d) = Real(vec[d]);
     171       29321 : };
     172             : 
     173             : // Point
     174        8891 : static auto point = registry.add<Point>([](Point & value, const hit::Field & field)
     175        8891 :                                         { set_scalar_component_value(value, field); });
     176             : // RealVectorValue
     177             : static auto realvectorvalue =
     178       20430 :     registry.add<RealVectorValue>([](RealVectorValue & value, const hit::Field & field)
     179       20430 :                                   { set_scalar_component_value(value, field); });
     180             : 
     181             : /*******************************************************************************/
     182             : /* Custom scalar registration                                                  */
     183             : /*******************************************************************************/
     184             : 
     185             : // We only support CLIArgString and std::vector<CLIArgString>, so this isn't
     186             : // added in the main MooseDerivativeString case
     187           0 : registerScalarParameter(CLIArgString);
     188             : // RealEigenVector
     189             : static auto realeigenvector = registry.add<RealEigenVector>(
     190        2030 :     [](RealEigenVector & value, const hit::Field & field)
     191             :     {
     192        4062 :       const auto vec = field.param<std::vector<double>>();
     193        2028 :       value.resize(vec.size());
     194        6506 :       for (const auto i : index_range(vec))
     195        4478 :         value(i) = Real(vec[i]);
     196        2028 :     });
     197             : // RealEigenVector
     198             : static auto realeigenmatrix = registry.add<RealEigenMatrix>(
     199         216 :     [](RealEigenMatrix & value, const hit::Field & field)
     200             :     {
     201         216 :       value.resize(0, 0);
     202         216 :       std::vector<std::string> tokens;
     203         648 :       MooseUtils::tokenize(field.param<std::string>(), tokens, 1, ";");
     204             : 
     205         625 :       for (const auto i : index_range(tokens))
     206             :       {
     207         413 :         const auto token = MooseUtils::trim(tokens[i]);
     208         413 :         std::vector<Real> values;
     209         826 :         if (!MooseUtils::tokenizeAndConvert<Real>(token, values))
     210           4 :           throw std::invalid_argument("invalid syntax for parameter: " + field.fullpath() + "[" +
     211           6 :                                       std::to_string(i) + "]='" + token + "'");
     212         411 :         if (i == 0)
     213         216 :           value.resize(tokens.size(), values.size());
     214         195 :         else if (libMesh::cast_int<std::size_t>(value.cols()) != values.size())
     215           2 :           throw std::invalid_argument("matrix is not square for parameter " + field.fullpath());
     216        1243 :         for (const auto j : index_range(values))
     217         834 :           value(i, j) = values[j];
     218         417 :       }
     219         216 :     });
     220             : // MooseEnum
     221      421883 : static auto mooseenum = registry.add<MooseEnum>([](MooseEnum & value, const hit::Field & field)
     222     1265658 :                                                 { value = field.param<std::string>(); });
     223             : // MultiMooseEnum
     224             : static auto multimooseenum = registry.add<MultiMooseEnum>(
     225       31220 :     [](MultiMooseEnum & value, const hit::Field & field)
     226      124880 :     { value = MooseUtils::stringJoin(field.param<std::vector<std::string>>(), " "); });
     227             : // ExecFlagEnum
     228             : static auto execflagenum = registry.add<ExecFlagEnum>(
     229       55924 :     [](ExecFlagEnum & value, const hit::Field & field)
     230      223696 :     { value = MooseUtils::stringJoin(field.param<std::vector<std::string>>(), " "); });
     231             : // RealTensorValue
     232             : static auto realtensorvalue = registry.add<RealTensorValue>(
     233          42 :     [](RealTensorValue & value, const hit::Field & field)
     234             :     {
     235          86 :       const auto vec = field.param<std::vector<double>>();
     236          40 :       if (vec.size() != LIBMESH_DIM * LIBMESH_DIM)
     237           4 :         throw std::invalid_argument("invalid RealTensorValue parameter '" + field.fullpath() +
     238           8 :                                     "': size is " + std::to_string(vec.size()) + " but should be " +
     239           6 :                                     std::to_string(LIBMESH_DIM * LIBMESH_DIM));
     240             : 
     241         152 :       for (const auto i : make_range(LIBMESH_DIM))
     242         456 :         for (const auto j : make_range(LIBMESH_DIM))
     243         342 :           value(i, j) = Real(vec[i * LIBMESH_DIM + j]);
     244          40 :     });
     245             : // ReporterName
     246             : static auto reportername = registry.add<ReporterName>(
     247        1033 :     [](ReporterName & value, const hit::Field & field)
     248        3101 :     { value = convert_reporter_name(field.param<std::string>(), field); });
     249             : 
     250             : /*******************************************************************************/
     251             : /* Component-typed vector registration                                         */
     252             : /*******************************************************************************/
     253             : 
     254             : /// Helper for setting a vector component value (one with 3 real values)
     255        8428 : const auto set_vector_component_value = [](auto & value, const hit::Field & field)
     256             : {
     257        8428 :   value.clear();
     258       16858 :   const auto vec = field.param<std::vector<double>>();
     259             : 
     260        8426 :   if (vec.size() % LIBMESH_DIM)
     261           5 :     throw std::invalid_argument("wrong number of values in vector parameter '" + field.fullpath() +
     262             :                                 "': size " + std::to_string(vec.size()) + " is not a multiple of " +
     263             :                                 std::to_string(LIBMESH_DIM));
     264             : 
     265        8421 :   const std::size_t size = vec.size() / LIBMESH_DIM;
     266        8421 :   value.resize(size);
     267       31153 :   for (const auto i : make_range(size))
     268       90928 :     for (const auto d : make_range(LIBMESH_DIM))
     269       68196 :       value[i](d) = vec[i * LIBMESH_DIM + d];
     270        8426 : };
     271             : 
     272             : // std::vector<Point>
     273             : static auto vector_point =
     274        8377 :     registry.add<std::vector<Point>>([](std::vector<Point> & value, const hit::Field & field)
     275        8377 :                                      { set_vector_component_value(value, field); });
     276             : // std::vector<RealVectorValue>
     277             : static auto vector_realvectorvalue = registry.add<std::vector<RealVectorValue>>(
     278          51 :     [](std::vector<RealVectorValue> & value, const hit::Field & field)
     279          51 :     { set_vector_component_value(value, field); });
     280             : 
     281             : /*******************************************************************************/
     282             : /* Custom vector registration                                                  */
     283             : /*******************************************************************************/
     284             : 
     285             : // std::vector<MooseEnum>
     286             : static auto vector_mooseenum = registry.add<std::vector<MooseEnum>>(
     287         260 :     [](std::vector<MooseEnum> & value, const hit::Field & field)
     288             :     {
     289             :       mooseAssert(!value.empty(), "Missing a value to initialize on");
     290             : 
     291             :       // With MOOSE enums we need a default object so it should have been
     292             :       // passed in the param pointer. We are only going to use the first
     293             :       // item in the vector (value[0]) and ignore the rest.
     294         520 :       const auto vec = field.param<std::vector<std::string>>();
     295         260 :       value.resize(vec.size(), value[0]);
     296         732 :       for (const auto i : index_range(vec))
     297         475 :         value[i] = vec[i];
     298         260 :     });
     299             : // std::vector<MooseEnum>
     300             : static auto vector_multimooseenum = registry.add<std::vector<MultiMooseEnum>>(
     301          17 :     [](std::vector<MultiMooseEnum> & value, const hit::Field & field)
     302             :     {
     303             :       mooseAssert(!value.empty(), "Missing a value to initialize on");
     304             : 
     305          68 :       const auto tokens = MooseUtils::split(field.param<std::string>(), ";");
     306          78 :       for (const auto i : index_range(tokens))
     307             :       {
     308          64 :         const auto & entry = tokens[i];
     309         128 :         if (MooseUtils::trim(entry) == "")
     310           6 :           throw std::invalid_argument("entry " + std::to_string(i) + " in '" + field.fullpath() +
     311           9 :                                       "' is empty");
     312             :       }
     313          14 :       value.resize(tokens.size(), value[0]);
     314          69 :       for (const auto i : index_range(tokens))
     315             :       {
     316          58 :         std::vector<std::string> strvals;
     317          58 :         MooseUtils::tokenize<std::string>(tokens[i], strvals, 1, " ");
     318          58 :         value[i] = strvals;
     319          58 :       }
     320          17 :     });
     321             : // std::vector<ReporterName>
     322             : static auto vector_reportername = registry.add<std::vector<ReporterName>>(
     323        1136 :     [](std::vector<ReporterName> & value, const hit::Field & field)
     324             :     {
     325        1136 :       value.clear();
     326        2272 :       const auto names = field.param<std::vector<std::string>>();
     327        1136 :       value.resize(names.size());
     328        3309 :       for (const auto i : index_range(names))
     329        2175 :         value[i] = convert_reporter_name(names[i], field);
     330        1136 :     });
     331             : // std::vector<CLIArgString>
     332             : static auto vector_cliargstring = registry.add<std::vector<CLIArgString>>(
     333        1902 :     [](std::vector<CLIArgString> & value, const hit::Field & field)
     334             :     {
     335        1902 :       value.clear();
     336        3804 :       const auto strvals = field.param<std::vector<std::string>>();
     337        1902 :       if (strvals.empty())
     338           3 :         return;
     339             : 
     340             :       // slightly oversized if vectors have been split
     341        1899 :       value.resize(strvals.size());
     342             : 
     343             :       // Re-assemble vector parameters
     344        1899 :       unsigned int i_param = 0;
     345        1899 :       bool vector_param_detected = false;
     346        5106 :       for (const auto i : index_range(strvals))
     347             :       {
     348             :         // Look for a quote, both types
     349             :         const auto double_split =
     350        6414 :             MooseUtils::rsplit(strvals[i], "\"", std::numeric_limits<std::size_t>::max());
     351             :         const auto single_split =
     352        6414 :             MooseUtils::rsplit(strvals[i], "\'", std::numeric_limits<std::size_t>::max());
     353        3207 :         if (double_split.size() + single_split.size() >= 3)
     354             :           // Either entering or exiting a vector parameter (>3 is entering another vector)
     355             :           // Even and >2 number of quotes means both finished and started another vector parameter
     356        1451 :           if ((double_split.size() + single_split.size()) % 2 == 1)
     357         216 :             vector_param_detected = !vector_param_detected;
     358             : 
     359             :         // We're building a vector parameters, just append the text, rebuild the spaces
     360        3207 :         if (vector_param_detected)
     361         360 :           value[i_param] += strvals[i] + ' ';
     362             :         else
     363             :         {
     364        2847 :           value[i_param] += strvals[i];
     365        2847 :           i_param++;
     366             :         }
     367        3207 :       }
     368             :       // Use actual size after re-forming vector parameters
     369        1899 :       value.resize(i_param);
     370        1902 :     });
     371             : 
     372             : /*******************************************************************************/
     373             : /* Component-typed double vector registration                                  */
     374             : /*******************************************************************************/
     375             : 
     376             : /// Helper for setting a double vector component value (one with 3 real values)
     377          96 : const auto set_double_vector_component_value = [](auto & value, const hit::Field & field)
     378             : {
     379         192 :   const auto strval = field.param<std::string>();
     380             : 
     381             :   // Split vector at delim ";" (substrings are not of type T yet)
     382          96 :   std::vector<std::string> tokens;
     383          96 :   MooseUtils::tokenize(strval, tokens, 1, ";");
     384          96 :   value.resize(tokens.size());
     385             : 
     386             :   // Split each token at spaces
     387          96 :   std::vector<std::vector<double>> vecvec(tokens.size());
     388         284 :   for (const auto i : index_range(tokens))
     389         380 :     if (!MooseUtils::tokenizeAndConvert<double>(tokens[i], vecvec[i]))
     390           2 :       throw std::invalid_argument("invalid format for parameter '" + field.fullpath() +
     391             :                                   "' at index " + std::to_string(i));
     392             : 
     393         280 :   for (const auto i : index_range(vecvec))
     394             :   {
     395         188 :     const auto & vec = vecvec[i];
     396         188 :     if (vec.size() % LIBMESH_DIM)
     397           2 :       throw std::invalid_argument(
     398             :           "wrong number of values in double-indexed vector component parameter '" +
     399             :           field.fullpath() + "' at index " + std::to_string(i) + ": subcomponent size " +
     400             :           std::to_string(vec.size()) + " is not a multiple of " + std::to_string(LIBMESH_DIM));
     401             :   }
     402             : 
     403             :   // convert vector<vector<double>> to vector<vector<T>>
     404          92 :   value.resize(vecvec.size());
     405         276 :   for (const auto i : index_range(vecvec))
     406             :   {
     407         184 :     const auto & vec_entry = vecvec[i];
     408         184 :     auto & value_entry = value[i];
     409         184 :     const std::size_t size = vec_entry.size() / LIBMESH_DIM;
     410         184 :     value_entry.resize(size);
     411         636 :     for (const auto j : make_range(size))
     412        1808 :       for (const auto d : make_range(LIBMESH_DIM))
     413        1356 :         value_entry[j](d) = vec_entry[j * LIBMESH_DIM + d];
     414             :   }
     415         104 : };
     416             : 
     417             : // std::vector<std::vector<Point>>
     418             : static auto doublevector_point = registry.add<std::vector<std::vector<Point>>>(
     419          94 :     [](std::vector<std::vector<Point>> & value, const hit::Field & field)
     420          94 :     { set_double_vector_component_value(value, field); });
     421             : // std::vector<std::vector<RealVectorValue>>
     422             : static auto doublevector_realvectorvalue = registry.add<std::vector<std::vector<RealVectorValue>>>(
     423           2 :     [](std::vector<std::vector<RealVectorValue>> & value, const hit::Field & field)
     424           2 :     { set_double_vector_component_value(value, field); });
     425             : 
     426             : /*******************************************************************************/
     427             : /* Map registration                                                            */
     428             : /*******************************************************************************/
     429             : 
     430           0 : registerMapParameter(std::string, unsigned int);
     431          48 : registerMapParameter(std::string, Real);
     432         240 : registerMapParameter(std::string, std::string);
     433          12 : registerMapParameter(unsigned int, unsigned int);
     434          12 : registerMapParameter(unsigned long, unsigned int);
     435          12 : registerMapParameter(unsigned long long, unsigned int);
     436             : 
     437             : } // end of namespace detail
     438             : } // end of namespace Moose::ParameterRegistration

Generated by: LCOV version 1.14