LCOV - code coverage report
Current view: top level - src/problems - DumpObjectsProblem.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 102 138 73.9 %
Date: 2026-05-29 20:35:17 Functions: 9 10 90.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 "DumpObjectsProblem.h"
      11             : #include "DumpObjectsAction.h"
      12             : #include "DumpObjectsNonlinearSystem.h"
      13             : #include "DumpObjectsLinearSystem.h"
      14             : #include "AuxiliarySystem.h"
      15             : #include "InputParameters.h"
      16             : #include "NonlinearSystem.h"
      17             : #include "LinearSystem.h"
      18             : #include "SolverSystem.h"
      19             : #include "Function.h"
      20             : #include <sstream>
      21             : 
      22             : #include "libmesh/string_to_enum.h"
      23             : 
      24             : using namespace libMesh;
      25             : 
      26             : registerMooseObject("MooseApp", DumpObjectsProblem);
      27             : 
      28             : InputParameters
      29        3097 : DumpObjectsProblem::validParams()
      30             : {
      31        3097 :   InputParameters params = FEProblemBase::validParams();
      32        6194 :   params.addClassDescription("Single purpose problem object that does not run the given input but "
      33             :                              "allows deconstructing actions into their series of underlying Moose "
      34             :                              "objects and variables.");
      35       12388 :   params.addParam<std::string>(
      36             :       "dump_path", "all", "Syntax path of the action of which to dump the generated syntax");
      37        9291 :   params.addParam<bool>(
      38             :       "include_all_user_specified_params",
      39        6194 :       true,
      40             :       "Whether to include all parameters that have been specified by a user in the dump, even if "
      41             :       "they match the default value of the parameter in the Factory");
      42             : 
      43             :   // Change the default because any complex solve or executioners needs the problem to perform its
      44             :   // setup duties (all the calls in initialSetup()) which are skipped by the DumpObjectsProblem
      45        6194 :   params.addParam<bool>(
      46             :       "solve",
      47        6194 :       false,
      48             :       "Whether to attempt to solve the Problem. This will only cause additional outputs of the "
      49             :       "objects and their parameters. This is unlikely to succeed with more complex executioners.");
      50        3097 :   return params;
      51           0 : }
      52             : 
      53          18 : DumpObjectsProblem::DumpObjectsProblem(const InputParameters & parameters)
      54             :   : FEProblemBase(parameters),
      55          36 :     _include_all_user_specified_params(getParam<bool>("include_all_user_specified_params"))
      56             : {
      57             :   // Make dummy systems based on parameters passed
      58          18 :   _solver_systems.resize(0);
      59          36 :   for (const auto i : index_range(_nl_sys_names))
      60             :   {
      61          18 :     const auto & sys_name = _nl_sys_names[i];
      62          18 :     const auto & new_sys = std::make_shared<DumpObjectsNonlinearSystem>(*this, sys_name);
      63          18 :     _solver_systems.push_back(new_sys);
      64          18 :     _nl[i] = new_sys;
      65          18 :   }
      66          18 :   for (const auto i : index_range(_linear_sys_names))
      67             :   {
      68           0 :     const auto & sys_name = _linear_sys_names[i];
      69           0 :     const auto & new_sys = std::make_shared<DumpObjectsLinearSystem>(*this, sys_name);
      70           0 :     _solver_systems.push_back(new_sys);
      71           0 :     _linear_systems[i] = new_sys;
      72           0 :   }
      73          18 :   _aux = std::make_shared<AuxiliarySystem>(*this, "aux0");
      74             : 
      75             :   // Create a dummy assembly for the systems at hand
      76          18 :   newAssemblyArray(_solver_systems);
      77             : 
      78             :   // Create extra vectors and matrices if any
      79          18 :   createTagVectors();
      80             : 
      81             :   // Create extra solution vectors if any
      82          18 :   createTagSolutions();
      83             : 
      84             :   // Add an action to call printObjects at the end of the action/tasks phase
      85             :   // NOTE: We previously relied on problem.solve() but some executioners (SIMPLE in NavierStokes) do
      86             :   // not support this
      87          36 :   auto action_params = _app.getActionFactory().getValidParams("DumpObjectsAction");
      88          18 :   action_params.applyParameters(parameters);
      89             :   auto dump_objects_action =
      90          72 :       _app.getActionFactory().create("DumpObjectsAction", "dump_objects", action_params);
      91          18 :   _app.actionWarehouse().addActionBlock(dump_objects_action);
      92          18 : }
      93             : 
      94             : std::string
      95          90 : DumpObjectsProblem::deduceNecessaryParameters(const std::string & type,
      96             :                                               const InputParameters & parameters)
      97             : {
      98          90 :   auto factory_params = stringifyParameters(_factory.getValidParams(type));
      99          90 :   auto specified_params = stringifyParameters(parameters);
     100             : 
     101          90 :   std::string param_text;
     102        1242 :   for (auto & value_pair : specified_params)
     103             :   {
     104             :     // parameter name
     105        1152 :     const auto & param_name = value_pair.first;
     106        1152 :     const auto & param_value = value_pair.second;
     107             : 
     108             :     // determine whether to include the parameter
     109        1152 :     auto factory_it = factory_params.find(param_name);
     110        1152 :     bool include_param = (factory_it->second != param_value);
     111        1152 :     if (_include_all_user_specified_params)
     112        1152 :       include_param = include_param || parameters.isParamSetByUser(param_name);
     113        1152 :     if (factory_it == factory_params.end() || include_param)
     114         144 :       param_text += "    " + param_name + " = " + param_value + '\n';
     115             :   }
     116             : 
     117         180 :   return param_text;
     118          90 : }
     119             : 
     120             : void
     121          90 : DumpObjectsProblem::dumpObjectHelper(const std::string & system,
     122             :                                      const std::string & type,
     123             :                                      const std::string & name,
     124             :                                      const InputParameters & parameters)
     125             : {
     126          90 :   auto path = _app.actionWarehouse().getCurrentActionName();
     127          90 :   auto param_text = deduceNecessaryParameters(type, parameters);
     128             : 
     129             :   // clang-format off
     130          90 :   _generated_syntax[path][system] +=
     131         180 :         "  [" + name + "]\n"
     132         180 :       + "    type = " + type + '\n'
     133         180 :       +      param_text
     134         180 :       + "  []\n";
     135             :   // clang-format on
     136          90 : }
     137             : 
     138             : void
     139           0 : DumpObjectsProblem::dumpVariableHelper(const std::string & system,
     140             :                                        const std::string & var_name,
     141             :                                        FEFamily family,
     142             :                                        Order order,
     143             :                                        Real scale_factor,
     144             :                                        const std::set<SubdomainID> * const active_subdomains)
     145             : {
     146           0 :   auto path = _app.actionWarehouse().getCurrentActionName();
     147           0 :   std::string param_text;
     148             : 
     149           0 :   if (active_subdomains)
     150             :   {
     151           0 :     std::string blocks;
     152           0 :     for (auto & subdomain_id : *active_subdomains)
     153             :     {
     154           0 :       auto subdomain_name = _mesh.getMesh().subdomain_name(subdomain_id);
     155           0 :       if (subdomain_name == "")
     156           0 :         subdomain_name = std::to_string(subdomain_id);
     157             : 
     158           0 :       if (!blocks.empty())
     159           0 :         blocks += ' ';
     160             : 
     161           0 :       blocks += subdomain_name;
     162           0 :     }
     163             : 
     164           0 :     if (active_subdomains->size() > 1)
     165           0 :       blocks = "'" + blocks + "'";
     166             : 
     167           0 :     param_text += "    blocks = " + blocks + '\n';
     168           0 :   }
     169             : 
     170           0 :   if (family != LAGRANGE)
     171           0 :     param_text += "    family = " + libMesh::Utility::enum_to_string<FEFamily>(family) + '\n';
     172           0 :   if (order != FIRST)
     173           0 :     param_text += "    order = " + libMesh::Utility::enum_to_string<Order>(order) + '\n';
     174           0 :   if (scale_factor != 1.0)
     175           0 :     param_text += "    scale = " + std::to_string(scale_factor);
     176             : 
     177             :   // clang-format off
     178           0 :   _generated_syntax[path][system] +=
     179           0 :         "  [" + var_name + "]\n"
     180           0 :       +      param_text
     181           0 :       + "  []\n";
     182             :   // clang-format on
     183           0 : }
     184             : 
     185             : void
     186          18 : DumpObjectsProblem::printObjects()
     187             : {
     188          36 :   const auto path = getParam<std::string>("dump_path");
     189          18 :   if (path != "all")
     190           9 :     dumpGeneratedSyntax(path);
     191             :   else
     192           9 :     dumpAllGeneratedSyntax();
     193          18 : }
     194             : 
     195             : void
     196           9 : DumpObjectsProblem::dumpGeneratedSyntax(const std::string path)
     197             : {
     198           9 :   auto pathit = _generated_syntax.find(path);
     199           9 :   if (pathit == _generated_syntax.end())
     200           0 :     return;
     201             : 
     202           9 :   Moose::out << "**START DUMP DATA**\n";
     203          36 :   for (const auto & system_pair : pathit->second)
     204          27 :     Moose::out << '[' << system_pair.first << "]\n" << system_pair.second << "[]\n\n";
     205           9 :   Moose::out << "**END DUMP DATA**\n";
     206           9 :   Moose::out << std::flush;
     207             : }
     208             : 
     209             : void
     210           9 : DumpObjectsProblem::dumpAllGeneratedSyntax() const
     211             : {
     212           9 :   Moose::out << "**START DUMP DATA**\n";
     213          27 :   for (const auto & path : _generated_syntax)
     214          54 :     for (const auto & system_pair : path.second)
     215          36 :       Moose::out << '[' << system_pair.first << "]\n" << system_pair.second << "[]\n\n";
     216           9 :   Moose::out << "**END DUMP DATA**\n";
     217           9 :   Moose::out << std::flush;
     218           9 : }
     219             : 
     220             : std::map<std::string, std::string>
     221         180 : DumpObjectsProblem::stringifyParameters(const InputParameters & parameters)
     222             : {
     223         180 :   std::map<std::string, std::string> parameter_map;
     224             : 
     225         180 :   std::string syntax;
     226         360 :   if (parameters.isParamValid("parser_syntax"))
     227           0 :     syntax = parameters.get<std::string>("parser_syntax");
     228             : 
     229        6336 :   for (auto & value_pair : parameters)
     230             :   {
     231             :     // parameter name
     232        6156 :     const auto & param_name = value_pair.first;
     233             : 
     234        6156 :     if (!parameters.isPrivate(param_name) && parameters.isParamValid(param_name))
     235             :     {
     236        2268 :       if (param_name == "control_tags")
     237             :       {
     238             :         // deal with the control tags. The current parser_syntax is automatically added to this. So
     239             :         // we can remove the parameter if that's all there is in it
     240             :       }
     241             :       else
     242             :       {
     243             :         // special treatment for some types
     244             : 
     245             :         // parameter value
     246        2232 :         std::string param_value;
     247        2232 :         if (parameters.have_parameter<bool>(param_name))
     248             :         {
     249         900 :           const bool & b = parameters.get<bool>(param_name);
     250         900 :           param_value = b ? "true" : "false";
     251             :         }
     252             :         else
     253             :         {
     254        1332 :           std::stringstream ss;
     255        1332 :           value_pair.second->print(ss);
     256        1332 :           param_value = ss.str();
     257        1332 :         }
     258             : 
     259             :         // delete trailing space
     260        2232 :         if (!param_value.empty() && param_value.back() == ' ')
     261          72 :           param_value.pop_back();
     262             : 
     263             :         // add quotes if the parameter contains spaces or is empty
     264        2232 :         if (param_value.find_first_of(" ") != std::string::npos || param_value.length() == 0)
     265         216 :           param_value = "'" + param_value + "'";
     266             : 
     267        2232 :         parameter_map[param_name] = param_value;
     268        2232 :       }
     269             :     }
     270             :   }
     271             : 
     272         360 :   return parameter_map;
     273         180 : }
     274             : 
     275             : void
     276          18 : DumpObjectsProblem::initialSetup()
     277             : {
     278          90 :   TIME_SECTION("initializingFunctions", 5, "Initializing Functions");
     279             :   mooseAssert(libMesh::n_threads() == 1, "We should only use one thread for dumping objects");
     280             : 
     281             :   // Call the initialSetup methods for functions
     282             :   // We need to do that at least for the parsed functions that can be used as parameters
     283             :   // in the input file
     284             :   // Note that we are not planning to use the functions, which is why we are not re-initing scalar
     285             :   // variables
     286          18 :   _functions.initialSetup(0);
     287          18 : }

Generated by: LCOV version 1.14