https://mooseframework.inl.gov
NonlinearEigenSystem.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 #include "NonlinearEigenSystem.h"
11 
12 // MOOSE includes
13 #include "DirichletBC.h"
14 #include "EigenDirichletBC.h"
15 #include "ArrayDirichletBC.h"
16 #include "EigenArrayDirichletBC.h"
17 #include "EigenProblem.h"
18 #include "IntegratedBC.h"
19 #include "KernelBase.h"
20 #include "NodalBC.h"
21 #include "TimeIntegrator.h"
22 #include "SlepcSupport.h"
23 #include "DGKernelBase.h"
24 #include "ScalarKernelBase.h"
25 #include "MooseVariableScalar.h"
26 #include "ResidualObject.h"
27 
28 #include "libmesh/libmesh_config.h"
29 #include "libmesh/petsc_matrix.h"
30 #include "libmesh/sparse_matrix.h"
31 #include "libmesh/diagonal_matrix.h"
32 #include "libmesh/petsc_shell_matrix.h"
33 #include "libmesh/petsc_solver_exception.h"
34 #include "libmesh/slepc_eigen_solver.h"
35 
36 using namespace libMesh;
37 
38 #ifdef LIBMESH_HAVE_SLEPC
39 
40 namespace Moose
41 {
42 
43 void
44 assemble_matrix(EquationSystems & es, const std::string & system_name)
45 {
46  EigenProblem * p = es.parameters.get<EigenProblem *>("_eigen_problem");
47  CondensedEigenSystem & eigen_system = es.get_system<CondensedEigenSystem>(system_name);
48  NonlinearEigenSystem & eigen_nl =
49  p->getNonlinearEigenSystem(/*nl_sys_num=*/eigen_system.number());
50 
51  // If this is a nonlinear eigenvalue problem,
52  // we do not need to assemble anything
53  if (p->isNonlinearEigenvalueSolver(eigen_nl.number()))
54  {
55  // If you want an efficient eigensolver,
56  // please use PETSc 3.13 or newer.
57  // We need to do an unnecessary assembly,
58  // if you use PETSc that is older than 3.13.
59 #if PETSC_RELEASE_LESS_THAN(3, 13, 0)
60  if (eigen_system.has_matrix_B())
61  p->computeJacobianTag(*eigen_system.current_local_solution,
62  eigen_system.get_matrix_B(),
63  eigen_nl.eigenMatrixTag());
64 #endif
65  return;
66  }
67 
68 #if !PETSC_RELEASE_LESS_THAN(3, 13, 0)
69  // If we use shell matrices and do not use a shell preconditioning matrix,
70  // we only need to form a preconditioning matrix
71  if (eigen_system.use_shell_matrices() && !eigen_system.use_shell_precond_matrix())
72  {
73  p->computeJacobianTag(*eigen_system.current_local_solution,
74  eigen_system.get_precond_matrix(),
75  eigen_nl.precondMatrixTag());
76  return;
77  }
78 #endif
79  // If it is a linear generalized eigenvalue problem,
80  // we assemble A and B together
81  if (eigen_system.generalized())
82  {
83  p->computeJacobianAB(*eigen_system.current_local_solution,
84  eigen_system.get_matrix_A(),
85  eigen_system.get_matrix_B(),
86  eigen_nl.nonEigenMatrixTag(),
87  eigen_nl.eigenMatrixTag());
88 #if LIBMESH_HAVE_SLEPC
89  if (p->negativeSignEigenKernel())
90  LibmeshPetscCallA(
91  p->comm().get(),
92  MatScale(static_cast<PetscMatrix<Number> &>(eigen_system.get_matrix_B()).mat(), -1.0));
93 #endif
94  return;
95  }
96 
97  // If it is a linear eigenvalue problem, we assemble matrix A
98  {
99  p->computeJacobianTag(*eigen_system.current_local_solution,
100  eigen_system.get_matrix_A(),
101  eigen_nl.nonEigenMatrixTag());
102 
103  return;
104  }
105 }
106 }
107 
108 NonlinearEigenSystem::NonlinearEigenSystem(EigenProblem & eigen_problem, const std::string & name)
110  eigen_problem, eigen_problem.es().add_system<CondensedEigenSystem>(name), name),
111  _eigen_sys(eigen_problem.es().get_system<CondensedEigenSystem>(name)),
112  _eigen_problem(eigen_problem),
113  _solver_configuration(nullptr),
114  _n_eigen_pairs_required(eigen_problem.getNEigenPairsRequired()),
115  _work_rhs_vector_AX(addVector("work_rhs_vector_Ax", false, PARALLEL)),
116  _work_rhs_vector_BX(addVector("work_rhs_vector_Bx", false, PARALLEL)),
117  _precond_matrix_includes_eigen(false),
118  _preconditioner(nullptr),
119  _num_constrained_dofs(0)
120 {
121  SlepcEigenSolver<Number> * solver =
122  cast_ptr<SlepcEigenSolver<Number> *>(_eigen_sys.eigen_solver.get());
123 
124  if (!solver)
125  mooseError("A slepc eigen solver is required");
126 
127  // setup of our class @SlepcSolverConfiguration
129  std::make_unique<SlepcEigenSolverConfiguration>(eigen_problem, *solver, *this);
130 
131  solver->set_solver_configuration(*_solver_configuration);
132 
133  _Ax_tag = eigen_problem.addVectorTag("Ax_tag");
134 
135  _Bx_tag = eigen_problem.addVectorTag("Eigen");
136 
137  _A_tag = eigen_problem.addMatrixTag("A_tag");
138 
139  _B_tag = eigen_problem.addMatrixTag("Eigen");
140 
141  // By default, _precond_tag and _A_tag will share the same
142  // objects. If we want to include eigen contributions to
143  // the preconditioning matrix, and then _precond_tag will
144  // point to part of "B" objects
145  _precond_tag = eigen_problem.addMatrixTag("Eigen_precond");
146 
147  // We do not rely on creating submatrices in the solve routine
149 }
150 
151 void
153 {
154  // If it is an eigen dirichlet boundary condition, we should skip it because their
155  // contributions should be zero. If we do not skip it, preconditioning matrix will
156  // be singular because boundary elements are zero.
157  if (_precond_matrix_includes_eigen && !dynamic_cast<EigenDirichletBC *>(&object) &&
158  !dynamic_cast<EigenArrayDirichletBC *>(&object))
159  object.useMatrixTag(_precond_tag, {});
160 
161  auto & vtags = object.getVectorTags({});
162  auto & mtags = object.getMatrixTags({});
163 
164  const bool eigen = (vtags.find(_Bx_tag) != vtags.end()) || (mtags.find(_B_tag) != mtags.end());
165 
166  if (eigen && !_eigen_sys.generalized())
167  object.mooseError("This object has been marked as contributing to B or Bx but the eigen "
168  "problem type is not a generalized one");
169 
170  // If it is an eigen kernel, mark its variable as eigen
171  if (eigen)
172  {
173  // Note: the object may be on the displaced system
174  auto sys = object.parameters().get<SystemBase *>("_sys");
175  auto vname = object.variable().name();
176  if (hasScalarVariable(vname))
177  sys->getScalarVariable(0, vname).eigen(true);
178  else
179  sys->getVariable(0, vname).eigen(true);
180 
181  // Associate the eigen matrix tag and the vector tag
182  // if this is a eigen kernel
183  object.useMatrixTag(_B_tag, {});
184  object.useVectorTag(_Bx_tag, {});
185  }
186  else
187  {
188  // Noneigen Vector tag
189  object.useVectorTag(_Ax_tag, {});
190  // Noneigen Matrix tag
191  object.useMatrixTag(_A_tag, {});
192  // Noneigen Kernels
193  object.useMatrixTag(_precond_tag, {});
194  }
195 }
196 
197 void
199 {
200  if (!(_num_constrained_dofs = dofMap().n_constrained_dofs()))
201  return;
202 
204  const auto m = cast_int<numeric_index_type>(_eigen_sys.local_non_condensed_dofs_vector.size());
205  auto M = m;
206  _communicator.sum(M);
208  {
209  _eigen_sys.get_condensed_matrix_A().init(M, M, m, m);
210  // A bit ludicrously MatCopy requires the matrix being copied to to be assembled
212  }
214  {
215  _eigen_sys.get_condensed_matrix_B().init(M, M, m, m);
217  }
219  {
222  }
223 }
224 
225 void
227 {
230 }
231 
232 void
234 {
237 }
238 
239 void
241 {
242  const bool presolve_succeeded = preSolve();
243  if (!presolve_succeeded)
244  return;
245 
246  std::unique_ptr<NumericVector<Number>> subvec;
247 
248  // We apply initial guess for only nonlinear solver
250  {
252  {
254  _eigen_sys.set_initial_space(*subvec);
255  }
256  else
258  }
259 
260  const bool time_integrator_solve = std::any_of(_time_integrators.begin(),
261  _time_integrators.end(),
262  [](auto & ti) { return ti->overridesSolve(); });
263  if (time_integrator_solve)
264  mooseAssert(_time_integrators.size() == 1,
265  "If solve is overridden, then there must be only one time integrator");
266 
267  if (time_integrator_solve)
268  _time_integrators.front()->solve();
269  else
270  system().solve();
271 
272  for (auto & ti : _time_integrators)
273  {
274  if (!ti->overridesSolve())
275  ti->setNumIterationsLastSolve();
276  ti->postSolve();
277  }
278 
279  // store solve information
281  {
282  auto snes = getSNES();
283 
284  // nonlinear iterations
285  PetscInt nl_its;
286  LibmeshPetscCallA(_eigen_problem.comm().get(), SNESGetIterationNumber(snes, &nl_its));
287  _n_iters = nl_its;
288 
289  // linear iterations
290  PetscInt l_its;
291  LibmeshPetscCallA(_eigen_problem.comm().get(), SNESGetLinearSolveIterations(snes, &l_its));
292  _n_linear_iters = l_its;
293 
294  // final residual
295  PetscReal norm;
296  LibmeshPetscCall(SNESGetFunctionNorm(snes, &norm));
298  }
299 
300  // store eigenvalues
301  unsigned int n_converged_eigenvalues = getNumConvergedEigenvalues();
302 
304 
305  if (_n_eigen_pairs_required < n_converged_eigenvalues)
306  n_converged_eigenvalues = _n_eigen_pairs_required;
307 
308  _eigen_values.resize(n_converged_eigenvalues);
309  for (unsigned int n = 0; n < n_converged_eigenvalues; n++)
311 
312  // Update the solution vector to the active eigenvector
313  if (n_converged_eigenvalues)
315 
318 }
319 
320 unsigned int
322 {
323  if (!_time_integrators.empty())
324  mooseError("Not implemented for time integrators.");
326  mooseError("Only implemented for nonlinear eigenvalue solvers.");
327 
328  return _n_iters;
329 }
330 
331 unsigned int
333 {
334  if (!_time_integrators.empty())
335  mooseError("Not implemented for time integrators.");
337  mooseError("Only implemented for nonlinear eigenvalue solvers.");
338 
339  return _n_linear_iters;
340 }
341 
342 Real
344 {
346  mooseError("Only implemented for nonlinear eigenvalue solvers.");
347 
348  return _final_residual;
349 }
350 
351 void
353 {
354  // Tell libmesh not to close matrices before solve
355  _eigen_sys.get_eigen_solver().set_close_matrix_before_solve(false);
356 
358  {
359  // Condensed Matrix A
361  {
362  Mat mat = static_cast<PetscMatrix<Number> &>(_eigen_sys.get_condensed_matrix_A()).mat();
363 
365  }
366 
367  // Condensed Matrix B
369  {
370  Mat mat = static_cast<PetscMatrix<Number> &>(_eigen_sys.get_condensed_matrix_B()).mat();
371 
373  }
374 
375  // Condensed Preconditioning matrix
377  {
378  Mat mat = static_cast<PetscMatrix<Number> &>(_eigen_sys.get_condensed_precond_matrix()).mat();
379 
381  }
382  }
383  else
384  {
385  // Matrix A
386  if (_eigen_sys.has_matrix_A())
387  {
388  Mat mat = static_cast<PetscMatrix<Number> &>(_eigen_sys.get_matrix_A()).mat();
389 
391  }
392 
393  // Matrix B
394  if (_eigen_sys.has_matrix_B())
395  {
396  Mat mat = static_cast<PetscMatrix<Number> &>(_eigen_sys.get_matrix_B()).mat();
397 
399  }
400 
401  // Preconditioning matrix
403  {
404  Mat mat = static_cast<PetscMatrix<Number> &>(_eigen_sys.get_precond_matrix()).mat();
405 
407  }
408  }
409 
410  // Shell matrix A
412  {
413  Mat mat = static_cast<PetscShellMatrix<Number> &>(_eigen_sys.get_shell_matrix_A()).mat();
414 
415  // Attach callbacks for nonlinear eigenvalue solver
417 
418  // Set MatMult operations for shell
420  }
421 
422  // Shell matrix B
424  {
425  Mat mat = static_cast<PetscShellMatrix<Number> &>(_eigen_sys.get_shell_matrix_B()).mat();
426 
428 
429  // Set MatMult operations for shell
431  }
432 
433  // Shell preconditioning matrix
435  {
436  Mat mat = static_cast<PetscShellMatrix<Number> &>(_eigen_sys.get_shell_precond_matrix()).mat();
437 
439  }
440 }
441 
442 void
443 NonlinearEigenSystem::stopSolve(const ExecFlagType &, const std::set<TagID> &)
444 {
445  mooseError("did not implement yet \n");
446 }
447 
448 void
450 {
451  mooseError("did not implement yet \n");
452 }
453 
454 bool
456 {
457  return _eigen_sys.get_n_converged();
458 }
459 
460 unsigned int
462 {
463  mooseError("did not implement yet \n");
464  return 0;
465 }
466 
469 {
470  return _work_rhs_vector_BX;
471 }
472 
475 {
476  return _work_rhs_vector_AX;
477 }
478 
481 {
482  return _work_rhs_vector_BX;
483 }
484 
487 {
488  mooseError("did not implement yet \n");
489  return NULL;
490 }
491 
492 SNES
494 {
495  EPS eps = getEPS();
496 
498  {
499  SNES snes = nullptr;
500  LibmeshPetscCall(Moose::SlepcSupport::mooseSlepcEPSGetSNES(eps, &snes));
501  return snes;
502  }
503  else
504  mooseError("There is no SNES in linear eigen solver");
505 }
506 
507 EPS
509 {
510  SlepcEigenSolver<Number> * solver =
511  cast_ptr<SlepcEigenSolver<Number> *>(&(*_eigen_sys.eigen_solver));
512 
513  if (!solver)
514  mooseError("Unable to retrieve eigen solver");
515 
516  return solver->eps();
517 }
518 
519 void
521 {
523  {
524  const auto & nodal_bcs = _nodal_bcs.getActiveObjects();
525  for (const auto & nodal_bc : nodal_bcs)
526  {
527  // If this is a dirichlet boundary condition
528  auto nbc = std::dynamic_pointer_cast<DirichletBC>(nodal_bc);
529  // If this is a eigen Dirichlet boundary condition
530  auto eigen_nbc = std::dynamic_pointer_cast<EigenDirichletBC>(nodal_bc);
531  // ArrayDirichletBC
532  auto anbc = std::dynamic_pointer_cast<ArrayDirichletBC>(nodal_bc);
533  // EigenArrayDirichletBC
534  auto aeigen_nbc = std::dynamic_pointer_cast<EigenArrayDirichletBC>(nodal_bc);
535  // If it is a Dirichlet boundary condition, then value has to be zero
536  if (nbc && nbc->variable().eigen() && nbc->getParam<Real>("value"))
537  mooseError(
538  "Can't set an inhomogeneous Dirichlet boundary condition for eigenvalue problems.");
539  // If it is an array Dirichlet boundary condition, all values should be zero
540  else if (anbc)
541  {
542  auto & values = anbc->getParam<RealEigenVector>("values");
543  for (MooseIndex(values) i = 0; i < values.size(); i++)
544  {
545  if (values(i))
546  mooseError("Can't set an inhomogeneous array Dirichlet boundary condition for "
547  "eigenvalue problems.");
548  }
549  }
550  else if (!nbc && !eigen_nbc && !anbc && !aeigen_nbc)
551  mooseError(
552  "Invalid NodalBC for eigenvalue problems, please use homogeneous (array) Dirichlet.");
553  }
554  }
555 }
556 
557 std::pair<Real, Real>
559 {
560  unsigned int n_converged_eigenvalues = getNumConvergedEigenvalues();
561  if (n >= n_converged_eigenvalues)
562  mooseError(n, " not in [0, ", n_converged_eigenvalues, ")");
563  return _eigen_sys.get_eigenvalue(n);
564 }
565 
566 std::pair<Real, Real>
568 {
569  unsigned int n_converged_eigenvalues = getNumConvergedEigenvalues();
570 
571  if (n >= n_converged_eigenvalues)
572  mooseError(n, " not in [0, ", n_converged_eigenvalues, ")");
573 
574  return _eigen_sys.get_eigenpair(n);
575 }
576 
577 void
579 {
581 
582  // If we have a customized preconditioner,
583  // We need to let PETSc know that
584  if (_preconditioner)
585  {
586  LibmeshPetscCall(Moose::SlepcSupport::registerPCToPETSc());
587  // Mark this, and then we can setup correct petsc options
590  }
591 }
592 
593 void
595 {
596  // Let us do nothing at the current moment
597 }
598 
599 void
601 {
602  mooseError(
603  "NonlinearEigenSystem::residualAndJacobianTogether is not implemented. It might even be "
604  "nonsensical. If it is sensical and you want this capability, please contact a MOOSE "
605  "developer.");
606 }
607 
608 void
610 {
612 }
613 
614 void
616 {
618 }
619 
620 std::set<TagID>
622 {
624  tags.insert(eigenVectorTag());
625  tags.insert(nonEigenVectorTag());
626  return tags;
627 }
628 
629 std::set<TagID>
631 {
633  tags.insert(eigenMatrixTag());
634  tags.insert(nonEigenMatrixTag());
635  return tags;
636 }
637 
638 #else
639 
641  const std::string & /*name*/)
642  : libMesh::ParallelObject(eigen_problem)
643 {
644  mooseError("Need to install SLEPc to solve eigenvalue problems, please reconfigure libMesh\n");
645 }
646 
647 #endif /* LIBMESH_HAVE_SLEPC */
std::string name(const ElemQuality q)
Nonlinear eigenvalue system to be solved.
std::vector< std::shared_ptr< TimeIntegrator > > _time_integrators
Time integrator.
Definition: SystemBase.h:1049
virtual void computeResidualTag(const NumericVector< Number > &soln, NumericVector< Number > &residual, TagID tag) override
Form a vector for all kernels and BCs with a given tag.
Definition: EigenProblem.C:295
const SparseMatrix< Number > & get_precond_matrix() const
NumericVector< Number > & residualVectorAX()
int eps(unsigned int i, unsigned int j)
2D version
std::unique_ptr< SlepcEigenSolverConfiguration > _solver_configuration
unsigned int activeEigenvalueIndex() const
Which eigenvalue is active.
Definition: EigenProblem.h:176
NumericVector< Number > & solution()
Definition: SystemBase.h:197
const SparseMatrix< Number > & get_matrix_A() const
SparseMatrix< Number > & get_condensed_precond_matrix()
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
virtual void postAddResidualObject(ResidualObject &object) override
Called after any ResidualObject-derived objects are added to the system.
TagID nonEigenVectorTag() const
Vector tag ID of left hand side.
const SparseMatrix< Number > & get_matrix_B() const
virtual libMesh::NonlinearSolver< Number > * nonlinearSolver() override
virtual void reinit() override
Reinitialize the system when the degrees of freedom in this system have changed.
TagID eigenVectorTag() const
Vector tag ID of right hand side.
void initializeCondensedMatrices()
Initialize the condensed matrices.
bool has_condensed_precond_matrix() const
virtual Real finalNonlinearResidual() const override
Return the final nonlinear residual.
MooseObjectTagWarehouse< NodalBCBase > _nodal_bcs
std::set< TagID > defaultVectorTags() const override
Get the default vector tags associated with this system.
bool negativeSignEigenKernel() const
A flag indicates if a negative sign is used in eigen kernels.
Definition: EigenProblem.h:57
const Parallel::Communicator & comm() const
NumericVector< Number > & _work_rhs_vector_AX
virtual void postInit() override
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
std::unique_ptr< libMesh::DiagonalMatrix< Number > > _scaling_matrix
A diagonal matrix used for computing scaling.
bool _customized_pc_for_eigen
Definition: SolverParams.h:29
const Parallel::Communicator & _communicator
void set_initial_space(NumericVector< Number > &initial_space_in)
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
const EigenSolver< Number > & get_eigen_solver() const
Base class for a system (of equations)
Definition: SystemBase.h:85
const T_sys & get_system(std::string_view name) const
NonlinearEigenSystem(EigenProblem &problem, const std::string &name)
NumericVector< Number > & _work_rhs_vector_BX
const ShellMatrix< Number > & get_shell_matrix_A() const
bool isNonlinearEigenvalueSolver(unsigned int eigen_sys_num) const
Definition: EigenProblem.C:676
unsigned int getNumConvergedEigenvalues() const
Get the number of converged eigenvalues.
Nonlinear system to be solved.
virtual const std::string & name() const
Definition: SystemBase.C:1342
unsigned int getNEigenPairsRequired() const
Definition: EigenProblem.h:37
SparseMatrix< Number > & get_condensed_matrix_A()
virtual libMesh::DofMap & dofMap()
Gets writeable reference to the dof map.
Definition: SystemBase.C:1164
virtual EPS getEPS()
Retrieve EPS (SLEPc eigen solver)
libMesh::Preconditioner< Number > * _preconditioner
const T & get(std::string_view) const
const std::vector< std::shared_ptr< T > > & getActiveObjects(THREAD_ID tid=0) const
Retrieve complete vector to the active all/block/boundary restricted objects for a given thread...
virtual void stopSolve(const ExecFlagType &exec_flag, const std::set< TagID > &vector_tags_to_close) override
Quit the current solve as soon as possible.
void attachCallbacksToMat(EigenProblem &eigen_problem, Mat mat, bool eigen)
Attach call backs to mat.
NumericVector< Number > & residualVectorBX()
virtual void turnOffJacobian() override
Turn off the Jacobian (must be called before equation system initialization)
std::pair< Real, Real > getConvergedEigenpair(dof_id_type n) const
Return the Nth converged eigenvalue and copies the respective eigen vector to the solution vector...
Jacobian-Free Newton Krylov.
Definition: MooseTypes.h:894
virtual bool converged() override
Returns the convergence state.
Boundary condition of a Dirichlet type.
Definition: DirichletBC.h:19
Moose::SolveType _type
Definition: SolverParams.h:19
const ShellMatrix< Number > & get_shell_precond_matrix() const
void initialize_condensed_dofs(const std::set< dof_id_type > &global_condensed_dofs_set=std::set< dof_id_type >())
unsigned int number() const
Gets the number of this system.
Definition: SystemBase.C:1158
void assemble_matrix(EquationSystems &es, const std::string &system_name)
virtual std::unique_ptr< NumericVector< T > > get_subvector(const std::vector< numeric_index_type > &)
virtual unsigned int nNonlinearIterations() const override
Return the number of non-linear iterations.
Set Dirichlet boundary condition for eigenvalue problems.
virtual void setupFiniteDifferencedPreconditioner() override
virtual void solve()
bool has_shell_precond_matrix() const
virtual std::pair< Real, Real > get_eigenvalue(dof_id_type i)
const NumericVector< Number > * _current_solution
solution vector from solver
Definition: SolverSystem.h:120
virtual std::set< TagID > defaultMatrixTags() const
Get the default matrix tags associted with this system.
Definition: SystemBase.h:320
void computeScalingResidual() override
Compute a "residual" for automatic scaling purposes.
virtual void postInit()
Definition: SystemBase.h:163
dof_id_type _num_constrained_dofs
The number of degrees of freedom constrained at the libMesh level, e.g.
virtual unsigned int getCurrentNonlinearIterationNumber() override
Returns the current nonlinear iteration number.
NonlinearEigenSystem & getNonlinearEigenSystem(const unsigned int nl_sys_num)
Definition: EigenProblem.h:299
virtual void close()=0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
This is the common base class for objects that give residual contributions.
PetscErrorCode mooseSlepcEPSGetSNES(EPS eps, SNES *snes)
Retrieve SNES from EPS.
Class for containing MooseEnum item information.
Definition: MooseEnumItem.h:18
bool hasActiveObjects(THREAD_ID tid=0) const
auto norm(const T &a)
std::unique_ptr< EigenSolver< Number > > eigen_solver
const ShellMatrix< Number > & get_shell_matrix_B() const
libMesh::CondensedEigenSystem & sys()
void residualAndJacobianTogether() override
Call this method if you want the residual and Jacobian to be computed simultaneously.
virtual std::set< TagID > defaultVectorTags() const
Get the default vector tags associated with this system.
Definition: SystemBase.h:313
virtual SNES getSNES() override
Retrieve snes from slepc eigen solver.
virtual std::pair< Real, Real > get_eigenpair(dof_id_type i) override
TagID eigenMatrixTag() const
Matrix tag ID of right hand side.
std::vector< dof_id_type > local_non_condensed_dofs_vector
void computeScalingJacobian() override
Compute a "Jacobian" for automatic scaling purposes.
virtual void reinit()
Reinitialize the system when the degrees of freedom in this system have changed.
Definition: SystemBase.h:169
SolverParams & solverParams(unsigned int solver_sys_num=0)
Get the solver parameters.
Boundary condition of a Dirichlet type for the eigen side.
void setOperationsForShellMat(EigenProblem &eigen_problem, Mat mat, bool eigen)
Set operations to shell mat.
Eigen::Matrix< Real, Eigen::Dynamic, 1 > RealEigenVector
Definition: MooseTypes.h:147
std::pair< Real, Real > getConvergedEigenvalue(dof_id_type n) const
Return the Nth converged eigenvalue.
TagID nonEigenMatrixTag() const
Matrix tag ID of left hand side.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
SparseMatrix< Number > & get_condensed_matrix_B()
unsigned int get_n_converged() const
bool preSolve()
Perform some steps to get ready for the solver.
Problem for solving eigenvalue problems.
Definition: EigenProblem.h:21
std::vector< std::pair< Real, Real > > _eigen_values
PETSC_EXTERN PetscErrorCode registerPCToPETSc()
Let PETSc know there is a preconditioner.
virtual NumericVector< Number > & RHS() override
unsigned int _n_eigen_pairs_required
virtual void solve() override
Solve the system (using libMesh magic)
virtual bool hasScalarVariable(const std::string &var_name) const
Definition: SystemBase.C:877
libMesh::CondensedEigenSystem & _eigen_sys
Boundary condition of a Dirichlet type.
std::set< TagID > defaultMatrixTags() const override
Get the default matrix tags associted with this system.
libMesh::Preconditioner< Number > * preconditioner() const
void checkIntegrity()
For eigenvalue problems (including standard and generalized), inhomogeneous (Dirichlet or Neumann) bo...
virtual unsigned int nLinearIterations() const override
Return the number of linear iterations.
virtual void attachPreconditioner(libMesh::Preconditioner< Number > *preconditioner) override
Attach a customized preconditioner that requires physics knowledge.
void computeJacobianAB(const NumericVector< Number > &soln, SparseMatrix< Number > &jacobianA, SparseMatrix< Number > &jacobianB, TagID tagA, TagID tagB)
Form two Jacobian matrices, where each is associated with one tag, through one element-loop.
Definition: EigenProblem.C:259
virtual void computeJacobianTag(const NumericVector< Number > &soln, SparseMatrix< Number > &jacobian, TagID tag) override
Form a Jacobian matrix for all kernels and BCs with a given tag.
Definition: EigenProblem.C:176
uint8_t dof_id_type
virtual void init(const numeric_index_type m, const numeric_index_type n, const numeric_index_type m_l, const numeric_index_type n_l, const numeric_index_type nnz=30, const numeric_index_type noz=10, const numeric_index_type blocksize=1)=0
virtual void restore_subvector(std::unique_ptr< NumericVector< T >>, const std::vector< numeric_index_type > &)
virtual libMesh::System & system() override
Get the reference to the libMesh system.