LCOV - code coverage report
Current view: top level - src/actions - AddDefaultConvergenceAction.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 419b9d Lines: 108 127 85.0 %
Date: 2025-08-08 20:01:16 Functions: 9 9 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 "AddDefaultConvergenceAction.h"
      11             : #include "FEProblem.h"
      12             : #include "Executioner.h"
      13             : #include "FEProblemSolve.h"
      14             : #include "FixedPointSolve.h"
      15             : #include "TransientBase.h"
      16             : #include "DefaultNonlinearConvergence.h"
      17             : #include "DefaultMultiAppFixedPointConvergence.h"
      18             : #include "DefaultSteadyStateConvergence.h"
      19             : 
      20             : registerMooseAction("MooseApp", AddDefaultConvergenceAction, "add_default_nonlinear_convergence");
      21             : registerMooseAction("MooseApp",
      22             :                     AddDefaultConvergenceAction,
      23             :                     "add_default_multiapp_fixed_point_convergence");
      24             : registerMooseAction("MooseApp",
      25             :                     AddDefaultConvergenceAction,
      26             :                     "add_default_steady_state_convergence");
      27             : 
      28             : InputParameters
      29       66787 : AddDefaultConvergenceAction::validParams()
      30             : {
      31       66787 :   InputParameters params = Action::validParams();
      32       66787 :   params.addClassDescription("Adds default Convergence objects to the simulation.");
      33       66787 :   return params;
      34           0 : }
      35             : 
      36       66787 : AddDefaultConvergenceAction::AddDefaultConvergenceAction(const InputParameters & params)
      37       66787 :   : Action(params)
      38             : {
      39       66787 : }
      40             : 
      41             : void
      42      186183 : AddDefaultConvergenceAction::act()
      43             : {
      44      186183 :   if (_current_task == "add_default_nonlinear_convergence")
      45       62073 :     addDefaultNonlinearConvergence();
      46      124110 :   else if (_current_task == "add_default_multiapp_fixed_point_convergence")
      47       62061 :     addDefaultMultiAppFixedPointConvergence();
      48       62049 :   else if (_current_task == "add_default_steady_state_convergence")
      49       62049 :     addDefaultSteadyStateConvergence();
      50      186159 : }
      51             : 
      52             : void
      53       62073 : AddDefaultConvergenceAction::addDefaultNonlinearConvergence()
      54             : {
      55       62073 :   if (_problem->needToAddDefaultNonlinearConvergence())
      56             :   {
      57       61502 :     const std::string default_name = "default_nonlinear_convergence";
      58             :     // Create a default convergence for every nonlinear system
      59       61502 :     std::vector<ConvergenceName> default_name_vec;
      60      121943 :     for (const auto & nl_sys_name : _problem->getNonlinearSystemNames())
      61       60441 :       default_name_vec.push_back(default_name + nl_sys_name);
      62       61502 :     _problem->setNonlinearConvergenceNames(default_name_vec);
      63       61502 :     _problem->addDefaultNonlinearConvergence(getMooseApp().getExecutioner()->parameters());
      64       61494 :   }
      65             : 
      66       62065 :   checkUnusedNonlinearConvergenceParameters();
      67       62061 : }
      68             : 
      69             : void
      70       62061 : AddDefaultConvergenceAction::addDefaultMultiAppFixedPointConvergence()
      71             : {
      72       62061 :   if (_problem->needToAddDefaultMultiAppFixedPointConvergence())
      73             :   {
      74       61964 :     const std::string conv_name = "default_multiapp_fixed_point_convergence";
      75       61964 :     _problem->setMultiAppFixedPointConvergenceName(conv_name);
      76       61964 :     _problem->addDefaultMultiAppFixedPointConvergence(getMooseApp().getExecutioner()->parameters());
      77       61952 :   }
      78             : 
      79       62049 :   checkUnusedMultiAppFixedPointConvergenceParameters();
      80       62049 : }
      81             : 
      82             : void
      83       62049 : AddDefaultConvergenceAction::addDefaultSteadyStateConvergence()
      84             : {
      85       62049 :   if (_problem->needToAddDefaultSteadyStateConvergence())
      86             :   {
      87       30542 :     const std::string conv_name = "default_steady_state_convergence";
      88       30542 :     _problem->setSteadyStateConvergenceName(conv_name);
      89       30542 :     _problem->addDefaultSteadyStateConvergence(getMooseApp().getExecutioner()->parameters());
      90       30542 :   }
      91             : 
      92       62049 :   checkUnusedSteadyStateConvergenceParameters();
      93       62049 : }
      94             : 
      95             : void
      96       62065 : AddDefaultConvergenceAction::checkUnusedNonlinearConvergenceParameters()
      97             : {
      98             :   // Only perform this check if the executioner uses Convergence objects
      99       62065 :   auto & executioner_params = getMooseApp().getExecutioner()->parameters();
     100       62065 :   if (!executioner_params.have_parameter<std::vector<ConvergenceName>>("nonlinear_convergence"))
     101         256 :     return;
     102             : 
     103             :   // Convergences may exist but be inactive
     104       61809 :   bool has_convergence = false;
     105      122557 :   for (const auto & cv_name : _problem->getNonlinearConvergenceNames())
     106       60748 :     if (_problem->hasConvergence(cv_name))
     107       60748 :       has_convergence = true;
     108       61809 :   if (!has_convergence)
     109        1277 :     return;
     110             : 
     111             :   // If a single convergence is a `DefaultNonlinearConvergence` they can handle the Executioner
     112             :   // parameters pertaining to the nonlinear system solve
     113       60532 :   bool has_a_default_nl_conv = false;
     114      121280 :   for (const auto & cv_name : _problem->getNonlinearConvergenceNames())
     115             :   {
     116       60748 :     if (!_problem->hasConvergence(cv_name))
     117           0 :       continue;
     118       60748 :     auto & conv = _problem->getConvergence(cv_name);
     119       60748 :     auto * default_nl_conv = dynamic_cast<DefaultNonlinearConvergence *>(&conv);
     120       60748 :     if (default_nl_conv)
     121       60624 :       has_a_default_nl_conv = true;
     122             :   }
     123             : 
     124             :   // Only Convergence objects deriving from DefaultNonlinearConvergence should
     125             :   // share parameters with the executioner.
     126       60532 :   if (!has_a_default_nl_conv)
     127             :   {
     128         244 :     for (const auto & cv_name : _problem->getNonlinearConvergenceNames())
     129             :     {
     130         124 :       if (!_problem->hasConvergence(cv_name))
     131           0 :         continue;
     132             : 
     133         124 :       auto nl_params = FEProblemSolve::feProblemDefaultConvergenceParams();
     134         124 :       std::vector<std::string> unused_params;
     135        1364 :       for (const auto & param : nl_params.getParametersList())
     136        1240 :         if (executioner_params.isParamSetByUser(param))
     137         128 :           unused_params.push_back(param);
     138             : 
     139         124 :       if (unused_params.size() > 0)
     140             :       {
     141           4 :         std::stringstream msg;
     142             :         msg << "The following nonlinear convergence parameters were set in the executioner, but "
     143           4 :                "are not used:\n";
     144           8 :         for (const auto & param : unused_params)
     145           4 :           msg << "  " << param << "\n";
     146           4 :         mooseError(msg.str());
     147           0 :       }
     148         120 :     }
     149             :   }
     150             : }
     151             : 
     152             : void
     153       62049 : AddDefaultConvergenceAction::checkUnusedMultiAppFixedPointConvergenceParameters()
     154             : {
     155             :   // Abort check if executioner does not allow Convergence objects
     156       62049 :   auto & executioner_params = getMooseApp().getExecutioner()->parameters();
     157       62049 :   if (!executioner_params.have_parameter<ConvergenceName>("multiapp_fixed_point_convergence"))
     158           0 :     return;
     159             : 
     160             :   // Abort if there is no fixed point convergence. For example, Executors may not have them.
     161       62049 :   if (!_problem->hasSetMultiAppFixedPointConvergenceName())
     162          20 :     return;
     163             : 
     164       62029 :   const auto & conv_name = _problem->getMultiAppFixedPointConvergenceName();
     165             : 
     166             :   // Abort check if Convergence is inactive
     167       62029 :   if (!_problem->hasConvergence(conv_name))
     168           0 :     return;
     169             : 
     170             :   // If the convergence is a DefaultMultiAppFixedPointConvergence they can handle the Executioner
     171             :   // parameters pertaining to the fixed point solve
     172       62029 :   auto & conv = _problem->getConvergence(conv_name);
     173       62029 :   const auto * const default_conv = dynamic_cast<DefaultMultiAppFixedPointConvergence *>(&conv);
     174             : 
     175             :   // Only Convergence objects deriving from DefaultMultiAppFixedPointConvergence should
     176             :   // share parameters with the executioner
     177       62029 :   if (!default_conv)
     178             :   {
     179          43 :     auto fp_params = FixedPointSolve::fixedPointDefaultConvergenceParams();
     180          43 :     std::vector<std::string> unused_params;
     181         516 :     for (const auto & param : fp_params.getParametersList())
     182         473 :       if (executioner_params.isParamSetByUser(param))
     183          43 :         unused_params.push_back(param);
     184             : 
     185          43 :     if (unused_params.size() > 0)
     186             :     {
     187           0 :       std::stringstream msg;
     188             :       msg << "The following fixed point convergence parameters were set in the executioner, but "
     189           0 :              "are not used:\n";
     190           0 :       for (const auto & param : unused_params)
     191           0 :         msg << "  " << param << "\n";
     192           0 :       mooseError(msg.str());
     193           0 :     }
     194          43 :   }
     195             : }
     196             : 
     197             : void
     198       62049 : AddDefaultConvergenceAction::checkUnusedSteadyStateConvergenceParameters()
     199             : {
     200             :   // Abort check if executioner does not allow Convergence objects
     201       62049 :   auto & executioner_params = getMooseApp().getExecutioner()->parameters();
     202       62049 :   if (!executioner_params.have_parameter<ConvergenceName>("steady_state_convergence"))
     203       31469 :     return;
     204             : 
     205       30580 :   const auto conv_name = _problem->getSteadyStateConvergenceName();
     206             : 
     207             :   // Abort check if Convergence is inactive
     208       30580 :   if (!_problem->hasConvergence(conv_name))
     209           0 :     return;
     210             : 
     211             :   // If the convergence is a DefaultSteadyStateConvergence they can handle the Executioner
     212             :   // parameters pertaining to the steady solve
     213       30580 :   auto & conv = _problem->getConvergence(conv_name);
     214       30580 :   auto * default_conv = dynamic_cast<DefaultSteadyStateConvergence *>(&conv);
     215             : 
     216             :   // Only Convergence objects deriving from DefaultSteadyStateConvergence should
     217             :   // share parameters with the executioner
     218       30580 :   if (!default_conv)
     219             :   {
     220          17 :     auto params = TransientBase::defaultSteadyStateConvergenceParams();
     221          17 :     std::vector<std::string> unused_params;
     222          68 :     for (const auto & param : params.getParametersList())
     223          51 :       if (executioner_params.isParamSetByUser(param))
     224          17 :         unused_params.push_back(param);
     225             : 
     226          17 :     if (unused_params.size() > 0)
     227             :     {
     228           0 :       std::stringstream msg;
     229             :       msg << "The following steady-state convergence parameters were set in the executioner, but "
     230           0 :              "are not used:\n";
     231           0 :       for (const auto & param : unused_params)
     232           0 :         msg << "  " << param << "\n";
     233           0 :       mooseError(msg.str());
     234           0 :     }
     235          17 :   }
     236       30580 : }

Generated by: LCOV version 1.14