Loading [MathJax]/extensions/tex2jax.js
https://mooseframework.inl.gov
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
Eigenvalue.C
Go to the documentation of this file.
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 #include "PetscSupport.h"
17 #include "SlepcSupport.h"
18 #include "UserObject.h"
19 
20 #include "libmesh/petsc_solver_exception.h"
21 
22 // Needed for LIBMESH_CHECK_ERR
24 
25 registerMooseObject("MooseApp", Eigenvalue);
26 
29 {
31 
32  params.addClassDescription(
33  "Eigenvalue solves a standard/generalized linear or nonlinear eigenvalue problem");
34 
35  params += FEProblemSolve::validParams();
36  params.addParam<Real>("time", 0.0, "System time");
37 
38  // matrix_free will be an invalid for griffin once the integration is done.
39  // In this PR, we can not change it. It will still be a valid option when users
40  // use non-Newton algorithms
41  params.addParam<bool>(
42  "matrix_free",
43  false,
44  "Whether or not to use a matrix free fashion to form operators. "
45  "If true, shell matrices will be used and meanwhile a preconditioning matrix"
46  "may be formed as well.");
47 
48  params.addParam<bool>(
49  "precond_matrix_free",
50  false,
51  "Whether or not to use a matrix free fashion for forming the preconditioning matrix. "
52  "If true, a shell matrix will be used for preconditioner.");
53 
54  params.addParam<bool>("constant_matrices",
55  false,
56  "Whether or not to use constant matrices so that we can use them to form "
57  "residuals on both linear and "
58  "nonlinear iterations");
59 
60  params.addParam<bool>("precond_matrix_includes_eigen",
61  false,
62  "Whether or not to include eigen kernels in the preconditioning matrix. "
63  "If true, the preconditioning matrix will include eigen kernels.");
64 
65  params.addPrivateParam<bool>("_use_eigen_value", true);
66 
67  params.addParam<Real>("initial_eigenvalue", 1, "Initial eigenvalue");
68  params.addParam<PostprocessorName>(
69  "normalization", "Postprocessor evaluating norm of eigenvector for normalization");
70  params.addParam<Real>("normal_factor",
71  "Normalize eigenvector to make a defined norm equal to this factor");
72 
73  params.addParam<bool>("auto_initialization",
74  true,
75  "If true, we will set an initial eigen vector in moose, otherwise EPS "
76  "solver will initial eigen vector");
77 
78  params.addParamNamesToGroup("matrix_free precond_matrix_free constant_matrices "
79  "precond_matrix_includes_eigen",
80  "Matrix and Matrix-Free");
81  params.addParamNamesToGroup("initial_eigenvalue auto_initialization",
82  "Eigenvector and eigenvalue initialization");
83  params.addParamNamesToGroup("normalization normal_factor", "Solution normalization");
84 
85  // If Newton and Inverse Power is combined in SLEPc side
86  params.addPrivateParam<bool>("_newton_inverse_power", false);
87 
88 // Add slepc options and eigen problems
89 #ifdef LIBMESH_HAVE_SLEPC
91 
93 #endif
94  return params;
95 }
96 
98  : Executioner(parameters),
99  _eigen_problem(*getCheckedPointerParam<EigenProblem *>(
100  "_eigen_problem", "This might happen if you don't have a mesh")),
101  _feproblem_solve(*this),
102  _normalization(isParamValid("normalization") ? &getPostprocessorValue("normalization")
103  : nullptr),
104  _system_time(getParam<Real>("time")),
105  _time_step(_eigen_problem.timeStep()),
106  _time(_eigen_problem.time()),
107  _final_timer(registerTimedSection("final", 1))
108 {
109 // Extract and store SLEPc options
110 #ifdef LIBMESH_HAVE_SLEPC
111  mooseAssert(_fe_problem.numSolverSystems() == 1,
112  "The Eigenvalue executioner only currently supports a single solver system.");
113 
115 
118  _eigen_problem.solverParams(/*solver_sys_num=*/0)._eigen_problem_type);
119 
120  // pass two control parameters to eigen problem
121  _eigen_problem.solverParams(/*solver_sys_num=*/0)._free_power_iterations =
122  getParam<unsigned int>("free_power_iterations");
123  _eigen_problem.solverParams(/*solver_sys_num=*/0)._extra_power_iterations =
124  getParam<unsigned int>("extra_power_iterations");
125 
126  if (!isParamValid("normalization") && isParamValid("normal_factor"))
127  paramError("normal_factor",
128  "Cannot set scaling factor without defining normalization postprocessor.");
129 
130  _fixed_point_solve->setInnerSolve(_feproblem_solve);
132 
133  if (isParamValid("normalization"))
134  {
135  const auto & normpp = getParam<PostprocessorName>("normalization");
136  if (isParamValid("normal_factor"))
137  _eigen_problem.setNormalization(normpp, getParam<Real>("normal_factor"));
138  else
140  }
141 
142  _eigen_problem.setInitialEigenvalue(getParam<Real>("initial_eigenvalue"));
143 
144  // Set a flag to nonlinear eigen system
145  _eigen_problem.getNonlinearEigenSystem(/*nl_sys_num=*/0)
146  .precondMatrixIncludesEigenKernels(getParam<bool>("precond_matrix_includes_eigen"));
147 #else
148  mooseError("SLEPc is required to use Eigenvalue executioner, please use '--download-slepc in "
149  "PETSc configuration'");
150 #endif
151  // SLEPc older than 3.13.0 can not take initial guess from moose
152  // It may generate converge issues
153 #if PETSC_RELEASE_LESS_THAN(3, 13, 0)
155  "Please use SLEPc-3.13.0 or higher. Old versions of SLEPc likely produce bad convergence");
156 #endif
157 
158  // To avoid petsc unused option warnings, ensure we do not set irrelevant options.
167 }
168 
169 #ifdef LIBMESH_HAVE_SLEPC
170 void
172 {
173  if (isParamValid("normalization"))
174  {
175  const auto & normpp = getParam<PostprocessorName>("normalization");
176  const auto & exec = _eigen_problem.getUserObject<UserObject>(normpp).getExecuteOnEnum();
177  if (!exec.isValueSet(EXEC_LINEAR))
178  mooseError("Normalization postprocessor ", normpp, " requires execute_on = 'linear'");
179  }
180 
181  // Does not allow time kernels
182  checkIntegrity();
183 
184  // Provide vector of ones to solver
185  // "auto_initialization" is on by default and we init the vector values associated
186  // with eigen-variables as ones. If "auto_initialization" is turned off by users,
187  // it is up to users to provide an initial guess. If "auto_initialization" is off
188  // and users does not provide an initial guess, slepc will automatically generate
189  // a random vector as the initial guess. The motivation to offer this option is
190  // that we have to initialize ONLY eigen variables in multiphysics simulation.
191  // auto_initialization can be overriden by initial conditions.
192  if (getParam<bool>("auto_initialization") && !_app.isRestarting())
194 
195  // Some setup
198 
199  // Make sure all PETSc options are setup correctly
201 }
202 
203 void
205 {
206 #if PETSC_RELEASE_LESS_THAN(3, 12, 0)
207  // Make sure the SLEPc options are setup for this app
209  _eigen_problem, _eigen_problem.solverParams(/*eigen_sys_num=*/0), _pars);
210 #else
211  // Options need to be setup once only
213  {
214  // Parent application has the default data base
215  if (!_app.isUltimateMaster())
216  LibmeshPetscCall(PetscOptionsPush(_eigen_problem.petscOptionsDatabase()));
218  _eigen_problem, _eigen_problem.solverParams(/*eigen_sys_num=*/0), _pars);
219  if (!_app.isUltimateMaster())
220  LibmeshPetscCall(PetscOptionsPop());
222  }
223 #endif
224 }
225 
226 void
228 {
229  // check to make sure that we don't have any time kernels in eigenvalue simulation
231  mooseError("You have specified time kernels in your eigenvalue simulation");
232 }
233 
234 #endif
235 
236 void
238 {
239 #ifdef LIBMESH_HAVE_SLEPC
240  // Recovering makes sense for only transient simulations since the solution from
241  // the previous time steps is required.
242  if (_app.isRecovering())
243  {
244  _console << "\nCannot recover eigenvalue solves!\nExiting...\n" << std::endl;
245  return;
246  }
247 
248  // Outputs initial conditions set by users
249  // It is consistent with Steady
250  _time_step = 0;
251  _time = _time_step;
254 
255  preExecute();
256 
257  // The following code of this function is copied from "Steady"
258  // "Eigenvalue" implementation can be considered a one-time-step simulation to
259  // have the code compatible with the rest moose world.
261 
262  // First step in any eigenvalue state solve is always 1 (preserving backwards compatibility)
263  _time_step = 1;
264 
265 #ifdef LIBMESH_ENABLE_AMR
266 
267  // Define the refinement loop
268  auto steps = _eigen_problem.adaptivity().getSteps();
269  for (const auto r_step : make_range(steps + 1))
270  {
271 #endif // LIBMESH_ENABLE_AMR
273 
275  if (!lastSolveConverged())
276  {
277  _console << "Aborting as solve did not converge" << std::endl;
278  break;
279  }
280 
281  // Compute markers and indicators only when we do have at least one adaptivity step
282  if (steps)
283  {
286  }
287  // need to keep _time in sync with _time_step to get correct output
288  _time = _time_step;
291 
292 #ifdef LIBMESH_ENABLE_AMR
293  if (r_step < steps)
294  {
296  }
297 
298  _time_step++;
299  }
300 #endif
301 
302  {
303  TIME_SECTION(_final_timer)
308  _time = _time_step;
311  }
312 
313  postExecute();
314 
315 #else
316  mooseError("SLEPc is required for eigenvalue executioner, please use --download-slepc when "
317  "configuring PETSc ");
318 #endif
319 }
void finalizeMultiApps()
virtual void preExecute()
Override this for actions that should take place before execution.
Definition: Executioner.h:73
void timestepSetup() override
virtual bool lastSolveConverged() const override
Whether or not the last solve converged.
Definition: Eigenvalue.h:45
Moose::PetscSupport::PetscOptions & getPetscOptions()
Retrieve a writable reference the PETSc options (used by PetscSupport)
bool _eigen_matrix_free
Definition: SolverParams.h:27
bool isUltimateMaster() const
Whether or not this app is the ultimate master app.
Definition: MooseApp.h:847
static InputParameters validParams()
Constructor.
Definition: Eigenvalue.C:28
T & getUserObject(const std::string &name, unsigned int tid=0) const
Get the user object by its name.
void precondMatrixIncludesEigenKernels(bool precond_matrix_includes_eigen)
If the preconditioning matrix includes eigen kernels.
void mooseDeprecated(Args &&... args) const
virtual void init() override
Initialize the executioner.
Definition: Eigenvalue.C:171
void addPrivateParam(const std::string &name, const T &value)
These method add a parameter to the InputParameters object which can be retrieved like any other para...
Eigenvalue executioner is used to drive the eigenvalue calculations.
Definition: Eigenvalue.h:30
virtual void postExecute()
Method called at the end of the simulation.
void initEigenvector(const Real initial_value)
For nonlinear eigen solver, a good initial value can help convergence.
Definition: EigenProblem.C:420
virtual void computeMarkers()
virtual void execute(const ExecFlagType &exec_type) override
Convenience function for performing execution of MOOSE systems.
Definition: EigenProblem.C:164
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
Real & _time
Definition: Eigenvalue.h:78
const ExecFlagType EXEC_TIMESTEP_END
Definition: Moose.C:33
bool isRestarting() const
Whether or not this is a "restart" calculation.
Definition: MooseApp.C:1691
bool _last_solve_converged
Definition: Eigenvalue.h:83
bool & petscOptionsInserted()
If PETSc options are already inserted.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
virtual void advanceState()
Advance all of the state holding vectors / datastructures so that we can move to the next timestep...
virtual bool containsTimeKernel() override
If the system has a kernel that corresponds to a time derivative.
InputParameters getSlepcValidParams(InputParameters &params)
Definition: SlepcSupport.C:38
void setNormalization(const PostprocessorName &pp, const Real value=std::numeric_limits< Real >::max())
Set postprocessor and normalization factor &#39;Postprocessor&#39; is often used to compute an integral of ph...
Definition: EigenProblem.C:629
Moose::EigenProblemType _eigen_problem_type
Definition: SolverParams.h:25
static InputParameters validParams()
Definition: Executioner.C:26
virtual void execute() override
Pure virtual execute function MUST be overridden by children classes.
Definition: Eigenvalue.C:237
virtual void checkIntegrity()
Eigenvalue executioner does not allow time kernels.
Definition: Eigenvalue.C:227
Eigenvalue(const InputParameters &parameters)
Definition: Eigenvalue.C:97
void slepcSetOptions(EigenProblem &eigen_problem, SolverParams &solver_params, const InputParameters &params)
Push all SLEPc/PETSc options into SLEPc/PETSc side.
Definition: SlepcSupport.C:550
void dontAddPetscFlag(const std::string &flag, PetscOptions &petsc_options)
Function to ensure that a particular petsc option is not added to the PetscOptions storage object to ...
const ExecFlagType EXEC_PRE_MULTIAPP_SETUP
Definition: Moose.C:47
virtual void computeIndicators()
virtual void postExecute()
Override this for actions that should take place after execution.
Definition: Executioner.h:78
void initialSetup() override
Executioners are objects that do the actual work of solving your problem.
Definition: Executioner.h:30
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:84
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
const ExecFlagType EXEC_LINEAR
Definition: Moose.C:29
FEProblemSolve _feproblem_solve
inner-most solve object to perform Newton solve with SLEPc
Definition: Eigenvalue.h:71
static InputParameters validParams()
registerMooseObject("MooseApp", Eigenvalue)
NonlinearEigenSystem & getNonlinearEigenSystem(const unsigned int nl_sys_num)
Definition: EigenProblem.h:299
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
int & _time_step
Definition: Eigenvalue.h:77
PetscOptions & petscOptionsDatabase()
void prepareSolverOptions()
Prepare right petsc options.
Definition: Eigenvalue.C:204
void dontAddNonlinearConvergedReason(FEProblemBase &fe_problem)
Function to ensure that -snes_converged_reason is not added to the PetscOptions storage object to be ...
Real _system_time
Definition: Eigenvalue.h:76
unsigned int getSteps() const
Pull out the number of steps previously set by calling init()
Definition: Adaptivity.h:105
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
unsigned int _free_power_iterations
Definition: SolverParams.h:31
const InputParameters & _pars
Parameters of this object, references the InputParameters stored in the InputParametersWarehouse.
SolverParams & solverParams(unsigned int solver_sys_num=0)
Get the solver parameters.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
const InputParameters & parameters() const
Get the parameters of the object.
PerfID _final_timer
Definition: Eigenvalue.h:80
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
void dontAddLinearConvergedReason(FEProblemBase &fe_problem)
Function to ensure that -ksp_converged_reason is not added to the PetscOptions storage object to be l...
void setInitialEigenvalue(const Real initial_eigenvalue)
Set an initial eigenvalue for initial normalization.
Definition: EigenProblem.h:69
void setEigenProblemSolverParams(EigenProblem &eigen_problem, const InputParameters &params)
Retrieve eigen problem params from &#39;params&#39;, and then set these params into SolverParams.
Definition: SlepcSupport.C:212
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
EigenProblem & _eigen_problem
Definition: Eigenvalue.h:68
bool execMultiApps(ExecFlagType type, bool auto_advance=true)
Execute the MultiApps associated with the ExecFlagType.
unsigned int _extra_power_iterations
Definition: SolverParams.h:32
Problem for solving eigenvalue problems.
Definition: EigenProblem.h:21
void storeSolveType(FEProblemBase &fe_problem, const InputParameters &params)
Set solve type into eigen problem (solverParams)
Definition: SlepcSupport.C:286
Adaptivity & adaptivity()
bool isRecovering() const
Whether or not this is a "recover" calculation.
Definition: MooseApp.C:1685
virtual std::size_t numSolverSystems() const override
const ExecFlagType EXEC_FINAL
Definition: Moose.C:39
void setEigenproblemType(Moose::EigenProblemType eigen_problem_type)
Set eigen problem type.
Base class for user-specific data.
Definition: UserObject.h:39
std::unique_ptr< FixedPointSolve > _fixed_point_solve
Definition: Executioner.h:169
virtual void outputStep(ExecFlagType type)
Output the current step.
InputParameters getSlepcEigenProblemValidParams()
Retrieve valid params that allow users to specify eigen problem configuration.
Definition: SlepcSupport.C:67
virtual bool adaptMesh()
FEProblemBase & _fe_problem
Definition: Executioner.h:166
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...
const ExecFlagType EXEC_INITIAL
Definition: Moose.C:28