LCOV - code coverage report
Current view: top level - src/actions - AddDefaultConvergenceAction.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 9a5f1f Lines: 108 127 85.0 %
Date: 2026-06-21 21:23:42 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       66338 : AddDefaultConvergenceAction::validParams()
      30             : {
      31       66338 :   InputParameters params = Action::validParams();
      32       66338 :   params.addClassDescription("Adds default Convergence objects to the simulation.");
      33       66338 :   return params;
      34           0 : }
      35             : 
      36       66338 : AddDefaultConvergenceAction::AddDefaultConvergenceAction(const InputParameters & params)
      37       66338 :   : Action(params)
      38             : {
      39       66338 : }
      40             : 
      41             : void
      42      184188 : AddDefaultConvergenceAction::act()
      43             : {
      44      184188 :   if (_current_task == "add_default_nonlinear_convergence")
      45       61405 :     addDefaultNonlinearConvergence();
      46      122783 :   else if (_current_task == "add_default_multiapp_fixed_point_convergence")
      47       61396 :     addDefaultMultiAppFixedPointConvergence();
      48       61387 :   else if (_current_task == "add_default_steady_state_convergence")
      49       61387 :     addDefaultSteadyStateConvergence();
      50      184170 : }
      51             : 
      52             : void
      53       61405 : AddDefaultConvergenceAction::addDefaultNonlinearConvergence()
      54             : {
      55       61405 :   if (_problem->needToAddDefaultNonlinearConvergence())
      56             :   {
      57       59703 :     const std::string default_name = "default_nonlinear_convergence";
      58             :     // Create a default convergence for every nonlinear system
      59       59703 :     std::vector<ConvergenceName> default_name_vec;
      60      118627 :     for (const auto & nl_sys_name : _problem->getNonlinearSystemNames())
      61       58924 :       default_name_vec.push_back(default_name + nl_sys_name);
      62       59703 :     _problem->setNonlinearConvergenceNames(default_name_vec);
      63       59703 :     _problem->addDefaultNonlinearConvergence(getMooseApp().getExecutioner()->parameters());
      64       59697 :   }
      65             : 
      66       61399 :   checkUnusedNonlinearConvergenceParameters();
      67       61396 : }
      68             : 
      69             : void
      70       61396 : AddDefaultConvergenceAction::addDefaultMultiAppFixedPointConvergence()
      71             : {
      72       61396 :   if (_problem->needToAddDefaultMultiAppFixedPointConvergence())
      73             :   {
      74       61297 :     const std::string conv_name = "default_multiapp_fixed_point_convergence";
      75       61297 :     _problem->setMultiAppFixedPointConvergenceName(conv_name);
      76       61297 :     _problem->addDefaultMultiAppFixedPointConvergence(getMooseApp().getExecutioner()->parameters());
      77       61288 :   }
      78             : 
      79       61387 :   checkUnusedMultiAppFixedPointConvergenceParameters();
      80       61387 : }
      81             : 
      82             : void
      83       61387 : AddDefaultConvergenceAction::addDefaultSteadyStateConvergence()
      84             : {
      85       61387 :   if (_problem->needToAddDefaultSteadyStateConvergence())
      86             :   {
      87       30229 :     const std::string conv_name = "default_steady_state_convergence";
      88       30229 :     _problem->setSteadyStateConvergenceName(conv_name);
      89       30229 :     _problem->addDefaultSteadyStateConvergence(getMooseApp().getExecutioner()->parameters());
      90       30229 :   }
      91             : 
      92       61387 :   checkUnusedSteadyStateConvergenceParameters();
      93       61387 : }
      94             : 
      95             : void
      96       61399 : AddDefaultConvergenceAction::checkUnusedNonlinearConvergenceParameters()
      97             : {
      98             :   // Only perform this check if the executioner uses Convergence objects
      99       61399 :   auto & executioner_params = getMooseApp().getExecutioner()->parameters();
     100       61399 :   if (!executioner_params.have_parameter<std::vector<ConvergenceName>>("nonlinear_convergence"))
     101        1408 :     return;
     102             : 
     103             :   // Convergences may exist but be inactive
     104       59991 :   bool has_convergence = false;
     105      119203 :   for (const auto & cv_name : _problem->getNonlinearConvergenceNames())
     106       59212 :     if (_problem->hasConvergence(cv_name))
     107       59212 :       has_convergence = true;
     108       59991 :   if (!has_convergence)
     109         980 :     return;
     110             : 
     111             :   // If a single convergence is a `DefaultNonlinearConvergence` they can handle the Executioner
     112             :   // parameters pertaining to the nonlinear system solve
     113       59011 :   bool has_a_default_nl_conv = false;
     114      118223 :   for (const auto & cv_name : _problem->getNonlinearConvergenceNames())
     115             :   {
     116       59212 :     if (!_problem->hasConvergence(cv_name))
     117           0 :       continue;
     118       59212 :     auto & conv = _problem->getConvergence(cv_name);
     119       59212 :     auto * default_nl_conv = dynamic_cast<DefaultNonlinearConvergence *>(&conv);
     120       59212 :     if (default_nl_conv)
     121       59089 :       has_a_default_nl_conv = true;
     122             :   }
     123             : 
     124             :   // Only Convergence objects deriving from DefaultNonlinearConvergence should
     125             :   // share parameters with the executioner.
     126       59011 :   if (!has_a_default_nl_conv)
     127             :   {
     128         243 :     for (const auto & cv_name : _problem->getNonlinearConvergenceNames())
     129             :     {
     130         123 :       if (!_problem->hasConvergence(cv_name))
     131           0 :         continue;
     132             : 
     133         123 :       auto nl_params = FEProblemSolve::feProblemDefaultConvergenceParams();
     134         123 :       std::vector<std::string> unused_params;
     135        1353 :       for (const auto & param : nl_params.getParametersList())
     136        1230 :         if (executioner_params.isParamSetByUser(param))
     137         126 :           unused_params.push_back(param);
     138             : 
     139         123 :       if (unused_params.size() > 0)
     140             :       {
     141           3 :         std::stringstream msg;
     142             :         msg << "The following nonlinear convergence parameters were set in the executioner, but "
     143           3 :                "are not used:\n";
     144           6 :         for (const auto & param : unused_params)
     145           3 :           msg << "  " << param << "\n";
     146           3 :         mooseError(msg.str());
     147           0 :       }
     148         120 :     }
     149             :   }
     150             : }
     151             : 
     152             : void
     153       61387 : AddDefaultConvergenceAction::checkUnusedMultiAppFixedPointConvergenceParameters()
     154             : {
     155             :   // Abort check if executioner does not allow Convergence objects
     156       61387 :   auto & executioner_params = getMooseApp().getExecutioner()->parameters();
     157       61387 :   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       61387 :   if (!_problem->hasSetMultiAppFixedPointConvergenceName())
     162          18 :     return;
     163             : 
     164       61369 :   const auto & conv_name = _problem->getMultiAppFixedPointConvergenceName();
     165             : 
     166             :   // Abort check if Convergence is inactive
     167       61369 :   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       61369 :   auto & conv = _problem->getConvergence(conv_name);
     173       61369 :   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       61369 :   if (!default_conv)
     178             :   {
     179          51 :     auto fp_params = FixedPointSolve::fixedPointDefaultConvergenceParams();
     180          51 :     std::vector<std::string> unused_params;
     181         612 :     for (const auto & param : fp_params.getParametersList())
     182         561 :       if (executioner_params.isParamSetByUser(param))
     183          51 :         unused_params.push_back(param);
     184             : 
     185          51 :     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          51 :   }
     195             : }
     196             : 
     197             : void
     198       61387 : AddDefaultConvergenceAction::checkUnusedSteadyStateConvergenceParameters()
     199             : {
     200             :   // Abort check if executioner does not allow Convergence objects
     201       61387 :   auto & executioner_params = getMooseApp().getExecutioner()->parameters();
     202       61387 :   if (!executioner_params.have_parameter<ConvergenceName>("steady_state_convergence"))
     203       31101 :     return;
     204             : 
     205       30286 :   const auto conv_name = _problem->getSteadyStateConvergenceName();
     206             : 
     207             :   // Abort check if Convergence is inactive
     208       30286 :   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       30286 :   auto & conv = _problem->getConvergence(conv_name);
     214       30286 :   auto * default_conv = dynamic_cast<DefaultSteadyStateConvergence *>(&conv);
     215             : 
     216             :   // Only Convergence objects deriving from DefaultSteadyStateConvergence should
     217             :   // share parameters with the executioner
     218       30286 :   if (!default_conv)
     219             :   {
     220          39 :     auto params = TransientBase::defaultSteadyStateConvergenceParams();
     221          39 :     std::vector<std::string> unused_params;
     222         156 :     for (const auto & param : params.getParametersList())
     223         117 :       if (executioner_params.isParamSetByUser(param))
     224          39 :         unused_params.push_back(param);
     225             : 
     226          39 :     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          39 :   }
     236       30286 : }

Generated by: LCOV version 1.14