LCOV - code coverage report
Current view: top level - src/systems - SolverSystem.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 89 102 87.3 %
Date: 2026-05-29 20:35:17 Functions: 14 15 93.3 %
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 "SolverSystem.h"
      11             : #include "SolutionInvalidity.h"
      12             : #include "FEProblemBase.h"
      13             : #include "TimeIntegrator.h"
      14             : #include "MooseUtils.h"
      15             : 
      16             : using namespace libMesh;
      17             : 
      18       61914 : SolverSystem::SolverSystem(SubProblem & subproblem,
      19             :                            FEProblemBase & fe_problem,
      20             :                            const std::string & name,
      21       61914 :                            Moose::VarKindType var_kind)
      22             :   : SystemBase(subproblem, fe_problem, name, var_kind),
      23       61914 :     _current_solution(nullptr),
      24       61914 :     _pc_side(Moose::PCS_DEFAULT),
      25       61914 :     _ksp_norm(Moose::KSPN_UNPRECONDITIONED)
      26             : {
      27       61914 : }
      28             : 
      29       58810 : SolverSystem::~SolverSystem() = default;
      30             : 
      31             : void
      32       60128 : SolverSystem::preInit()
      33             : {
      34       60128 :   SystemBase::preInit();
      35             : 
      36       60128 :   _current_solution = system().current_local_solution.get();
      37             : 
      38       60128 :   if (_serialized_solution.get())
      39          36 :     _serialized_solution->init(system().n_dofs(), false, SERIAL);
      40       60128 : }
      41             : 
      42             : void
      43        3297 : SolverSystem::restoreSolutions()
      44             : {
      45             :   // call parent
      46        3297 :   SystemBase::restoreSolutions();
      47             :   // and update _current_solution
      48        3297 :   _current_solution = system().current_local_solution.get();
      49        3297 : }
      50             : 
      51             : void
      52        3735 : SolverSystem::serializeSolution()
      53             : {
      54        3735 :   if (_serialized_solution.get())
      55             :   {
      56        3735 :     if (!_serialized_solution->initialized() || _serialized_solution->size() != system().n_dofs())
      57             :     {
      58          58 :       _serialized_solution->clear();
      59          58 :       _serialized_solution->init(system().n_dofs(), false, SERIAL);
      60             :     }
      61             : 
      62        3735 :     _current_solution->localize(*_serialized_solution);
      63             :   }
      64        3735 : }
      65             : 
      66             : void
      67     3618730 : SolverSystem::setSolution(const NumericVector<Number> & soln)
      68             : {
      69     3618730 :   _current_solution = &soln;
      70             : 
      71     3618730 :   auto tag = _subproblem.getVectorTagID(Moose::SOLUTION_TAG);
      72     3618730 :   associateVectorToTag(const_cast<NumericVector<Number> &>(soln), tag);
      73             : 
      74     3618730 :   if (_serialized_solution.get())
      75        3735 :     serializeSolution();
      76     3618730 : }
      77             : 
      78             : void
      79       21100 : SolverSystem::setFixedPointRelaxationFactor(const Real relaxation_factor)
      80             : {
      81       21100 :   _fixed_point_relaxation_factor = relaxation_factor;
      82       21100 : }
      83             : 
      84             : void
      85       21100 : SolverSystem::clearFixedPointRelaxation()
      86             : {
      87       21100 :   _fixed_point_relaxation_factor = 1.0;
      88       21100 : }
      89             : 
      90             : void
      91       21100 : SolverSystem::saveOldSolutionForFixedPointRelaxation()
      92             : {
      93       21100 :   if (MooseUtils::absoluteFuzzyEqual(_fixed_point_relaxation_factor, 1.0))
      94           0 :     return;
      95             : 
      96       21100 :   if (!hasSolutionState(1, Moose::SolutionIterationType::FixedPoint))
      97         225 :     needSolutionState(1, Moose::SolutionIterationType::FixedPoint, solution().type());
      98             : 
      99             :   // Just in case checking if someone already allocated one which does not match
     100             :   mooseAssert(solutionStateParallelType(1, Moose::SolutionIterationType::FixedPoint) ==
     101             :                   solution().type(),
     102             :               "Fixed point relaxation requires the previous fixed point solution state to have "
     103             :               "the same parallel type as the system solution.");
     104             : 
     105       21100 :   solutionState(1, Moose::SolutionIterationType::FixedPoint) = solution();
     106             : }
     107             : 
     108             : void
     109       21100 : SolverSystem::applyFixedPointRelaxation()
     110             : {
     111       21100 :   if (MooseUtils::absoluteFuzzyEqual(_fixed_point_relaxation_factor, 1.0))
     112           0 :     return;
     113             : 
     114             :   mooseAssert(hasSolutionState(1, Moose::SolutionIterationType::FixedPoint),
     115             :               "Fixed point relaxation was requested but the old fixed point solution was not "
     116             :               "saved.");
     117             : 
     118             :   // This might be paranoid but who knows, maybe someone requests nonghosted
     119             :   mooseAssert(solutionStateParallelType(1, Moose::SolutionIterationType::FixedPoint) ==
     120             :                   solution().type(),
     121             :               "Fixed point relaxation requires the previous fixed point solution state to have "
     122             :               "the same parallel type as the system solution.");
     123             : 
     124       21100 :   auto & sol = solution();
     125       21100 :   sol.scale(_fixed_point_relaxation_factor);
     126       42200 :   sol.add(1.0 - _fixed_point_relaxation_factor,
     127       21100 :           solutionState(1, Moose::SolutionIterationType::FixedPoint));
     128       21100 :   sol.close();
     129       21100 :   update();
     130             : }
     131             : 
     132             : void
     133       13141 : SolverSystem::setPCSide(MooseEnum pcs)
     134             : {
     135       13141 :   if (pcs == "left")
     136           0 :     _pc_side = Moose::PCS_LEFT;
     137       13141 :   else if (pcs == "right")
     138           0 :     _pc_side = Moose::PCS_RIGHT;
     139       13141 :   else if (pcs == "symmetric")
     140           0 :     _pc_side = Moose::PCS_SYMMETRIC;
     141       13141 :   else if (pcs == "default")
     142       13141 :     _pc_side = Moose::PCS_DEFAULT;
     143             :   else
     144           0 :     mooseError("Unknown PC side specified.");
     145       13141 : }
     146             : 
     147             : void
     148       13141 : SolverSystem::setMooseKSPNormType(MooseEnum kspnorm)
     149             : {
     150       13141 :   if (kspnorm == "none")
     151           0 :     _ksp_norm = Moose::KSPN_NONE;
     152       13141 :   else if (kspnorm == "preconditioned")
     153           0 :     _ksp_norm = Moose::KSPN_PRECONDITIONED;
     154       13141 :   else if (kspnorm == "unpreconditioned")
     155       13141 :     _ksp_norm = Moose::KSPN_UNPRECONDITIONED;
     156           0 :   else if (kspnorm == "natural")
     157           0 :     _ksp_norm = Moose::KSPN_NATURAL;
     158           0 :   else if (kspnorm == "default")
     159           0 :     _ksp_norm = Moose::KSPN_DEFAULT;
     160             :   else
     161           0 :     mooseError("Unknown ksp norm type specified.");
     162       13141 : }
     163             : 
     164             : void
     165      313739 : SolverSystem::checkInvalidSolution()
     166             : {
     167      313739 :   auto & solution_invalidity = _app.solutionInvalidity();
     168             : 
     169             :   // sync all solution invalid counts to rank 0 process
     170      313739 :   solution_invalidity.syncIteration();
     171             : 
     172      313739 :   if (solution_invalidity.hasInvalidSolution())
     173             :   {
     174         626 :     if (_fe_problem.acceptInvalidSolution())
     175         164 :       if (_fe_problem.showInvalidSolutionConsole())
     176         161 :         solution_invalidity.print(_console);
     177             :       else
     178           3 :         mooseWarning("The Solution Invalidity warnings are detected but silenced! "
     179             :                      "Use Problem/show_invalid_solution_console=true to show solution counts");
     180             :     else
     181             :       // output the occurrence of solution invalid in a summary table
     182         462 :       if (_fe_problem.showInvalidSolutionConsole())
     183         462 :         solution_invalidity.print(_console);
     184             :   }
     185      313736 : }
     186             : 
     187             : void
     188     5923690 : SolverSystem::compute(const ExecFlagType type)
     189             : {
     190             :   // Let's try not to overcompute
     191     5923690 :   bool compute_tds = false;
     192     5923690 :   if (type == EXEC_LINEAR)
     193     3134946 :     compute_tds = true;
     194     2788744 :   else if (type == EXEC_NONLINEAR)
     195             :   {
     196      488812 :     if (_fe_problem.computingScalingJacobian() || matrixFromColoring())
     197         654 :       compute_tds = true;
     198             :   }
     199     2299932 :   else if ((type == EXEC_TIMESTEP_END) || (type == EXEC_FINAL))
     200             :   {
     201      365399 :     if (_fe_problem.solverParams(number())._type == Moose::ST_LINEAR)
     202             :       // We likely don't have a final residual evaluation upon which we compute the time derivatives
     203             :       // so we need to do so now
     204       10800 :       compute_tds = true;
     205             :   }
     206             : 
     207             :   // avoid division by dt which might be zero.
     208     5923690 :   if (compute_tds && _fe_problem.dt() > 0.)
     209     5454662 :     for (auto & ti : _time_integrators)
     210             :     {
     211             :       // Do things like compute integration weights
     212     2725461 :       ti->preStep();
     213     2725461 :       ti->computeTimeDerivatives();
     214             :     }
     215     5923690 : }

Generated by: LCOV version 1.14