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 : // MOOSE includes 11 : #include "Eigenvalue.h" 12 : #include "EigenProblem.h" 13 : #include "Factory.h" 14 : #include "MooseApp.h" 15 : #include "NonlinearEigenSystem.h" 16 : 17 : registerMooseObject("MooseApp", Eigenvalue); 18 : 19 : InputParameters 20 4188 : Eigenvalue::validParams() 21 : { 22 4188 : InputParameters params = Executioner::validParams(); 23 : 24 4188 : params.addClassDescription( 25 : "Eigenvalue solves a standard/generalized linear or nonlinear eigenvalue problem"); 26 : 27 4188 : params += EigenProblemSolve::validParams(); 28 12564 : params.addParam<Real>("time", 0.0, "System time"); 29 : 30 4188 : return params; 31 0 : } 32 : 33 565 : Eigenvalue::Eigenvalue(const InputParameters & parameters) 34 : : Executioner(parameters), 35 1695 : _eigen_problem(*getCheckedPointerParam<EigenProblem *>( 36 : "_eigen_problem", "This might happen if you don't have a mesh")), 37 565 : _eigen_problem_solve(*this), 38 1124 : _system_time(getParam<Real>("time")), 39 562 : _time_step(_eigen_problem.timeStep()), 40 562 : _time(_eigen_problem.time()), 41 1689 : _final_timer(registerTimedSection("final", 1)) 42 : { 43 562 : _fixed_point_solve->setInnerSolve(_eigen_problem_solve); 44 562 : _time = _system_time; 45 562 : } 46 : 47 : #ifdef LIBMESH_HAVE_SLEPC 48 : void 49 550 : Eigenvalue::init() 50 : { 51 : // Does not allow time kernels 52 550 : checkIntegrity(); 53 : 54 : // Provide vector of ones to solver 55 : // "auto_initialization" is on by default and we init the vector values associated 56 : // with eigen-variables as ones. If "auto_initialization" is turned off by users, 57 : // it is up to users to provide an initial guess. If "auto_initialization" is off 58 : // and users does not provide an initial guess, slepc will automatically generate 59 : // a random vector as the initial guess. The motivation to offer this option is 60 : // that we have to initialize ONLY eigen variables in multiphysics simulation. 61 : // auto_initialization can be overriden by initial conditions. 62 1650 : if (getParam<bool>("auto_initialization") && !_app.isRestarting()) 63 541 : _eigen_problem.initEigenvector(1.0); 64 : 65 550 : _eigen_problem.execute(EXEC_PRE_MULTIAPP_SETUP); 66 550 : _eigen_problem.initialSetup(); 67 550 : _fixed_point_solve->initialSetup(); 68 550 : _eigen_problem_solve.initialSetup(); 69 550 : } 70 : 71 : void 72 550 : Eigenvalue::checkIntegrity() 73 : { 74 : // check to make sure that we don't have any time kernels in eigenvalue simulation 75 550 : if (_eigen_problem.getNonlinearSystemBase(/*nl_sys=*/0).containsTimeKernel()) 76 0 : mooseError("You have specified time kernels in your eigenvalue simulation"); 77 550 : } 78 : #endif 79 : 80 : void 81 658 : Eigenvalue::execute() 82 : { 83 : #ifdef LIBMESH_HAVE_SLEPC 84 : // Recovering makes sense for only transient simulations since the solution from 85 : // the previous time steps is required. 86 658 : if (_app.isRecovering()) 87 : { 88 28 : _console << "\nCannot recover eigenvalue solves!\nExiting...\n" << std::endl; 89 28 : _last_solve_converged = true; 90 28 : return; 91 : } 92 : 93 : // Outputs initial conditions set by users 94 : // It is consistent with Steady 95 630 : _time_step = 0; 96 630 : _time = _time_step; 97 630 : _eigen_problem.outputStep(EXEC_INITIAL); 98 630 : _time = _system_time; 99 : 100 630 : preExecute(); 101 : 102 : // The following code of this function is copied from "Steady" 103 : // "Eigenvalue" implementation can be considered a one-time-step simulation to 104 : // have the code compatible with the rest moose world. 105 630 : _eigen_problem.advanceState(); 106 : 107 : // First step in any eigenvalue state solve is always 1 (preserving backwards compatibility) 108 630 : _time_step = 1; 109 : 110 : #ifdef LIBMESH_ENABLE_AMR 111 : 112 : // Define the refinement loop 113 630 : auto steps = _eigen_problem.adaptivity().getSteps(); 114 1251 : for (const auto r_step : make_range(steps + 1)) 115 : { 116 : #endif // LIBMESH_ENABLE_AMR 117 630 : _eigen_problem.timestepSetup(); 118 : 119 630 : _last_solve_converged = _fixed_point_solve->solve(); 120 630 : if (!lastSolveConverged()) 121 : { 122 9 : _console << "Aborting as solve did not converge" << std::endl; 123 9 : break; 124 : } 125 : 126 : // Compute markers and indicators only when we do have at least one adaptivity step 127 621 : if (steps) 128 : { 129 0 : _eigen_problem.computeIndicators(); 130 0 : _eigen_problem.computeMarkers(); 131 : } 132 : // need to keep _time in sync with _time_step to get correct output 133 621 : _time = _time_step; 134 621 : _eigen_problem.outputStep(EXEC_TIMESTEP_END); 135 621 : _time = _system_time; 136 : 137 : #ifdef LIBMESH_ENABLE_AMR 138 621 : if (r_step < steps) 139 : { 140 0 : _eigen_problem.adaptMesh(); 141 : } 142 : 143 621 : _time_step++; 144 : } 145 : #endif 146 : 147 : { 148 630 : TIME_SECTION(_final_timer) 149 630 : _eigen_problem.execMultiApps(EXEC_FINAL); 150 630 : _eigen_problem.finalizeMultiApps(); 151 630 : _eigen_problem.postExecute(); 152 630 : _eigen_problem.execute(EXEC_FINAL); 153 630 : _time = _time_step; 154 630 : _eigen_problem.outputStep(EXEC_FINAL); 155 630 : _time = _system_time; 156 630 : } 157 : 158 630 : postExecute(); 159 : 160 : #else 161 : mooseError("SLEPc is required for eigenvalue executioner, please use --download-slepc when " 162 : "configuring PETSc "); 163 : #endif 164 : }