LCOV - code coverage report
Current view: top level - src/parser - ParameterRegistration.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: a4781e Lines: 219 226 96.9 %
Date: 2025-09-23 09:14:59 Functions: 348 565 61.6 %
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      201814 : setScalarValue(bool & value, const hit::Field & field)
      25             : {
      26             :   // Handles non-quoted values
      27             :   try
      28             :   {
      29      201814 :     value = field.boolVal();
      30             :   }
      31             :   // Handles quoted values
      32          96 :   catch (hit::Error &)
      33             :   {
      34         192 :     const auto strval = field.param<std::string>();
      35          96 :     if (strval == "1")
      36           1 :       value = true;
      37          95 :     else if (strval == "0")
      38           1 :       value = false;
      39          94 :     else if (!hit::toBool(strval, &value))
      40           2 :       throw std::invalid_argument("invalid boolean syntax for parameter: " + field.path() + "='" +
      41           3 :                                   strval + "'");
      42          97 :   }
      43      201813 : }
      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        9764 : registerParameter(FileName);
      66        1280 : registerParameter(FileNameNoExtension);
      67           0 : registerParameter(RelativeFileName);
      68          51 : registerParameter(DataFileName);
      69        6777 : registerParameter(MeshFileName);
      70          40 : registerParameter(MatrixFileName);
      71           0 : registerParameter(OutFileBase);
      72      199475 : registerParameter(NonlinearVariableName);
      73        5677 : registerParameter(LinearVariableName);
      74           0 : registerParameter(SolverVariableName);
      75       46052 : registerParameter(AuxVariableName);
      76       93900 : registerParameter(VariableName);
      77      150538 : registerParameter(BoundaryName);
      78       54803 : registerParameter(SubdomainName);
      79       10687 : registerParameter(PostprocessorName);
      80        1564 : registerParameter(VectorPostprocessorName);
      81        1349 : registerParameter(MeshDivisionName);
      82       49441 : registerParameter(FunctionName);
      83          13 : registerParameter(DistributionName);
      84         367 : registerParameter(SamplerName);
      85        7187 : registerParameter(UserObjectName);
      86         531 : registerParameter(IndicatorName);
      87        2109 : registerParameter(MarkerName);
      88       14095 : registerParameter(MultiAppName);
      89        8803 : registerParameter(OutputName);
      90       14357 : registerParameter(MaterialPropertyName);
      91       21803 : registerParameter(MooseFunctorName);
      92         141 : registerParameter(MaterialName);
      93        6647 : registerParameter(TagName);
      94       27878 : registerParameter(MeshGeneratorName);
      95         904 : registerParameter(ExtraElementIDName);
      96        3025 : registerParameter(ReporterValueName);
      97           0 : registerParameter(ComponentName);
      98         114 : registerParameter(PhysicsName);
      99         976 : registerParameter(PositionsName);
     100          56 : registerParameter(TimesName);
     101          40 : registerParameter(ExecutorName);
     102         929 : registerParameter(ParsedFunctionExpression);
     103        1064 : registerParameter(NonlinearSystemName);
     104        1671 : registerParameter(ConvergenceName);
     105        2654 : registerParameter(LinearSystemName);
     106        3228 : registerParameter(SolverSystemName);
     107             : #ifdef MOOSE_MFEM_ENABLED
     108         707 : registerParameter(MFEMScalarCoefficientName);
     109         159 : registerParameter(MFEMVectorCoefficientName);
     110           0 : registerParameter(MFEMMatrixCoefficientName);
     111             : #endif
     112             : 
     113             : /*******************************************************************************/
     114             : /* Native type registration                                                    */
     115             : /*                                                                             */
     116             : /* Registers for scalars, vectors, double vectors, and triple vectors          */
     117             : /*******************************************************************************/
     118             : 
     119      294718 : registerParameter(double);
     120      736285 : registerParameter(std::string);
     121        1952 : registerParameter(short int);
     122        3872 : registerParameter(int);
     123          92 : registerParameter(long int);
     124       15663 : registerParameter(unsigned short);
     125      179207 : registerParameter(unsigned int);
     126        3816 : registerParameter(unsigned long);
     127           2 : registerParameter(unsigned long long);
     128             : 
     129             : /*******************************************************************************/
     130             : /* Bool registration                                                           */
     131             : /*******************************************************************************/
     132             : 
     133      201814 : registerScalarParameter(bool);
     134        1572 : registerVectorParameter(bool);
     135             : 
     136             : /*******************************************************************************/
     137             : /* Helpers used across types                                                   */
     138             : /*******************************************************************************/
     139             : 
     140             : /// Helper for converting a string to a ReporterName, which requires splitting
     141             : /// the string at the '/' delimiter
     142        3087 : const auto convert_reporter_name = [](const std::string & val,
     143             :                                       const hit::Field & field) -> ReporterName
     144             : {
     145        3087 :   const auto names = MooseUtils::rsplit(val, "/", 2);
     146        3087 :   if (names.size() != 2)
     147           4 :     throw std::invalid_argument("invalid syntax in ReporterName parameter " + field.fullpath() +
     148           6 :                                 ": supplied name '" + val + "' must contain the '/' delimiter");
     149        6170 :   return {names[0], names[1]};
     150        3087 : };
     151             : 
     152             : /*******************************************************************************/
     153             : /* Component-typed scalar registration                                         */
     154             : /*******************************************************************************/
     155             : 
     156             : /// Helper for setting a scalar component value (one with 3 real values)
     157       29361 : const auto set_scalar_component_value = [](auto & value, const hit::Field & field)
     158             : {
     159       58722 :   const auto vec = field.param<std::vector<double>>();
     160       29361 :   if (vec.size() != LIBMESH_DIM)
     161           1 :     throw std::invalid_argument("wrong number of values in " + MooseUtils::prettyCppType(&value) +
     162             :                                 " parameter '" + field.fullpath() + "': was given " +
     163             :                                 std::to_string(vec.size()) + " component(s) but should have " +
     164             :                                 std::to_string(LIBMESH_DIM));
     165             : 
     166      117440 :   for (const auto d : make_range(LIBMESH_DIM))
     167       88080 :     value(d) = Real(vec[d]);
     168       29361 : };
     169             : 
     170             : // Point
     171        8058 : static auto point = registry.add<Point>([](Point & value, const hit::Field & field)
     172        8058 :                                         { set_scalar_component_value(value, field); });
     173             : // RealVectorValue
     174             : static auto realvectorvalue =
     175       21303 :     registry.add<RealVectorValue>([](RealVectorValue & value, const hit::Field & field)
     176       21303 :                                   { set_scalar_component_value(value, field); });
     177             : 
     178             : /*******************************************************************************/
     179             : /* Custom scalar registration                                                  */
     180             : /*******************************************************************************/
     181             : 
     182             : // We only support CLIArgString and std::vector<CLIArgString>, so this isn't
     183             : // added in the main MooseDerivativeString case
     184           0 : registerScalarParameter(CLIArgString);
     185             : // RealEigenVector
     186             : static auto realeigenvector = registry.add<RealEigenVector>(
     187        1984 :     [](RealEigenVector & value, const hit::Field & field)
     188             :     {
     189        3969 :       const auto vec = field.param<std::vector<double>>();
     190        1983 :       value.resize(vec.size());
     191        6417 :       for (const auto i : index_range(vec))
     192        4434 :         value(i) = Real(vec[i]);
     193        1983 :     });
     194             : // RealEigenVector
     195             : static auto realeigenmatrix = registry.add<RealEigenMatrix>(
     196         189 :     [](RealEigenMatrix & value, const hit::Field & field)
     197             :     {
     198         189 :       value.resize(0, 0);
     199         189 :       std::vector<std::string> tokens;
     200         567 :       MooseUtils::tokenize(field.param<std::string>(), tokens, 1, ";");
     201             : 
     202         554 :       for (const auto i : index_range(tokens))
     203             :       {
     204         367 :         const auto token = MooseUtils::trim(tokens[i]);
     205         367 :         std::vector<Real> values;
     206         734 :         if (!MooseUtils::tokenizeAndConvert<Real>(token, values))
     207           2 :           throw std::invalid_argument("invalid syntax for parameter: " + field.fullpath() + "[" +
     208           3 :                                       std::to_string(i) + "]='" + token + "'");
     209         366 :         if (i == 0)
     210         189 :           value.resize(tokens.size(), values.size());
     211         177 :         else if (libMesh::cast_int<std::size_t>(value.cols()) != values.size())
     212           1 :           throw std::invalid_argument("matrix is not square for parameter " + field.fullpath());
     213        1112 :         for (const auto j : index_range(values))
     214         747 :           value(i, j) = values[j];
     215         369 :       }
     216         189 :     });
     217             : // MooseEnum
     218      442390 : static auto mooseenum = registry.add<MooseEnum>([](MooseEnum & value, const hit::Field & field)
     219     1327182 :                                                 { value = field.param<std::string>(); });
     220             : // MultiMooseEnum
     221             : static auto multimooseenum = registry.add<MultiMooseEnum>(
     222       34625 :     [](MultiMooseEnum & value, const hit::Field & field)
     223      138500 :     { value = MooseUtils::stringJoin(field.param<std::vector<std::string>>(), " "); });
     224             : // ExecFlagEnum
     225             : static auto execflagenum = registry.add<ExecFlagEnum>(
     226       59918 :     [](ExecFlagEnum & value, const hit::Field & field)
     227      239672 :     { value = MooseUtils::stringJoin(field.param<std::vector<std::string>>(), " "); });
     228             : // RealTensorValue
     229             : static auto realtensorvalue = registry.add<RealTensorValue>(
     230          42 :     [](RealTensorValue & value, const hit::Field & field)
     231             :     {
     232          85 :       const auto vec = field.param<std::vector<double>>();
     233          41 :       if (vec.size() != LIBMESH_DIM * LIBMESH_DIM)
     234           2 :         throw std::invalid_argument("invalid RealTensorValue parameter '" + field.fullpath() +
     235           4 :                                     "': size is " + std::to_string(vec.size()) + " but should be " +
     236           3 :                                     std::to_string(LIBMESH_DIM * LIBMESH_DIM));
     237             : 
     238         160 :       for (const auto i : make_range(LIBMESH_DIM))
     239         480 :         for (const auto j : make_range(LIBMESH_DIM))
     240         360 :           value(i, j) = Real(vec[i * LIBMESH_DIM + j]);
     241          41 :     });
     242             : // ReporterName
     243             : static auto reportername = registry.add<ReporterName>(
     244         911 :     [](ReporterName & value, const hit::Field & field)
     245        2734 :     { value = convert_reporter_name(field.param<std::string>(), field); });
     246             : 
     247             : /*******************************************************************************/
     248             : /* Component-typed vector registration                                         */
     249             : /*******************************************************************************/
     250             : 
     251             : /// Helper for setting a vector component value (one with 3 real values)
     252        8779 : const auto set_vector_component_value = [](auto & value, const hit::Field & field)
     253             : {
     254        8779 :   value.clear();
     255       17559 :   const auto vec = field.param<std::vector<double>>();
     256             : 
     257        8778 :   if (vec.size() % LIBMESH_DIM)
     258           5 :     throw std::invalid_argument("wrong number of values in vector parameter '" + field.fullpath() +
     259             :                                 "': size " + std::to_string(vec.size()) + " is not a multiple of " +
     260             :                                 std::to_string(LIBMESH_DIM));
     261             : 
     262        8773 :   const std::size_t size = vec.size() / LIBMESH_DIM;
     263        8773 :   value.resize(size);
     264       30681 :   for (const auto i : make_range(size))
     265       87632 :     for (const auto d : make_range(LIBMESH_DIM))
     266       65724 :       value[i](d) = vec[i * LIBMESH_DIM + d];
     267        8778 : };
     268             : 
     269             : // std::vector<Point>
     270             : static auto vector_point =
     271        8719 :     registry.add<std::vector<Point>>([](std::vector<Point> & value, const hit::Field & field)
     272        8719 :                                      { set_vector_component_value(value, field); });
     273             : // std::vector<RealVectorValue>
     274             : static auto vector_realvectorvalue = registry.add<std::vector<RealVectorValue>>(
     275          60 :     [](std::vector<RealVectorValue> & value, const hit::Field & field)
     276          60 :     { set_vector_component_value(value, field); });
     277             : 
     278             : /*******************************************************************************/
     279             : /* Custom vector registration                                                  */
     280             : /*******************************************************************************/
     281             : 
     282             : // std::vector<MooseEnum>
     283             : static auto vector_mooseenum = registry.add<std::vector<MooseEnum>>(
     284         268 :     [](std::vector<MooseEnum> & value, const hit::Field & field)
     285             :     {
     286             :       mooseAssert(!value.empty(), "Missing a value to initialize on");
     287             : 
     288             :       // With MOOSE enums we need a default object so it should have been
     289             :       // passed in the param pointer. We are only going to use the first
     290             :       // item in the vector (value[0]) and ignore the rest.
     291         536 :       const auto vec = field.param<std::vector<std::string>>();
     292         268 :       value.resize(vec.size(), value[0]);
     293         735 :       for (const auto i : index_range(vec))
     294         471 :         value[i] = vec[i];
     295         268 :     });
     296             : // std::vector<MooseEnum>
     297             : static auto vector_multimooseenum = registry.add<std::vector<MultiMooseEnum>>(
     298          19 :     [](std::vector<MultiMooseEnum> & value, const hit::Field & field)
     299             :     {
     300             :       mooseAssert(!value.empty(), "Missing a value to initialize on");
     301             : 
     302          76 :       const auto tokens = MooseUtils::split(field.param<std::string>(), ";");
     303          89 :       for (const auto i : index_range(tokens))
     304             :       {
     305          74 :         const auto & entry = tokens[i];
     306         148 :         if (MooseUtils::trim(entry) == "")
     307           8 :           throw std::invalid_argument("entry " + std::to_string(i) + " in '" + field.fullpath() +
     308          12 :                                       "' is empty");
     309             :       }
     310          15 :       value.resize(tokens.size(), value[0]);
     311          77 :       for (const auto i : index_range(tokens))
     312             :       {
     313          66 :         std::vector<std::string> strvals;
     314          66 :         MooseUtils::tokenize<std::string>(tokens[i], strvals, 1, " ");
     315          66 :         value[i] = strvals;
     316          66 :       }
     317          19 :     });
     318             : // std::vector<ReporterName>
     319             : static auto vector_reportername = registry.add<std::vector<ReporterName>>(
     320        1176 :     [](std::vector<ReporterName> & value, const hit::Field & field)
     321             :     {
     322        1176 :       value.clear();
     323        2352 :       const auto names = field.param<std::vector<std::string>>();
     324        1176 :       value.resize(names.size());
     325        3351 :       for (const auto i : index_range(names))
     326        2176 :         value[i] = convert_reporter_name(names[i], field);
     327        1176 :     });
     328             : // std::vector<CLIArgString>
     329             : static auto vector_cliargstring = registry.add<std::vector<CLIArgString>>(
     330        1877 :     [](std::vector<CLIArgString> & value, const hit::Field & field)
     331             :     {
     332        1877 :       value.clear();
     333        3754 :       const auto strvals = field.param<std::vector<std::string>>();
     334        1877 :       if (strvals.empty())
     335           4 :         return;
     336             : 
     337             :       // slightly oversized if vectors have been split
     338        1873 :       value.resize(strvals.size());
     339             : 
     340             :       // Re-assemble vector parameters
     341        1873 :       unsigned int i_param = 0;
     342        1873 :       bool vector_param_detected = false;
     343        5212 :       for (const auto i : index_range(strvals))
     344             :       {
     345             :         // Look for a quote, both types
     346             :         const auto double_split =
     347        6678 :             MooseUtils::rsplit(strvals[i], "\"", std::numeric_limits<std::size_t>::max());
     348             :         const auto single_split =
     349        6678 :             MooseUtils::rsplit(strvals[i], "\'", std::numeric_limits<std::size_t>::max());
     350        3339 :         if (double_split.size() + single_split.size() >= 3)
     351             :           // Either entering or exiting a vector parameter (>3 is entering another vector)
     352             :           // Even and >2 number of quotes means both finished and started another vector parameter
     353        1607 :           if ((double_split.size() + single_split.size()) % 2 == 1)
     354         234 :             vector_param_detected = !vector_param_detected;
     355             : 
     356             :         // We're building a vector parameters, just append the text, rebuild the spaces
     357        3339 :         if (vector_param_detected)
     358         390 :           value[i_param] += strvals[i] + ' ';
     359             :         else
     360             :         {
     361        2949 :           value[i_param] += strvals[i];
     362        2949 :           i_param++;
     363             :         }
     364        3339 :       }
     365             :       // Use actual size after re-forming vector parameters
     366        1873 :       value.resize(i_param);
     367        1877 :     });
     368             : 
     369             : /*******************************************************************************/
     370             : /* Component-typed double vector registration                                  */
     371             : /*******************************************************************************/
     372             : 
     373             : /// Helper for setting a double vector component value (one with 3 real values)
     374         119 : const auto set_double_vector_component_value = [](auto & value, const hit::Field & field)
     375             : {
     376         238 :   const auto strval = field.param<std::string>();
     377             : 
     378             :   // Split vector at delim ";" (substrings are not of type T yet)
     379         119 :   std::vector<std::string> tokens;
     380         119 :   MooseUtils::tokenize(strval, tokens, 1, ";");
     381         119 :   value.resize(tokens.size());
     382             : 
     383             :   // Split each token at spaces
     384         119 :   std::vector<std::vector<double>> vecvec(tokens.size());
     385         355 :   for (const auto i : index_range(tokens))
     386         474 :     if (!MooseUtils::tokenizeAndConvert<double>(tokens[i], vecvec[i]))
     387           1 :       throw std::invalid_argument("invalid format for parameter '" + field.fullpath() +
     388             :                                   "' at index " + std::to_string(i));
     389             : 
     390         353 :   for (const auto i : index_range(vecvec))
     391             :   {
     392         236 :     const auto & vec = vecvec[i];
     393         236 :     if (vec.size() % LIBMESH_DIM)
     394           1 :       throw std::invalid_argument(
     395             :           "wrong number of values in double-indexed vector component parameter '" +
     396             :           field.fullpath() + "' at index " + std::to_string(i) + ": subcomponent size " +
     397             :           std::to_string(vec.size()) + " is not a multiple of " + std::to_string(LIBMESH_DIM));
     398             :   }
     399             : 
     400             :   // convert vector<vector<double>> to vector<vector<T>>
     401         117 :   value.resize(vecvec.size());
     402         351 :   for (const auto i : index_range(vecvec))
     403             :   {
     404         234 :     const auto & vec_entry = vecvec[i];
     405         234 :     auto & value_entry = value[i];
     406         234 :     const std::size_t size = vec_entry.size() / LIBMESH_DIM;
     407         234 :     value_entry.resize(size);
     408         815 :     for (const auto j : make_range(size))
     409        2324 :       for (const auto d : make_range(LIBMESH_DIM))
     410        1743 :         value_entry[j](d) = vec_entry[j * LIBMESH_DIM + d];
     411             :   }
     412         123 : };
     413             : 
     414             : // std::vector<std::vector<Point>>
     415             : static auto doublevector_point = registry.add<std::vector<std::vector<Point>>>(
     416         118 :     [](std::vector<std::vector<Point>> & value, const hit::Field & field)
     417         118 :     { set_double_vector_component_value(value, field); });
     418             : // std::vector<std::vector<RealVectorValue>>
     419             : static auto doublevector_realvectorvalue = registry.add<std::vector<std::vector<RealVectorValue>>>(
     420           1 :     [](std::vector<std::vector<RealVectorValue>> & value, const hit::Field & field)
     421           1 :     { set_double_vector_component_value(value, field); });
     422             : 
     423             : /*******************************************************************************/
     424             : /* Map registration                                                            */
     425             : /*******************************************************************************/
     426             : 
     427           0 : registerMapParameter(std::string, unsigned int);
     428          52 : registerMapParameter(std::string, Real);
     429         359 : registerMapParameter(std::string, std::string);
     430          13 : registerMapParameter(unsigned int, unsigned int);
     431          13 : registerMapParameter(unsigned long, unsigned int);
     432          13 : registerMapParameter(unsigned long long, unsigned int);
     433             : 
     434             : } // end of namespace detail
     435             : } // end of namespace Moose::ParameterRegistration

Generated by: LCOV version 1.14