www.mooseframework.org
EigenProblem.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "libmesh/libmesh_config.h"
11 
12 #include "EigenProblem.h"
13 #include "Assembly.h"
14 #include "AuxiliarySystem.h"
15 #include "DisplacedProblem.h"
16 #include "NonlinearEigenSystem.h"
17 #include "SlepcSupport.h"
18 #include "RandomData.h"
19 #include "OutputWarehouse.h"
20 #include "Function.h"
21 #include "MooseVariableScalar.h"
22 
23 // libMesh includes
24 #include "libmesh/system.h"
25 #include "libmesh/eigen_solver.h"
26 #include "libmesh/enum_eigen_solver_type.h"
27 
29 
32 {
34  params.addClassDescription("Problem object for solving an eigenvalue problem.");
35  params.addParam<bool>("negative_sign_eigen_kernel",
36  true,
37  "Whether or not to use a negative sign for eigenvalue kernels. "
38  "Using a negative sign makes eigenvalue kernels consistent with "
39  "a nonlinear solver");
40 
41  params.addParam<unsigned int>(
42  "active_eigen_index",
43  0,
44  "Which eigenvector is used to compute residual and also associated to nonlinear variable");
45  params.addParam<PostprocessorName>("bx_norm", "A postprocessor describing the norm of Bx");
46 
47  return params;
48 }
49 
51  : FEProblemBase(parameters)
52 #ifdef LIBMESH_HAVE_SLEPC
53  ,
54  // By default, we want to compute an eigenvalue only (smallest or largest)
55  _n_eigen_pairs_required(1),
56  _generalized_eigenvalue_problem(false),
57  _negative_sign_eigen_kernel(getParam<bool>("negative_sign_eigen_kernel")),
58  _active_eigen_index(getParam<unsigned int>("active_eigen_index")),
59  _do_free_power_iteration(false),
60  _output_inverse_eigenvalue(false),
61  _on_linear_solver(false),
62  _matrices_formed(false),
63  _constant_matrices(false),
64  _has_normalization(false),
65  _normal_factor(1.0),
66  _first_solve(declareRestartableData<bool>("first_solve", true)),
67  _bx_norm_name(isParamValid("bx_norm")
68  ? std::make_optional(getParam<PostprocessorName>("bx_norm"))
69  : std::nullopt)
70 #endif
71 {
72 #ifdef LIBMESH_HAVE_SLEPC
73  if (_nl_sys_names.size() > 1)
74  paramError("nl_sys_names",
75  "eigen problems do not currently support multiple nonlinear eigen systems");
76 
77  for (const auto i : index_range(_nl_sys_names))
78  {
79  const auto & sys_name = _nl_sys_names[i];
80  auto & nl = _nl[i];
81  nl = std::make_shared<NonlinearEigenSystem>(*this, sys_name);
83  _current_nl_sys = nl.get();
84  }
85 
86  _aux = std::make_shared<AuxiliarySystem>(*this, "aux0");
87 
89 
91 
92  es().parameters.set<EigenProblem *>("_eigen_problem") = this;
93 #else
94  mooseError("Need to install SLEPc to solve eigenvalue problems, please reconfigure\n");
95 #endif /* LIBMESH_HAVE_SLEPC */
96 
97  // SLEPc older than 3.13.0 can not take initial guess from moose
98 #if PETSC_RELEASE_LESS_THAN(3, 13, 0)
100  "Please use SLEPc-3.13.0 or higher. Old versions of SLEPc likely produce bad convergence");
101 #endif
102  // Create extra vectors and matrices if any
104 
105  // Create extra solution vectors if any
107 }
108 
109 #ifdef LIBMESH_HAVE_SLEPC
110 void
112 {
113  switch (eigen_problem_type)
114  {
116  _nl_eigen->sys().set_eigenproblem_type(libMesh::HEP);
118  break;
119 
121  _nl_eigen->sys().set_eigenproblem_type(libMesh::NHEP);
123  break;
124 
126  _nl_eigen->sys().set_eigenproblem_type(libMesh::GHEP);
128  break;
129 
131  _nl_eigen->sys().set_eigenproblem_type(libMesh::GHIEP);
133  break;
134 
136  _nl_eigen->sys().set_eigenproblem_type(libMesh::GNHEP);
138  break;
139 
141  mooseError("libMesh does not support EPT_POS_GEN_NON_HERMITIAN currently \n");
142  break;
143 
146  break;
147 
148  default:
149  mooseError("Unknown eigen solver type \n");
150  }
151 }
152 
153 void
155 {
156  if (exec_type == EXEC_INITIAL)
157  // we need to scale the solution properly and we can do this only all initial setup of
158  // depending objects by the residual evaluations has been done to this point.
159  preScaleEigenVector(std::pair<Real, Real>(_initial_eigenvalue, 0));
160 
161  FEProblemBase::execute(exec_type);
162 }
163 
164 void
166  SparseMatrix<Number> & jacobian,
167  TagID tag)
168 {
169  TIME_SECTION("computeJacobianTag", 3);
170 
171  // Disassociate the default tags because we will associate vectors with only the
172  // specific system tags that we need for this instance
173  _nl_eigen->disassociateDefaultMatrixTags();
174 
175  // Clear FE tags and first add the specific tag associated with the Jacobian
176  _fe_matrix_tags.clear();
177  _fe_matrix_tags.insert(tag);
178 
179  // Add any other user-added matrix tags if they have associated matrices
180  const auto & matrix_tags = getMatrixTags();
181  for (const auto & matrix_tag : matrix_tags)
182  if (_nl_eigen->hasMatrix(matrix_tag.second))
183  _fe_matrix_tags.insert(matrix_tag.second);
184 
185  _nl_eigen->setSolution(soln);
186 
187  _nl_eigen->associateMatrixToTag(jacobian, tag);
188 
190 
191  _nl_eigen->disassociateMatrixFromTag(jacobian, tag);
192 }
193 
194 void
196  const NumericVector<Number> & soln,
197  const std::vector<std::unique_ptr<SparseMatrix<Number>>> & jacobians,
198  const std::set<TagID> & tags)
199 {
200  TIME_SECTION("computeMatricesTags", 3);
201 
202  if (jacobians.size() != tags.size())
203  mooseError("The number of matrices ",
204  jacobians.size(),
205  " does not equal the number of tags ",
206  tags.size());
207 
208  // Disassociate the default tags because we will associate vectors with only the
209  // specific system tags that we need for this instance
210  _nl_eigen->disassociateDefaultMatrixTags();
211 
212  _fe_matrix_tags.clear();
213 
214  _nl_eigen->setSolution(soln);
215 
216  unsigned int i = 0;
217  for (auto tag : tags)
218  _nl_eigen->associateMatrixToTag(*(jacobians[i++]), tag);
219 
220  computeJacobianTags(tags);
221 
222  i = 0;
223  for (auto tag : tags)
224  _nl_eigen->disassociateMatrixFromTag(*(jacobians[i++]), tag);
225 }
226 
227 void
228 EigenProblem::computeJacobianBlocks(std::vector<JacobianBlock *> & blocks,
229  const unsigned int nl_sys_num)
230 {
231  TIME_SECTION("computeJacobianBlocks", 3);
232  setCurrentNonlinearSystem(nl_sys_num);
233 
234  if (_displaced_problem)
235  _aux->compute(EXEC_PRE_DISPLACE);
236 
237  _aux->compute(EXEC_NONLINEAR);
238 
240 
241  _current_nl_sys->computeJacobianBlocks(blocks, {_nl_eigen->precondMatrixTag()});
242 
244 }
245 
246 void
248  SparseMatrix<Number> & jacobianA,
249  SparseMatrix<Number> & jacobianB,
250  TagID tagA,
251  TagID tagB)
252 {
253  TIME_SECTION("computeJacobianAB", 3);
254 
255  // Disassociate the default tags because we will associate vectors with only the
256  // specific system tags that we need for this instance
257  _nl_eigen->disassociateDefaultMatrixTags();
258 
259  // Clear FE tags and first add the specific tags associated with the Jacobian
260  _fe_matrix_tags.clear();
261  _fe_matrix_tags.insert(tagA);
262  _fe_matrix_tags.insert(tagB);
263 
264  // Add any other user-added matrix tags if they have associated matrices
265  const auto & matrix_tags = getMatrixTags();
266  for (const auto & matrix_tag : matrix_tags)
267  if (_nl_eigen->hasMatrix(matrix_tag.second))
268  _fe_matrix_tags.insert(matrix_tag.second);
269 
270  _nl_eigen->setSolution(soln);
271 
272  _nl_eigen->associateMatrixToTag(jacobianA, tagA);
273  _nl_eigen->associateMatrixToTag(jacobianB, tagB);
274 
276 
277  _nl_eigen->disassociateMatrixFromTag(jacobianA, tagA);
278  _nl_eigen->disassociateMatrixFromTag(jacobianB, tagB);
279 }
280 
281 void
283  NumericVector<Number> & residual,
284  TagID tag)
285 {
286  TIME_SECTION("computeResidualTag", 3);
287 
288  // Disassociate the default tags because we will associate vectors with only the
289  // specific system tags that we need for this instance
290  _nl_eigen->disassociateDefaultVectorTags();
291 
292  // Clear FE tags and first add the specific tag associated with the residual
293  _fe_vector_tags.clear();
294  _fe_vector_tags.insert(tag);
295 
296  // Add any other user-added vector residual tags if they have associated vectors
297  const auto & residual_vector_tags = getVectorTags(Moose::VECTOR_TAG_RESIDUAL);
298  for (const auto & vector_tag : residual_vector_tags)
299  if (_nl_eigen->hasVector(vector_tag._id))
300  _fe_vector_tags.insert(vector_tag._id);
301 
302  _nl_eigen->associateVectorToTag(residual, tag);
303 
304  _nl_eigen->setSolution(soln);
305 
307 
308  _nl_eigen->disassociateVectorFromTag(residual, tag);
309 }
310 
311 void
313  NumericVector<Number> & residualA,
314  NumericVector<Number> & residualB,
315  TagID tagA,
316  TagID tagB)
317 {
318  TIME_SECTION("computeResidualAB", 3);
319 
320  // Disassociate the default tags because we will associate vectors with only the
321  // specific system tags that we need for this instance
322  _nl_eigen->disassociateDefaultVectorTags();
323 
324  // Clear FE tags and first add the specific tags associated with the residual
325  _fe_vector_tags.clear();
326  _fe_vector_tags.insert(tagA);
327  _fe_vector_tags.insert(tagB);
328 
329  // Add any other user-added vector residual tags if they have associated vectors
330  const auto & residual_vector_tags = getVectorTags(Moose::VECTOR_TAG_RESIDUAL);
331  for (const auto & vector_tag : residual_vector_tags)
332  if (_nl_eigen->hasVector(vector_tag._id))
333  _fe_vector_tags.insert(vector_tag._id);
334 
335  _nl_eigen->associateVectorToTag(residualA, tagA);
336  _nl_eigen->associateVectorToTag(residualB, tagB);
337 
338  _nl_eigen->setSolution(soln);
339 
341 
342  _nl_eigen->disassociateVectorFromTag(residualA, tagA);
343  _nl_eigen->disassociateVectorFromTag(residualB, tagB);
344 }
345 
346 Real
348 {
349  computeResidualAB(*_nl_eigen->currentSolution(),
350  _nl_eigen->residualVectorAX(),
351  _nl_eigen->residualVectorBX(),
352  _nl_eigen->nonEigenVectorTag(),
353  _nl_eigen->eigenVectorTag());
354 
355  Real eigenvalue = 1.0;
356 
357  if (_active_eigen_index < _nl_eigen->getNumConvergedEigenvalues())
358  eigenvalue = _nl_eigen->getConvergedEigenvalue(_active_eigen_index).first;
359 
360  // Scale BX with eigenvalue
361  _nl_eigen->residualVectorBX() *= eigenvalue;
362 
363  // Compute entire residual
365  _nl_eigen->residualVectorAX() += _nl_eigen->residualVectorBX();
366  else
367  _nl_eigen->residualVectorAX() -= _nl_eigen->residualVectorBX();
368 
369  return _nl_eigen->residualVectorAX().l2_norm();
370 }
371 
372 void
373 EigenProblem::adjustEigenVector(const Real value, bool scaling)
374 {
375  std::vector<VariableName> var_names = getVariableNames();
376  for (auto & vn : var_names)
377  {
378  MooseVariableBase * var = nullptr;
379  if (hasScalarVariable(vn))
380  var = &getScalarVariable(0, vn);
381  else
382  var = &getVariable(0, vn);
383  // Do operations for only eigen variable
384  if (var->eigen())
385  for (unsigned int vc = 0; vc < var->count(); ++vc)
386  {
387  std::set<dof_id_type> var_indices;
388  _nl_eigen->system().local_dof_indices(var->number() + vc, var_indices);
389  for (const auto & dof : var_indices)
390  _nl_eigen->solution().set(dof, scaling ? (_nl_eigen->solution()(dof) * value) : value);
391  }
392  }
393 
394  _nl_eigen->solution().close();
395  _nl_eigen->update();
396 }
397 
398 void
399 EigenProblem::scaleEigenvector(const Real scaling_factor)
400 {
401  adjustEigenVector(scaling_factor, true);
402 }
403 
404 void
405 EigenProblem::initEigenvector(const Real initial_value)
406 {
407  // Yaqi's note: the following code will set a flat solution for lagrange and
408  // constant monomial variables. For the first or higher order elemental variables,
409  // the solution is not flat. Fortunately, the initial guess does not affect
410  // the final solution as long as it is not perpendicular to the true solution.
411  // We, in general, do not need to worry about that.
412 
414 }
415 
416 void
417 EigenProblem::preScaleEigenVector(const std::pair<Real, Real> & eig)
418 {
419  // pre-scale the solution to make sure ||Bx||_2 is equal to inverse of eigenvalue
421  *_nl_eigen->currentSolution(), _nl_eigen->residualVectorBX(), _nl_eigen->eigenVectorTag());
422 
423  // Eigenvalue magnitude
424  Real v = std::sqrt(eig.first * eig.first + eig.second * eig.second);
425  // Scaling factor
426  Real factor = 1 / v / (bxNormProvided() ? formNorm() : _nl_eigen->residualVectorBX().l2_norm());
427  // Scale eigenvector
428  if (!MooseUtils::absoluteFuzzyEqual(factor, 1))
429  scaleEigenvector(factor);
430 }
431 
432 void
434 {
435  if (_has_normalization)
436  {
437  Real v;
439  {
440  if (_active_eigen_index >= _nl_eigen->getNumConvergedEigenvalues())
441  mooseError("Number of converged eigenvalues ",
442  _nl_eigen->getNumConvergedEigenvalues(),
443  " but you required eigenvalue ",
445 
446  // when normal factor is not provided, we use the inverse of the norm of
447  // the active eigenvalue for normalization
448  auto eig = _nl_eigen->getAllConvergedEigenvalues()[_active_eigen_index];
449  v = 1 / std::sqrt(eig.first * eig.first + eig.second * eig.second);
450  }
451  else
452  v = _normal_factor;
453 
455 
456  // We scale SLEPc eigen vector here, so we need to scale it back for optimal
457  // convergence if we call EPS solver again
458  mooseAssert(v != 0., "normal factor can not be zero");
459 
460  unsigned int itr = 0;
461 
462  while (!MooseUtils::relativeFuzzyEqual(v, c))
463  {
464  // If postprocessor is not defined on eigen variables, scaling might not work
465  if (itr > 10)
466  mooseError("Can not scale eigenvector to the required factor ",
467  v,
468  " please check if postprocessor is defined on only eigen variables");
469 
470  mooseAssert(c != 0., "postprocessor value used for scaling can not be zero");
471 
472  scaleEigenvector(v / c);
473 
474  // update all aux variables and user objects on linear
476 
478 
479  itr++;
480  }
481  }
482 }
483 
484 void
486 {
488  _nl_eigen->checkIntegrity();
489 }
490 
491 void
492 EigenProblem::doFreeNonlinearPowerIterations(unsigned int free_power_iterations)
493 {
494  mooseAssert(_current_nl_sys, "This needs to be non-null");
495 
496  doFreePowerIteration(true);
497  // Set free power iterations
499 
500  // Call solver
503 
504  // Clear free power iterations
505  auto executioner = getMooseApp().getExecutioner();
506  if (executioner)
508  else
509  mooseError("There is no executioner for this moose app");
510 
511  doFreePowerIteration(false);
512 }
513 
514 void
515 EigenProblem::solve(const unsigned int nl_sys_num)
516 {
517 #if !PETSC_RELEASE_LESS_THAN(3, 12, 0)
518  // Master has the default database
519  if (!_app.isUltimateMaster())
520  PetscOptionsPush(_petsc_option_data_base);
521 #endif
522 
523  setCurrentNonlinearSystem(nl_sys_num);
524 
525  if (_solve)
526  {
527  TIME_SECTION("solve", 1);
528 
529  // Set necessary slepc callbacks
530  // We delay this call as much as possible because libmesh
531  // could rebuild matrices due to mesh changes or something else.
532  _nl_eigen->attachSLEPcCallbacks();
533 
534  // If there is an eigenvalue, we scale 1/|Bx| to eigenvalue
535  if (_active_eigen_index < _nl_eigen->getNumConvergedEigenvalues())
536  {
537  std::pair<Real, Real> eig = _nl_eigen->getConvergedEigenvalue(_active_eigen_index);
538  preScaleEigenVector(eig);
539  }
540 
542  solverParams()._eigen_solve_type != Moose::EST_NONLINEAR_POWER)
543  {
544  // Let do an initial solve if a nonlinear eigen solver but not power is used.
545  // The initial solver is a Inverse Power, and it is used to compute a good initial
546  // guess for Newton
547  if (solverParams()._free_power_iterations && _first_solve)
548  {
549  _console << std::endl << " -------------------------------" << std::endl;
550  _console << " Free power iteration starts ..." << std::endl;
551  _console << " -------------------------------" << std::endl << std::endl;
552  doFreeNonlinearPowerIterations(solverParams()._free_power_iterations);
553  _first_solve = false;
554  }
555 
556  // Let us do extra power iterations here if necessary
557  if (solverParams()._extra_power_iterations)
558  {
559  _console << std::endl << " --------------------------------------" << std::endl;
560  _console << " Extra Free power iteration starts ..." << std::endl;
561  _console << " --------------------------------------" << std::endl << std::endl;
562  doFreeNonlinearPowerIterations(solverParams()._extra_power_iterations);
563  }
564  }
565 
566  // We print this for only nonlinear solver
568  {
569  _console << std::endl << " -------------------------------------" << std::endl;
570 
571  if (solverParams()._eigen_solve_type != Moose::EST_NONLINEAR_POWER)
572  _console << " Nonlinear Newton iteration starts ..." << std::endl;
573  else
574  _console << " Nonlinear power iteration starts ..." << std::endl;
575 
576  _console << " -------------------------------------" << std::endl << std::endl;
577  }
578 
581 
582  // with PJFNKMO solve type, we need to evaluate the linear objects to bring them up-to-date
583  if (solverParams()._eigen_solve_type == Moose::EST_PJFNKMO)
585 
586  // Scale eigen vector if users ask
588  }
589 
590 #if !PETSC_RELEASE_LESS_THAN(3, 12, 0)
591  if (!_app.isUltimateMaster())
592  PetscOptionsPop();
593 #endif
594 
595  // sync solutions in displaced problem
596  if (_displaced_problem)
597  _displaced_problem->syncSolutions();
598 
599  // Reset the matrix flag, so that we reform matrix in next picard iteration
600  _matrices_formed = false;
601 }
602 
603 void
604 EigenProblem::setNormalization(const PostprocessorName & pp, const Real value)
605 {
606  _has_normalization = true;
607  _normalization = pp;
609 }
610 
611 void
613 {
614 #if !PETSC_RELEASE_LESS_THAN(3, 13, 0)
615  // If matrix_free=true, this tells Libmesh to use shell matrices
616  _nl_eigen->sys().use_shell_matrices(solverParams()._eigen_matrix_free &&
617  !solverParams()._eigen_matrix_vector_mult);
618  // We need to tell libMesh if we are using a shell preconditioning matrix
619  _nl_eigen->sys().use_shell_precond_matrix(solverParams()._precond_matrix_free);
620 #endif
621 
623 }
624 
625 bool
627 {
628  if (_solve)
629  return _nl_eigen->converged();
630  else
631  return true;
632 }
633 
634 bool
636 {
642 }
643 
644 void
646 {
648 }
649 
650 Real
652 {
653  mooseAssert(_bx_norm_name,
654  "We should not get here unless a bx_norm postprocessor has been provided");
656 }
657 #endif
Nonlinear eigenvalue system to be solved.
virtual void update(bool update_libmesh_system=true)
Update the system (doing libMesh magic)
Definition: SystemBase.C:1211
Generalized Non-Hermitian.
Definition: MooseTypes.h:789
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:282
static InputParameters validParams()
Definition: EigenProblem.C:31
void computeJacobianBlocks(std::vector< JacobianBlock *> &blocks)
Computes several Jacobian blocks simultaneously, summing their contributions into smaller preconditio...
bool _matrices_formed
Whether or not matrices had been formed.
Definition: EigenProblem.h:263
Generalized Hermitian indefinite.
Definition: MooseTypes.h:788
Newton-based eigensolver with an assembled Jacobian matrix (fully coupled by default) ...
Definition: MooseTypes.h:774
Moose::EigenSolveType _eigen_solve_type
Definition: SolverParams.h:24
bool isUltimateMaster() const
Whether or not this app is the ultimate master app.
Definition: MooseApp.h:823
virtual void initPetscOutputAndSomeSolverSettings() override
Hook up monitors for SNES and KSP.
Definition: EigenProblem.C:645
SolverParams & solverParams()
Get the solver parameters.
PostprocessorName _normalization
Postprocessor used to compute a factor from eigenvector.
Definition: EigenProblem.h:269
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: MooseUtils.h:346
void mooseDeprecated(Args &&... args) const
virtual void computeJacobianBlocks(std::vector< JacobianBlock *> &blocks, const unsigned int nl_sys_num) override
Computes several Jacobian blocks simultaneously, summing their contributions into smaller preconditio...
Definition: EigenProblem.C:228
unsigned int TagID
Definition: MooseTypes.h:199
unsigned int number() const
Get variable number coming from libMesh.
bool _currently_computing_jacobian
Flag to determine whether the problem is currently computing Jacobian.
Definition: SubProblem.h:1026
virtual void init() override
The same as PJFNK except that matrix-vector multiplication is employed to replace residual evaluation...
Definition: MooseTypes.h:776
void initEigenvector(const Real initial_value)
For nonlinear eigen solver, a good initial value can help convergence.
Definition: EigenProblem.C:405
void clearFreeNonlinearPowerIterations(const InputParameters &params)
Definition: SlepcSupport.C:365
bool _has_normalization
Whether or not we normalize eigenvector.
Definition: EigenProblem.h:267
EigenProblem(const InputParameters &parameters)
Definition: EigenProblem.C:50
unsigned int count() const
Get the number of components Note: For standard and vector variables, the number is one...
virtual void execute(const ExecFlagType &exec_type) override
Convenience function for performing execution of MOOSE systems.
Definition: EigenProblem.C:154
PetscOptions _petsc_option_data_base
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void adjustEigenVector(const Real value, bool scaling)
Adjust eigen vector by either scaling the existing values or setting new values The operations are ap...
Definition: EigenProblem.C:373
void doFreeNonlinearPowerIterations(unsigned int free_power_iterations)
Do some free/extra power iterations.
Definition: EigenProblem.C:492
virtual bool hasScalarVariable(const std::string &var_name) const override
Returns a Boolean indicating whether any system contains a variable with the name provided...
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.
use whatever SLPEC has by default
Definition: MooseTypes.h:791
ADRealEigenVector< T, D, asd > sqrt(const ADRealEigenVector< T, D, asd > &)
bool _negative_sign_eigen_kernel
Whether or not use negative sign for Bx.
Definition: EigenProblem.h:249
Generalized Non-Hermitian with positive (semi-)definite B.
Definition: MooseTypes.h:790
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
void preScaleEigenVector(const std::pair< Real, Real > &eig)
Eigenvector need to be scaled back if it was scaled in an earlier stage Scaling eigen vector does not...
Definition: EigenProblem.C:417
MooseApp & getMooseApp() const
Get the MooseApp this class is associated with.
Definition: MooseBase.h:44
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const override
Returns the variable reference for requested variable which must be of the expected_var_type (Nonline...
virtual void computeResidualTags(const std::set< TagID > &tags)
Form multiple residual vectors and each is associated with one tag.
auto max(const L &left, const R &right)
virtual void newAssemblyArray(std::vector< std::shared_ptr< NonlinearSystemBase >> &nl)
std::shared_ptr< NonlinearEigenSystem > _nl_eigen
Definition: EigenProblem.h:245
bool eigen() const
Whether or not this variable operates on an eigen kernel.
bool _generalized_eigenvalue_problem
Definition: EigenProblem.h:244
virtual EquationSystems & es() override
bool isNonlinearEigenvalueSolver() const
Definition: EigenProblem.C:635
Real formNorm()
Form the Bx norm.
Definition: EigenProblem.C:651
bool & _first_solve
A flag to indicate if it is the first time calling the solve.
Definition: EigenProblem.h:274
std::vector< std::shared_ptr< NonlinearSystemBase > > _nl
The nonlinear systems.
void createTagSolutions()
Create extra tagged solution vectors.
virtual void execute(const ExecFlagType &exec_type)
Convenience function for performing execution of MOOSE systems.
virtual std::vector< VariableName > getVariableNames()
Returns a list of all the variables in the problem (both from the NL and Aux systems.
virtual Real computeResidualL2Norm() override
Compute the residual of Ax - Bx.
Definition: EigenProblem.C:347
Preconditioned Jacobian-free Newton Krylov.
Definition: MooseTypes.h:775
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:604
const bool & _solve
Whether or not to actually solve the nonlinear system.
NonlinearSystemBase * _current_nl_sys
The current nonlinear system that we are solving.
void setCurrentNonlinearSystem(const unsigned int nl_sys_num)
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
void createTagVectors()
Create extra tagged vectors and matrices.
virtual void init() override
Definition: EigenProblem.C:612
std::shared_ptr< AuxiliarySystem > _aux
The auxiliary system.
void computeResidualAB(const NumericVector< Number > &soln, NumericVector< Number > &residualA, NumericVector< Number > &residualB, TagID tagA, TagID tagB)
Form two vetors, where each is associated with one tag, through one element-loop. ...
Definition: EigenProblem.C:312
virtual MooseVariableScalar & getScalarVariable(const THREAD_ID tid, const std::string &var_name) override
Returns the scalar variable reference from whichever system contains it.
void computeMatricesTags(const NumericVector< Number > &soln, const std::vector< std::unique_ptr< SparseMatrix< Number >>> &jacobians, const std::set< TagID > &tags)
Form several matrices simultaneously.
Definition: EigenProblem.C:195
std::vector< VectorTag > getVectorTags(const std::set< TagID > &tag_ids) const
Definition: SubProblem.C:149
registerMooseObject("MooseApp", EigenProblem)
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:69
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
virtual void checkProblemIntegrity()
Method called to perform a series of sanity checks before a simulation is run.
Nonlinear inverse power.
Definition: MooseTypes.h:773
Real _initial_eigenvalue
A value used for initial normalization.
Definition: EigenProblem.h:276
unsigned int _active_eigen_index
Which eigenvalue is used to compute residual.
Definition: EigenProblem.h:252
const PostprocessorValue & getPostprocessorValueByName(const PostprocessorName &name, std::size_t t_index=0) const
Get a read-only reference to the value associated with a Postprocessor that exists.
virtual std::map< TagName, TagID > & getMatrixTags()
Return all matrix tags in the system, where a tag is represented by a map from name to ID...
Definition: SubProblem.h:215
virtual void initNullSpaceVectors(const InputParameters &parameters, std::vector< std::shared_ptr< NonlinearSystemBase >> &nl)
Executioner * getExecutioner() const
Retrieve the Executioner for this App.
Definition: MooseApp.C:1482
virtual void solve() override=0
Solve the system (using libMesh magic)
void solveSetup()
Calls the timestepSetup function for each of the output objects.
const ExecFlagType EXEC_PRE_DISPLACE
Definition: Moose.C:44
const std::vector< NonlinearSystemName > _nl_sys_names
The nonlinear system names.
const ExecFlagType EXEC_NONLINEAR
Definition: Moose.C:30
std::set< TagID > _fe_matrix_tags
void scaleEigenvector(const Real scaling_factor)
Scale eigenvector.
Definition: EigenProblem.C:399
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Class for containing MooseEnum item information.
Definition: MooseEnumItem.h:18
void setFreeNonlinearPowerIterations(unsigned int free_power_iterations)
Set SLEPc/PETSc options to trigger free power iteration.
Definition: SlepcSupport.C:350
void postScaleEigenVector()
Normalize eigen vector.
Definition: EigenProblem.C:433
bool relativeFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within a relative tolerance.
Definition: MooseUtils.h:454
Jacobian-free Newton Krylov.
Definition: MooseTypes.h:777
virtual bool nlConverged(const unsigned int nl_sys_num) override
Definition: EigenProblem.C:626
Non-Hermitian.
Definition: MooseTypes.h:786
std::set< TagID > _fe_vector_tags
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
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...
std::shared_ptr< DisplacedProblem > _displaced_problem
const InputParameters & parameters() const
Get the parameters of the object.
Real _normal_factor
Postprocessor target value.
Definition: EigenProblem.h:272
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
static InputParameters validParams()
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
std::optional< PostprocessorName > _bx_norm_name
The name of the Postprocessor providing the Bx norm.
Definition: EigenProblem.h:292
Problem for solving eigenvalue problems.
Definition: EigenProblem.h:21
bool bxNormProvided() const
Whether a Bx norm postprocessor has been provided.
Definition: EigenProblem.h:235
virtual void checkProblemIntegrity() override
Method called to perform a series of sanity checks before a simulation is run.
Definition: EigenProblem.C:485
EigenProblemType
Type of the eigen problem.
Definition: MooseTypes.h:783
bool doFreePowerIteration() const
Whether or not we are doing free power iteration.
Definition: EigenProblem.h:82
void setEigenproblemType(Moose::EigenProblemType eigen_problem_type)
Set eigen problem type.
Number initial_value(const Point &, const Parameters &, const std::string &, const std::string &)
void ErrorVector unsigned int
virtual void solve(const unsigned int nl_sys_num) override
Definition: EigenProblem.C:515
auto index_range(const T &sizable)
Generalized Hermitian.
Definition: MooseTypes.h:787
OutputWarehouse & getOutputWarehouse()
Get the OutputWarehouse objects.
Definition: MooseApp.C:1772
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:247
virtual void computeJacobianTags(const std::set< TagID > &tags)
Form multiple matrices, and each is associated with a tag.
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:165
const ExecFlagType EXEC_INITIAL
Definition: Moose.C:28