LCOV - code coverage report
Current view: top level - src/executioners - EigenExecutionerBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 296 319 92.8 %
Date: 2025-07-17 01:28:37 Functions: 15 16 93.8 %
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 "EigenExecutionerBase.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "AuxiliarySystem.h"
      14             : #include "DisplacedProblem.h"
      15             : #include "FEProblem.h"
      16             : #include "MooseApp.h"
      17             : #include "MooseEigenSystem.h"
      18             : #include "UserObject.h"
      19             : 
      20             : InputParameters
      21       28742 : EigenExecutionerBase::validParams()
      22             : {
      23       28742 :   InputParameters params = Executioner::validParams();
      24       28742 :   params.addClassDescription("Executioner for eigenvalue problems.");
      25             : 
      26       28742 :   params += FEProblemSolve::validParams();
      27             : 
      28       28742 :   params.addRequiredParam<PostprocessorName>("bx_norm", "To evaluate |Bx| for the eigenvalue");
      29       28742 :   params.addParam<PostprocessorName>("normalization", "To evaluate |x| for normalization");
      30       28742 :   params.addParam<Real>("normal_factor", "Normalize x to make |x| equal to this factor");
      31       86226 :   params.addParam<bool>(
      32       57484 :       "output_before_normalization", true, "True to output a step before normalization");
      33       28742 :   params.addParam<bool>("auto_initialization", true, "True to ask the solver to set initial");
      34       28742 :   params.addParam<Real>("time", 0.0, "System time");
      35             : 
      36       28742 :   params.addPrivateParam<bool>("_eigen", true);
      37             : 
      38       28742 :   params.addParamNamesToGroup("normalization normal_factor output_before_normalization",
      39             :                               "Normalization");
      40       28742 :   params.addParamNamesToGroup("auto_initialization time", "Advanced");
      41             : 
      42       28742 :   params.addParam<Real>("k0", 1.0, "Initial guess of the eigenvalue");
      43             : 
      44       28742 :   params.addPrivateParam<bool>("_eigen", true);
      45             : 
      46       28742 :   return params;
      47           0 : }
      48             : 
      49             : const Real &
      50         156 : EigenExecutionerBase::eigenvalueOld()
      51             : {
      52         156 :   return _source_integral_old;
      53             : }
      54             : 
      55         106 : EigenExecutionerBase::EigenExecutionerBase(const InputParameters & parameters)
      56             :   : Executioner(parameters),
      57         106 :     _problem(_fe_problem),
      58         212 :     _eigen_sys(static_cast<MooseEigenSystem &>(_problem.getNonlinearSystemBase(/*nl_sys=*/0))),
      59         106 :     _feproblem_solve(*this),
      60         106 :     _eigenvalue(addAttributeReporter("eigenvalue", getParam<Real>("k0"))),
      61         106 :     _source_integral(getPostprocessorValue("bx_norm")),
      62         106 :     _source_integral_old(1),
      63         212 :     _normalization(isParamValid("normalization")
      64         140 :                        ? getPostprocessorValue("normalization")
      65         318 :                        : getPostprocessorValue("bx_norm")) // use |Bx| for normalization by default
      66             : {
      67             :   // FIXME: currently we have to use old and older solution vectors for power iteration.
      68             :   //       We will need 'step' in the future.
      69         106 :   _problem.transient(true);
      70         106 :   _eigen_sys.needSolutionState(2);
      71         106 :   _fe_problem.getAuxiliarySystem().needSolutionState(2);
      72             : 
      73             :   // we want to tell the App about what our system time is (in case anyone else is interested).
      74         106 :   Real system_time = getParam<Real>("time");
      75         106 :   _app.setStartTime(system_time);
      76             : 
      77             :   // set the system time
      78         106 :   _problem.time() = system_time;
      79         106 :   _problem.timeOld() = system_time;
      80             : 
      81             :   // used for controlling screen print-out
      82         106 :   _problem.timeStep() = 0;
      83         106 :   _problem.dt() = 1.0;
      84         106 : }
      85             : 
      86             : void
      87         105 : EigenExecutionerBase::init()
      88             : {
      89         105 :   checkIntegrity();
      90         105 :   _eigen_sys.buildSystemDoFIndices(MooseEigenSystem::EIGEN);
      91             : 
      92         105 :   if (getParam<bool>("auto_initialization"))
      93             :   {
      94             :     // Initialize the solution of the eigen variables
      95             :     // Note: initial conditions will override this if there is any by _problem.initialSetup()
      96          95 :     _eigen_sys.initSystemSolution(MooseEigenSystem::EIGEN, 1.0);
      97             :   }
      98         105 :   _problem.initialSetup();
      99         105 :   _eigen_sys.initSystemSolutionOld(MooseEigenSystem::EIGEN, 0.0);
     100             : 
     101             :   // check when the postprocessors are evaluated
     102             :   const ExecFlagEnum & bx_exec =
     103         105 :       _problem.getUserObject<UserObject>(getParam<PostprocessorName>("bx_norm")).getExecuteOnEnum();
     104         105 :   if (!bx_exec.isValueSet(EXEC_LINEAR))
     105           0 :     mooseError("Postprocessor " + getParam<PostprocessorName>("bx_norm") +
     106             :                " requires execute_on = 'linear'");
     107             : 
     108         105 :   if (isParamValid("normalization"))
     109          68 :     _norm_exec = _problem.getUserObject<UserObject>(getParam<PostprocessorName>("normalization"))
     110          34 :                      .getExecuteOnEnum();
     111             :   else
     112          71 :     _norm_exec = bx_exec;
     113             : 
     114             :   // check if _source_integral has been evaluated during initialSetup()
     115         105 :   if (!bx_exec.isValueSet(EXEC_INITIAL))
     116         105 :     _problem.execute(EXEC_LINEAR);
     117             : 
     118         105 :   if (_source_integral == 0.0)
     119           0 :     mooseError("|Bx| = 0!");
     120             : 
     121             :   // normalize solution to make |Bx|=_eigenvalue, _eigenvalue at this point has the initialized
     122             :   // value
     123         105 :   makeBXConsistent(_eigenvalue);
     124             : 
     125         105 :   if (_problem.getDisplacedProblem() != NULL)
     126          10 :     _problem.getDisplacedProblem()->syncSolutions();
     127             : 
     128             :   /* a time step check point */
     129         105 :   _problem.onTimestepEnd();
     130         105 : }
     131             : 
     132             : void
     133         305 : EigenExecutionerBase::makeBXConsistent(Real k)
     134             : {
     135         305 :   Real consistency_tolerance = 1e-10;
     136             : 
     137             :   // Scale the solution so that the postprocessor is equal to k.
     138             :   // Note: all dependent objects of k must be evaluated on linear!
     139             :   // We have a fix point loop here, in case the postprocessor is a nonlinear function of the scaling
     140             :   // factor.
     141             :   // FIXME: We have assumed this loop always converges.
     142         390 :   while (std::fabs(k - _source_integral) > consistency_tolerance * std::fabs(k))
     143             :   {
     144             :     // On the first time entering, the _source_integral has been updated properly in
     145             :     // FEProblemBase::initialSetup()
     146          85 :     _eigen_sys.scaleSystemSolution(MooseEigenSystem::EIGEN, k / _source_integral);
     147          85 :     _problem.execute(EXEC_LINEAR);
     148          85 :     std::stringstream ss;
     149          85 :     ss << std::fixed << std::setprecision(10) << _source_integral;
     150          85 :     _console << "\n|Bx| = " << ss.str() << std::endl;
     151          85 :   }
     152         305 : }
     153             : 
     154             : void
     155         105 : EigenExecutionerBase::checkIntegrity()
     156             : {
     157             :   // check to make sure that we don't have any time kernels in this simulation
     158         105 :   if (_eigen_sys.containsTimeKernel())
     159           0 :     mooseError("You have specified time kernels in your steady state eigenvalue simulation");
     160         105 :   if (!_eigen_sys.containsEigenKernel())
     161           0 :     mooseError("You have not specified any eigen kernels in your eigenvalue simulation");
     162         105 : }
     163             : 
     164             : bool
     165         105 : EigenExecutionerBase::inversePowerIteration(unsigned int min_iter,
     166             :                                             unsigned int max_iter,
     167             :                                             Real l_rtol,
     168             :                                             bool cheb_on,
     169             :                                             Real tol_eig,
     170             :                                             bool echo,
     171             :                                             PostprocessorName xdiff,
     172             :                                             Real tol_x,
     173             :                                             Real & k,
     174             :                                             Real & initial_res)
     175             : {
     176             :   mooseAssert(max_iter >= min_iter,
     177             :               "Maximum number of power iterations must be greater than or equal to its minimum");
     178             :   mooseAssert(l_rtol > 0.0, "Invaid linear convergence tolerance");
     179             :   mooseAssert(tol_eig > 0.0, "Invalid eigenvalue tolerance");
     180             :   mooseAssert(tol_x > 0.0, "Invalid solution norm tolerance");
     181             : 
     182             :   // obtain the solution diff
     183         105 :   const PostprocessorValue * solution_diff = NULL;
     184         105 :   if (!xdiff.empty())
     185             :   {
     186          10 :     solution_diff = &_problem.getPostprocessorValueByName(xdiff);
     187          10 :     const ExecFlagEnum & xdiff_exec = _problem.getUserObject<UserObject>(xdiff).getExecuteOnEnum();
     188          10 :     if (!xdiff_exec.isValueSet(EXEC_LINEAR))
     189           0 :       mooseError("Postprocessor " + xdiff + " requires execute_on = 'linear'");
     190             :   }
     191             : 
     192             :   // not perform any iteration when max_iter==0
     193         105 :   if (max_iter == 0)
     194           0 :     return true;
     195             : 
     196             :   // turn off nonlinear flag so that RHS kernels opterate on previous solutions
     197         105 :   _eigen_sys.eigenKernelOnOld();
     198             : 
     199             :   // FIXME: currently power iteration use old and older solutions,
     200             :   // so save old and older solutions before they are changed by the power iteration
     201         105 :   _problem.saveOldSolutions();
     202         105 :   if (_problem.getDisplacedProblem() != NULL)
     203          10 :     _problem.getDisplacedProblem()->saveOldSolutions();
     204             : 
     205             :   // save solver control parameters to be modified by the power iteration
     206         105 :   Real tol1 = _problem.es().parameters.get<Real>("linear solver tolerance");
     207             :   unsigned int num1 =
     208         105 :       _problem.es().parameters.get<unsigned int>("nonlinear solver maximum iterations");
     209         105 :   Real tol2 = _problem.es().parameters.get<Real>("nonlinear solver relative residual tolerance");
     210             : 
     211             :   // every power iteration is a linear solve, so set nonlinear iteration number to one
     212         105 :   _problem.es().parameters.set<Real>("linear solver tolerance") = l_rtol;
     213             :   // disable nonlinear convergence check
     214         105 :   _problem.es().parameters.set<unsigned int>("nonlinear solver maximum iterations") = 1;
     215         105 :   _problem.es().parameters.set<Real>("nonlinear solver relative residual tolerance") = 1 - 1e-8;
     216             : 
     217         105 :   if (echo)
     218             :   {
     219         105 :     _console << '\n';
     220         105 :     _console << " Power iterations starts\n";
     221         105 :     _console << " ________________________________________________________________________________ "
     222         105 :              << std::endl;
     223             :   }
     224             : 
     225             :   // some iteration variables
     226         105 :   Chebyshev_Parameters chebyshev_parameters;
     227             : 
     228         105 :   std::vector<Real> keff_history;
     229         105 :   std::vector<Real> diff_history;
     230             : 
     231             :   bool converged;
     232             : 
     233         105 :   unsigned int iter = 0;
     234             : 
     235             :   // power iteration loop...
     236             :   // Note: |Bx|/k will stay constant one!
     237         105 :   makeBXConsistent(k);
     238             :   while (true)
     239             :   {
     240        2514 :     if (echo)
     241        2514 :       _console << " Power iteration= " << iter << std::endl;
     242             : 
     243             :     // Important: we do not call _problem.advanceState() because we do not
     244             :     // want to overwrite the old postprocessor values and old material
     245             :     // properties in stateful materials.
     246        2514 :     _eigen_sys.copyOldSolutions();
     247        2514 :     _problem.getAuxiliarySystem().copyOldSolutions();
     248        2514 :     if (_problem.getDisplacedProblem() != NULL)
     249             :     {
     250        2162 :       _problem.getDisplacedProblem()->solverSys(_eigen_sys.number()).copyOldSolutions();
     251        2162 :       _problem.getDisplacedProblem()->auxSys().copyOldSolutions();
     252             :     }
     253             : 
     254        2514 :     Real k_old = k;
     255        2514 :     _source_integral_old = _source_integral;
     256             : 
     257        2514 :     preIteration();
     258        2514 :     _problem.solve(_eigen_sys.number());
     259        2514 :     converged = _problem.converged(_eigen_sys.number());
     260        2514 :     if (!converged)
     261           0 :       break;
     262        2514 :     postIteration();
     263             : 
     264             :     // save the initial residual
     265        2514 :     if (iter == 0)
     266         105 :       initial_res = _eigen_sys.referenceResidual();
     267             : 
     268             :     // update eigenvalue
     269        2514 :     k = k_old * _source_integral / _source_integral_old;
     270        2514 :     _eigenvalue = k;
     271             : 
     272        2514 :     if (echo)
     273             :     {
     274             :       // output on screen the convergence history only when we want to and MOOSE output system is
     275             :       // not used
     276        2514 :       keff_history.push_back(k);
     277        2514 :       if (solution_diff)
     278        2162 :         diff_history.push_back(*solution_diff);
     279             : 
     280        2514 :       std::stringstream ss;
     281        2514 :       if (solution_diff)
     282             :       {
     283        2162 :         ss << '\n';
     284        2162 :         ss << " +================+=====================+=====================+\n";
     285        2162 :         ss << " | iteration      | eigenvalue          | solution_difference |\n";
     286        2162 :         ss << " +================+=====================+=====================+\n";
     287        2162 :         unsigned int j = 0;
     288        2162 :         if (keff_history.size() > 10)
     289             :         {
     290        2062 :           ss << " :                :                     :                     :\n";
     291        2062 :           j = keff_history.size() - 10;
     292             :         }
     293       23332 :         for (; j < keff_history.size(); j++)
     294       21170 :           ss << " | " << std::setw(14) << j << " | " << std::setw(19) << std::scientific
     295       21170 :              << std::setprecision(8) << keff_history[j] << " | " << std::setw(19) << std::scientific
     296       21170 :              << std::setprecision(8) << diff_history[j] << " |\n";
     297        2162 :         ss << " +================+=====================+=====================+\n" << std::flush;
     298             :       }
     299             :       else
     300             :       {
     301         352 :         ss << '\n';
     302         352 :         ss << " +================+=====================+\n";
     303         352 :         ss << " | iteration      | eigenvalue          |\n";
     304         352 :         ss << " +================+=====================+\n";
     305         352 :         unsigned int j = 0;
     306         352 :         if (keff_history.size() > 10)
     307             :         {
     308           0 :           ss << " :                :                     :\n";
     309           0 :           j = keff_history.size() - 10;
     310             :         }
     311        1444 :         for (; j < keff_history.size(); j++)
     312        1092 :           ss << " | " << std::setw(14) << j << " | " << std::setw(19) << std::scientific
     313        1092 :              << std::setprecision(8) << keff_history[j] << " |\n";
     314         352 :         ss << " +================+=====================+\n" << std::flush;
     315         352 :         ss << std::endl;
     316             :       }
     317        2514 :       _console << ss.str();
     318        2514 :     }
     319             : 
     320             :     // increment iteration number here
     321        2514 :     iter++;
     322             : 
     323        2514 :     if (cheb_on)
     324             :     {
     325        2162 :       chebyshev(chebyshev_parameters, iter, solution_diff);
     326        2162 :       if (echo)
     327        2162 :         _console << " Chebyshev step: " << chebyshev_parameters.icheb << std::endl;
     328             :     }
     329             : 
     330        2514 :     if (echo)
     331             :       _console
     332        2514 :           << " ________________________________________________________________________________ "
     333        2514 :           << std::endl;
     334             : 
     335             :     // not perform any convergence check when number of iterations is less than min_iter
     336        2514 :     if (iter >= min_iter)
     337             :     {
     338             :       // no need to check convergence of the last iteration
     339        2157 :       if (iter != max_iter)
     340             :       {
     341        2062 :         Real keff_error = fabs(k_old - k) / k;
     342        2062 :         if (keff_error > tol_eig)
     343        2052 :           converged = false;
     344        2062 :         if (solution_diff)
     345        2062 :           if (*solution_diff > tol_x)
     346           0 :             converged = false;
     347        2062 :         if (converged)
     348          10 :           break;
     349             :       }
     350             :       else
     351             :       {
     352          95 :         converged = false;
     353          95 :         break;
     354             :       }
     355             :     }
     356        2409 :   }
     357             : 
     358             :   // restore parameters changed by the executioner
     359         105 :   _problem.es().parameters.set<Real>("linear solver tolerance") = tol1;
     360         105 :   _problem.es().parameters.set<unsigned int>("nonlinear solver maximum iterations") = num1;
     361         105 :   _problem.es().parameters.set<Real>("nonlinear solver relative residual tolerance") = tol2;
     362             : 
     363             :   // FIXME: currently power iteration use old and older solutions, so restore them
     364         105 :   _problem.restoreOldSolutions();
     365         105 :   if (_problem.getDisplacedProblem() != NULL)
     366          10 :     _problem.getDisplacedProblem()->restoreOldSolutions();
     367             : 
     368         105 :   return converged;
     369         105 : }
     370             : 
     371             : void
     372        2514 : EigenExecutionerBase::preIteration()
     373             : {
     374        2514 : }
     375             : 
     376             : void
     377        2514 : EigenExecutionerBase::postIteration()
     378             : {
     379        2514 : }
     380             : 
     381             : void
     382         105 : EigenExecutionerBase::postExecute()
     383             : {
     384         105 :   if (getParam<bool>("output_before_normalization"))
     385             :   {
     386          95 :     _problem.timeStep()++;
     387          95 :     Real t = _problem.time();
     388          95 :     _problem.time() = _problem.timeStep();
     389          95 :     _problem.outputStep(EXEC_TIMESTEP_END);
     390          95 :     _problem.time() = t;
     391             :   }
     392             : 
     393         105 :   Real s = 1.0;
     394         105 :   if (_norm_exec.isValueSet(EXEC_CUSTOM))
     395             :   {
     396           0 :     _console << " Cannot let the normalization postprocessor on custom.\n";
     397           0 :     _console << " Normalization is abandoned!" << std::endl;
     398             :   }
     399             :   else
     400             :   {
     401         105 :     bool force = _norm_exec.isValueSet(EXEC_TIMESTEP_END) || _norm_exec.isValueSet(EXEC_LINEAR);
     402         105 :     s = normalizeSolution(force);
     403         105 :     if (!MooseUtils::absoluteFuzzyEqual(s, 1.0))
     404          24 :       _console << " Solution is rescaled with factor " << s << " for normalization!" << std::endl;
     405             :   }
     406             : 
     407         105 :   if ((!getParam<bool>("output_before_normalization")) || !MooseUtils::absoluteFuzzyEqual(s, 1.0))
     408             :   {
     409          24 :     _problem.timeStep()++;
     410          24 :     Real t = _problem.time();
     411          24 :     _problem.time() = _problem.timeStep();
     412          24 :     _problem.outputStep(EXEC_TIMESTEP_END);
     413          24 :     _problem.time() = t;
     414             :   }
     415             : 
     416             :   {
     417         105 :     TIME_SECTION("final", 1, "Executing Final Objects")
     418         105 :     _problem.execMultiApps(EXEC_FINAL);
     419         105 :     _problem.execute(EXEC_FINAL);
     420         105 :     _problem.outputStep(EXEC_FINAL);
     421         105 :   }
     422         105 : }
     423             : 
     424             : Real
     425         105 : EigenExecutionerBase::normalizeSolution(bool force)
     426             : {
     427         105 :   if (force)
     428         105 :     _problem.execute(EXEC_INITIAL);
     429             : 
     430             :   Real factor;
     431         105 :   if (isParamValid("normal_factor"))
     432          24 :     factor = getParam<Real>("normal_factor");
     433             :   else
     434          81 :     factor = _eigenvalue;
     435         105 :   Real scaling = factor / _normalization;
     436             : 
     437         105 :   if (!MooseUtils::absoluteFuzzyEqual(scaling, 1.0))
     438             :   {
     439             :     // FIXME: we assume linear scaling here!
     440          24 :     _eigen_sys.scaleSystemSolution(MooseEigenSystem::EIGEN, scaling);
     441             :     // update all aux variables and user objects
     442             : 
     443         648 :     for (const ExecFlagType & flag : _app.getExecuteOnEnum().items())
     444         624 :       _problem.execute(flag);
     445             :   }
     446         105 :   return scaling;
     447             : }
     448             : 
     449             : void
     450         105 : EigenExecutionerBase::printEigenvalue()
     451             : {
     452         105 :   std::ostringstream ss;
     453         105 :   ss << '\n';
     454         105 :   ss << "*******************************************************\n";
     455         105 :   ss << " Eigenvalue = " << std::fixed << std::setprecision(10) << _eigenvalue << '\n';
     456         105 :   ss << "*******************************************************";
     457             : 
     458         105 :   _console << ss.str() << std::endl;
     459         105 : }
     460             : 
     461         105 : EigenExecutionerBase::Chebyshev_Parameters::Chebyshev_Parameters()
     462         105 :   : n_iter(50), fsmooth(2), finit(6), lgac(0), icheb(0), flux_error_norm_old(1), icho(0)
     463             : {
     464         105 : }
     465             : 
     466             : void
     467           0 : EigenExecutionerBase::Chebyshev_Parameters::reinit()
     468             : {
     469           0 :   finit = 6;
     470           0 :   lgac = 0;
     471           0 :   icheb = 0;
     472           0 :   flux_error_norm_old = 1;
     473           0 :   icho = 0;
     474           0 : }
     475             : 
     476             : void
     477        2162 : EigenExecutionerBase::chebyshev(Chebyshev_Parameters & chebyshev_parameters,
     478             :                                 unsigned int iter,
     479             :                                 const PostprocessorValue * solution_diff)
     480             : {
     481        2162 :   if (!solution_diff)
     482           0 :     mooseError("solution diff is required for Chebyshev acceleration");
     483             : 
     484        2162 :   if (chebyshev_parameters.lgac == 0)
     485             :   {
     486         274 :     if (chebyshev_parameters.icho == 0)
     487          70 :       chebyshev_parameters.ratio = *solution_diff / chebyshev_parameters.flux_error_norm_old;
     488             :     else
     489             :     {
     490         204 :       chebyshev_parameters.ratio = chebyshev_parameters.ratio_new;
     491         204 :       chebyshev_parameters.icho = 0;
     492             :     }
     493             : 
     494         274 :     if (iter > chebyshev_parameters.finit && chebyshev_parameters.ratio >= 0.4 &&
     495         214 :         chebyshev_parameters.ratio <= 1)
     496             :     {
     497         214 :       chebyshev_parameters.lgac = 1;
     498         214 :       chebyshev_parameters.icheb = 1;
     499         214 :       chebyshev_parameters.error_begin = *solution_diff;
     500         214 :       chebyshev_parameters.iter_begin = iter;
     501         214 :       double alp = 2 / (2 - chebyshev_parameters.ratio);
     502         214 :       std::vector<double> coef(2);
     503         214 :       coef[0] = alp;
     504         214 :       coef[1] = 1 - alp;
     505         214 :       _eigen_sys.combineSystemSolution(MooseEigenSystem::EIGEN, coef);
     506         214 :       _problem.execute(EXEC_LINEAR);
     507         214 :       _eigenvalue = _source_integral;
     508         214 :     }
     509             :   }
     510             :   else
     511             :   {
     512        1888 :     chebyshev_parameters.icheb++;
     513        1888 :     double gamma = acosh(2 / chebyshev_parameters.ratio - 1);
     514        1888 :     double alp = 4 / chebyshev_parameters.ratio *
     515        1888 :                  std::cosh((chebyshev_parameters.icheb - 1) * gamma) /
     516        1888 :                  std::cosh(chebyshev_parameters.icheb * gamma);
     517        1888 :     double beta = (1 - chebyshev_parameters.ratio / 2) * alp - 1;
     518             :     /*  if (iter<int(chebyshev_parameters.iter_begin+chebyshev_parameters.n_iter))
     519             :         {
     520             :           std::vector<double> coef(3);
     521             :           coef[0] = alp;
     522             :           coef[1] = 1-alp+beta;
     523             :           coef[2] = -beta;
     524             :           _eigen_sys.combineSystemSolution(NonlinearSystem::EIGEN, coef);
     525             :         }
     526             :         else
     527             :         {*/
     528             :     double gamma_new =
     529        1888 :         (*solution_diff / chebyshev_parameters.error_begin) *
     530        1888 :         (std::cosh((chebyshev_parameters.icheb - 1) * acosh(2 / chebyshev_parameters.ratio - 1)));
     531        1888 :     if (gamma_new < 1.0)
     532         850 :       gamma_new = 1.0;
     533             : 
     534        1888 :     chebyshev_parameters.ratio_new =
     535        1888 :         chebyshev_parameters.ratio / 2 *
     536        1888 :         (std::cosh(acosh(gamma_new) / (chebyshev_parameters.icheb - 1)) + 1);
     537        1888 :     if (gamma_new > 1.01)
     538             :     {
     539         210 :       chebyshev_parameters.lgac = 0;
     540             :       //      chebyshev_parameters.icheb = 0;
     541             :       //      if (chebyshev_parameters.icheb>30)
     542             :       //      {
     543         210 :       if (chebyshev_parameters.icheb > 0)
     544             :       {
     545         210 :         chebyshev_parameters.icho = 1;
     546         210 :         chebyshev_parameters.finit = iter;
     547             :       }
     548             :       else
     549             :       {
     550           0 :         chebyshev_parameters.icho = 0;
     551           0 :         chebyshev_parameters.finit = iter + chebyshev_parameters.fsmooth;
     552             :       }
     553             :     }
     554             :     else
     555             :     {
     556        1678 :       std::vector<double> coef(3);
     557        1678 :       coef[0] = alp;
     558        1678 :       coef[1] = 1 - alp + beta;
     559        1678 :       coef[2] = -beta;
     560        1678 :       _eigen_sys.combineSystemSolution(MooseEigenSystem::EIGEN, coef);
     561        1678 :       _problem.execute(EXEC_LINEAR);
     562        1678 :       _eigenvalue = _source_integral;
     563        1678 :     }
     564             :     //    }
     565             :   }
     566        2162 :   chebyshev_parameters.flux_error_norm_old = *solution_diff;
     567        2162 : }
     568             : 
     569             : bool
     570          95 : EigenExecutionerBase::nonlinearSolve(Real nl_rtol, Real nl_atol, Real l_rtol, Real & k)
     571             : {
     572          95 :   makeBXConsistent(k);
     573             : 
     574             :   // turn on nonlinear flag so that eigen kernels opterate on the current solutions
     575          95 :   _eigen_sys.eigenKernelOnCurrent();
     576             : 
     577             :   // set nonlinear solver controls
     578          95 :   Real tol1 = _problem.es().parameters.get<Real>("nonlinear solver absolute residual tolerance");
     579          95 :   Real tol2 = _problem.es().parameters.get<Real>("linear solver tolerance");
     580          95 :   Real tol3 = _problem.es().parameters.get<Real>("nonlinear solver relative residual tolerance");
     581             : 
     582          95 :   _problem.es().parameters.set<Real>("nonlinear solver absolute residual tolerance") = nl_atol;
     583          95 :   _problem.es().parameters.set<Real>("nonlinear solver relative residual tolerance") = nl_rtol;
     584          95 :   _problem.es().parameters.set<Real>("linear solver tolerance") = l_rtol;
     585             : 
     586             :   // call nonlinear solve
     587          95 :   _problem.solve(_eigen_sys.number());
     588             : 
     589          95 :   k = _source_integral;
     590          95 :   _eigenvalue = k;
     591             : 
     592          95 :   _problem.es().parameters.set<Real>("nonlinear solver absolute residual tolerance") = tol1;
     593          95 :   _problem.es().parameters.set<Real>("linear solver tolerance") = tol2;
     594          95 :   _problem.es().parameters.set<Real>("nonlinear solver relative residual tolerance") = tol3;
     595             : 
     596          95 :   return _problem.converged(_eigen_sys.number());
     597             : }

Generated by: LCOV version 1.14