LCOV - code coverage report
Current view: top level - src/problems - DumpObjectsProblem.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 102 138 73.9 %
Date: 2025-07-17 01:28:37 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       14305 : DumpObjectsProblem::validParams()
      30             : {
      31       14305 :   InputParameters params = FEProblemBase::validParams();
      32       14305 :   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       14305 :   params.addParam<std::string>(
      36             :       "dump_path", "all", "Syntax path of the action of which to dump the generated syntax");
      37       42915 :   params.addParam<bool>(
      38             :       "include_all_user_specified_params",
      39       28610 :       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       42915 :   params.addParam<bool>(
      46             :       "solve",
      47       28610 :       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       14305 :   return params;
      51           0 : }
      52             : 
      53          20 : DumpObjectsProblem::DumpObjectsProblem(const InputParameters & parameters)
      54             :   : FEProblemBase(parameters),
      55          20 :     _include_all_user_specified_params(getParam<bool>("include_all_user_specified_params"))
      56             : {
      57             :   // Make dummy systems based on parameters passed
      58          20 :   _solver_systems.resize(0);
      59          40 :   for (const auto i : index_range(_nl_sys_names))
      60             :   {
      61          20 :     const auto & sys_name = _nl_sys_names[i];
      62          20 :     const auto & new_sys = std::make_shared<DumpObjectsNonlinearSystem>(*this, sys_name);
      63          20 :     _solver_systems.push_back(new_sys);
      64          20 :     _nl[i] = new_sys;
      65          20 :   }
      66          20 :   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          20 :   _aux = std::make_shared<AuxiliarySystem>(*this, "aux0");
      74             : 
      75             :   // Create a dummy assembly for the systems at hand
      76          20 :   newAssemblyArray(_solver_systems);
      77             : 
      78             :   // Create extra vectors and matrices if any
      79          20 :   createTagVectors();
      80             : 
      81             :   // Create extra solution vectors if any
      82          20 :   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          20 :   auto action_params = _app.getActionFactory().getValidParams("DumpObjectsAction");
      88          20 :   action_params.applyParameters(parameters);
      89             :   auto dump_objects_action =
      90          20 :       _app.getActionFactory().create("DumpObjectsAction", "dump_objects", action_params);
      91          20 :   _app.actionWarehouse().addActionBlock(dump_objects_action);
      92          20 : }
      93             : 
      94             : std::string
      95         100 : DumpObjectsProblem::deduceNecessaryParameters(const std::string & type,
      96             :                                               const InputParameters & parameters)
      97             : {
      98         100 :   auto factory_params = stringifyParameters(_factory.getValidParams(type));
      99         100 :   auto specified_params = stringifyParameters(parameters);
     100             : 
     101         100 :   std::string param_text;
     102        1340 :   for (auto & value_pair : specified_params)
     103             :   {
     104             :     // parameter name
     105        1240 :     const auto & param_name = value_pair.first;
     106        1240 :     const auto & param_value = value_pair.second;
     107             : 
     108             :     // determine whether to include the parameter
     109        1240 :     auto factory_it = factory_params.find(param_name);
     110        1240 :     bool include_param = (factory_it->second != param_value);
     111        1240 :     if (_include_all_user_specified_params)
     112        1240 :       include_param = include_param || parameters.isParamSetByUser(param_name);
     113        1240 :     if (factory_it == factory_params.end() || include_param)
     114         160 :       param_text += "    " + param_name + " = " + param_value + '\n';
     115             :   }
     116             : 
     117         200 :   return param_text;
     118         100 : }
     119             : 
     120             : void
     121         100 : DumpObjectsProblem::dumpObjectHelper(const std::string & system,
     122             :                                      const std::string & type,
     123             :                                      const std::string & name,
     124             :                                      const InputParameters & parameters)
     125             : {
     126         100 :   auto path = _app.actionWarehouse().getCurrentActionName();
     127         100 :   auto param_text = deduceNecessaryParameters(type, parameters);
     128             : 
     129             :   // clang-format off
     130         100 :   _generated_syntax[path][system] +=
     131         200 :         "  [" + name + "]\n"
     132         200 :       + "    type = " + type + '\n'
     133         200 :       +      param_text
     134         200 :       + "  []\n";
     135             :   // clang-format on
     136         100 : }
     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          20 : DumpObjectsProblem::printObjects()
     187             : {
     188          20 :   const auto path = getParam<std::string>("dump_path");
     189          20 :   if (path != "all")
     190          10 :     dumpGeneratedSyntax(path);
     191             :   else
     192          10 :     dumpAllGeneratedSyntax();
     193          20 : }
     194             : 
     195             : void
     196          10 : DumpObjectsProblem::dumpGeneratedSyntax(const std::string path)
     197             : {
     198          10 :   auto pathit = _generated_syntax.find(path);
     199          10 :   if (pathit == _generated_syntax.end())
     200           0 :     return;
     201             : 
     202          10 :   Moose::out << "**START DUMP DATA**\n";
     203          40 :   for (const auto & system_pair : pathit->second)
     204          30 :     Moose::out << '[' << system_pair.first << "]\n" << system_pair.second << "[]\n\n";
     205          10 :   Moose::out << "**END DUMP DATA**\n";
     206          10 :   Moose::out << std::flush;
     207             : }
     208             : 
     209             : void
     210          10 : DumpObjectsProblem::dumpAllGeneratedSyntax() const
     211             : {
     212          10 :   Moose::out << "**START DUMP DATA**\n";
     213          30 :   for (const auto & path : _generated_syntax)
     214          60 :     for (const auto & system_pair : path.second)
     215          40 :       Moose::out << '[' << system_pair.first << "]\n" << system_pair.second << "[]\n\n";
     216          10 :   Moose::out << "**END DUMP DATA**\n";
     217          10 :   Moose::out << std::flush;
     218          10 : }
     219             : 
     220             : std::map<std::string, std::string>
     221         200 : DumpObjectsProblem::stringifyParameters(const InputParameters & parameters)
     222             : {
     223         200 :   std::map<std::string, std::string> parameter_map;
     224             : 
     225         200 :   std::string syntax;
     226         200 :   if (parameters.isParamValid("parser_syntax"))
     227           0 :     syntax = parameters.get<std::string>("parser_syntax");
     228             : 
     229        6960 :   for (auto & value_pair : parameters)
     230             :   {
     231             :     // parameter name
     232        6760 :     const auto & param_name = value_pair.first;
     233             : 
     234        6760 :     if (!parameters.isPrivate(param_name) && parameters.isParamValid(param_name))
     235             :     {
     236        2440 :       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        2400 :         std::string param_value;
     247        2400 :         if (parameters.have_parameter<bool>(param_name))
     248             :         {
     249        1000 :           const bool & b = parameters.get<bool>(param_name);
     250        1000 :           param_value = b ? "true" : "false";
     251             :         }
     252             :         else
     253             :         {
     254        1400 :           std::stringstream ss;
     255        1400 :           value_pair.second->print(ss);
     256        1400 :           param_value = ss.str();
     257        1400 :         }
     258             : 
     259             :         // delete trailing space
     260        2400 :         if (!param_value.empty() && param_value.back() == ' ')
     261          80 :           param_value.pop_back();
     262             : 
     263             :         // add quotes if the parameter contains spaces or is empty
     264        2400 :         if (param_value.find_first_of(" ") != std::string::npos || param_value.length() == 0)
     265         240 :           param_value = "'" + param_value + "'";
     266             : 
     267        2400 :         parameter_map[param_name] = param_value;
     268        2400 :       }
     269             :     }
     270             :   }
     271             : 
     272         400 :   return parameter_map;
     273         200 : }
     274             : 
     275             : void
     276          20 : DumpObjectsProblem::initialSetup()
     277             : {
     278          20 :   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          20 :   _functions.initialSetup(0);
     287          20 : }

Generated by: LCOV version 1.14