LCOV - code coverage report
Current view: top level - src/multiapps - FullSolveMultiApp.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 57 64 89.1 %
Date: 2025-07-17 01:28:37 Functions: 6 6 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 "FullSolveMultiApp.h"
      11             : #include "LayeredSideDiffusiveFluxAverage.h"
      12             : #include "Executioner.h"
      13             : #include "TransientBase.h"
      14             : #include "Console.h"
      15             : 
      16             : // libMesh
      17             : #include "libmesh/mesh_tools.h"
      18             : 
      19             : registerMooseObject("MooseApp", FullSolveMultiApp);
      20             : 
      21             : InputParameters
      22       32486 : FullSolveMultiApp::validParams()
      23             : {
      24       32486 :   InputParameters params = MultiApp::validParams();
      25       32486 :   params.addClassDescription("Performs a complete simulation during each execution.");
      26       97458 :   params.addParam<bool>(
      27             :       "keep_full_output_history",
      28       64972 :       false,
      29             :       "Whether or not to keep the full output history when this multiapp has multiple entries");
      30       97458 :   params.addParam<bool>("ignore_solve_not_converge",
      31       64972 :                         false,
      32             :                         "True to continue main app even if a sub app's solve does not converge.");
      33       32486 :   return params;
      34           0 : }
      35             : 
      36        1975 : FullSolveMultiApp::FullSolveMultiApp(const InputParameters & parameters)
      37        1975 :   : MultiApp(parameters), _ignore_diverge(getParam<bool>("ignore_solve_not_converge"))
      38             : {
      39             :   // You could end up with some dirty hidden behavior if you do this. We could remove this check,
      40             :   // but I don't think that it's sane to do so.
      41        1975 :   if (_no_restore && (_app.isRecovering() || _app.isRestarting()))
      42           0 :     paramError("no_restore",
      43             :                "The parent app is restarting or recovering, restoration cannot be disabled");
      44        1975 : }
      45             : 
      46             : void
      47        1211 : FullSolveMultiApp::restore(bool force)
      48             : {
      49        1211 :   if (!_no_restore)
      50         781 :     MultiApp::restore(force);
      51        1207 : }
      52             : 
      53             : void
      54        1863 : FullSolveMultiApp::initialSetup()
      55             : {
      56        1863 :   MultiApp::initialSetup();
      57             : 
      58        1863 :   if (_has_an_app)
      59             :   {
      60        1863 :     Moose::ScopedCommSwapper swapper(_my_comm);
      61             : 
      62        1863 :     _executioners.resize(_my_num_apps);
      63             : 
      64             :     // Grab Executioner from each app
      65        5064 :     for (unsigned int i = 0; i < _my_num_apps; i++)
      66             :     {
      67        3205 :       auto & app = _apps[i];
      68        3205 :       Executioner * ex = app->getExecutioner();
      69             : 
      70        3205 :       if (!ex)
      71           0 :         mooseError("Executioner does not exist!");
      72             : 
      73        3205 :       if (_ignore_diverge)
      74             :       {
      75          16 :         TransientBase * tex = dynamic_cast<TransientBase *>(ex);
      76          16 :         if (tex && tex->parameters().get<bool>("error_on_dtmin"))
      77           4 :           mooseError("Requesting to ignore failed solutions, but 'Executioner/error_on_dtmin' is "
      78             :                      "true in sub-application. Set this parameter to false in sub-application to "
      79             :                      "avoid an error if Transient solve fails.");
      80             :       }
      81             : 
      82        3201 :       ex->init();
      83             : 
      84        3201 :       _executioners[i] = ex;
      85             :     }
      86        1859 :   }
      87        1859 : }
      88             : 
      89             : bool
      90        2955 : FullSolveMultiApp::solveStep(Real /*dt*/, Real /*target_time*/, bool auto_advance)
      91             : {
      92        2955 :   if (!auto_advance)
      93           0 :     mooseError("FullSolveMultiApp is not compatible with auto_advance=false");
      94             : 
      95        2955 :   if (!_has_an_app)
      96           0 :     return true;
      97             : 
      98        2955 :   TIME_SECTION(_solve_step_timer);
      99             : 
     100        2955 :   Moose::ScopedCommSwapper swapper(_my_comm);
     101             : 
     102             :   int rank;
     103             :   int ierr;
     104        2955 :   ierr = MPI_Comm_rank(_communicator.get(), &rank);
     105        2955 :   mooseCheckMPIErr(ierr);
     106             : 
     107        2955 :   bool last_solve_converged = true;
     108        7021 :   for (unsigned int i = 0; i < _my_num_apps; i++)
     109             :   {
     110             :     // reset output system if desired
     111        4074 :     if (!getParam<bool>("keep_full_output_history"))
     112        3814 :       _apps[i]->getOutputWarehouse().reset();
     113             : 
     114        4074 :     Executioner * ex = _executioners[i];
     115        4074 :     ex->execute();
     116             : 
     117        4066 :     last_solve_converged = last_solve_converged && ex->lastSolveConverged();
     118             : 
     119        4066 :     showStatusMessage(i);
     120             :   }
     121             : 
     122        2947 :   return last_solve_converged || _ignore_diverge;
     123        2947 : }
     124             : 
     125             : void
     126        4066 : FullSolveMultiApp::showStatusMessage(unsigned int i) const
     127             : {
     128        7953 :   if (!_fe_problem.verboseMultiApps() &&
     129        7953 :       _apps[i]->getOutputWarehouse().getOutputs<Console>().size() > 0)
     130        3887 :     return;
     131         179 :   else if (!_executioners[i]->lastSolveConverged())
     132           0 :     _console << COLOR_RED << "Subapp " << _apps[i]->name() << " solve Did NOT Converge!"
     133           0 :              << COLOR_DEFAULT << std::endl;
     134             :   else
     135         179 :     _console << COLOR_GREEN << "Subapp " << _apps[i]->name() << " solve converged!" << COLOR_DEFAULT
     136         179 :              << std::endl;
     137             : }

Generated by: LCOV version 1.14