Loading [MathJax]/extensions/tex2jax.js
https://mooseframework.inl.gov
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
EigenProblem.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 "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 #include "UserObject.h"
23 
24 // libMesh includes
25 #include "libmesh/system.h"
26 #include "libmesh/eigen_solver.h"
27 #include "libmesh/enum_eigen_solver_type.h"
28 
29 // Needed for LIBMESH_CHECK_ERR
31 
33 
36 {
38  params.addClassDescription("Problem object for solving an eigenvalue problem.");
39  params.addParam<bool>("negative_sign_eigen_kernel",
40  true,
41  "Whether or not to use a negative sign for eigenvalue kernels. "
42  "Using a negative sign makes eigenvalue kernels consistent with "
43  "a nonlinear solver");
44 
45  params.addParam<unsigned int>(
46  "active_eigen_index",
47  0,
48  "Which eigenvector is used to compute residual and also associated to nonlinear variable");
49  params.addParam<PostprocessorName>("bx_norm", "A postprocessor describing the norm of Bx");
50 
51  params.addParamNamesToGroup("negative_sign_eigen_kernel active_eigen_index bx_norm",
52  "Eigenvalue solve");
53 
54  return params;
55 }
56 
58  : FEProblemBase(parameters)
59 #ifdef LIBMESH_HAVE_SLEPC
60  ,
61  // By default, we want to compute an eigenvalue only (smallest or largest)
62  _n_eigen_pairs_required(1),
63  _generalized_eigenvalue_problem(false),
64  _negative_sign_eigen_kernel(getParam<bool>("negative_sign_eigen_kernel")),
65  _active_eigen_index(getParam<unsigned int>("active_eigen_index")),
66  _do_free_power_iteration(false),
67  _output_inverse_eigenvalue(false),
68  _on_linear_solver(false),
69  _matrices_formed(false),
70  _constant_matrices(false),
71  _has_normalization(false),
72  _normal_factor(1.0),
73  _first_solve(declareRestartableData<bool>("first_solve", true)),
74  _bx_norm_name(isParamValid("bx_norm")
75  ? std::make_optional(getParam<PostprocessorName>("bx_norm"))
76  : std::nullopt)
77 #endif
78 {
79 #ifdef LIBMESH_HAVE_SLEPC
80  if (_nl_sys_names.size() > 1)
81  paramError("nl_sys_names",
82  "eigen problems do not currently support multiple nonlinear eigen systems");
83  if (_linear_sys_names.size())
84  paramError("linear_sys_names", "EigenProblem only works with a single nonlinear eigen system");
85 
86  for (const auto i : index_range(_nl_sys_names))
87  {
88  const auto & sys_name = _nl_sys_names[i];
89  auto & nl = _nl[i];
90  nl = std::make_shared<NonlinearEigenSystem>(*this, sys_name);
92  _current_nl_sys = nl.get();
94  }
95 
96  _aux = std::make_shared<AuxiliarySystem>(*this, "aux0");
97 
99 
101 
102  es().parameters.set<EigenProblem *>("_eigen_problem") = this;
103 #else
104  mooseError("Need to install SLEPc to solve eigenvalue problems, please reconfigure\n");
105 #endif /* LIBMESH_HAVE_SLEPC */
106 
107  // SLEPc older than 3.13.0 can not take initial guess from moose
108 #if PETSC_RELEASE_LESS_THAN(3, 13, 0)
110  "Please use SLEPc-3.13.0 or higher. Old versions of SLEPc likely produce bad convergence");
111 #endif
112  // Create extra vectors and matrices if any
114 
115  // Create extra solution vectors if any
117 }
118 
119 #ifdef LIBMESH_HAVE_SLEPC
120 void
122 {
123  switch (eigen_problem_type)
124  {
126  _nl_eigen->sys().set_eigenproblem_type(libMesh::HEP);
128  break;
129 
131  _nl_eigen->sys().set_eigenproblem_type(libMesh::NHEP);
133  break;
134 
136  _nl_eigen->sys().set_eigenproblem_type(libMesh::GHEP);
138  break;
139 
141  _nl_eigen->sys().set_eigenproblem_type(libMesh::GHIEP);
143  break;
144 
146  _nl_eigen->sys().set_eigenproblem_type(libMesh::GNHEP);
148  break;
149 
151  mooseError("libMesh does not support EPT_POS_GEN_NON_HERMITIAN currently \n");
152  break;
153 
156  break;
157 
158  default:
159  mooseError("Unknown eigen solver type \n");
160  }
161 }
162 
163 void
165 {
166  if (exec_type == EXEC_INITIAL && !_app.isRestarting())
167  // we need to scale the solution properly and we can do this only all initial setup of
168  // depending objects by the residual evaluations has been done to this point.
169  preScaleEigenVector(std::pair<Real, Real>(_initial_eigenvalue, 0));
170 
171  FEProblemBase::execute(exec_type);
172 }
173 
174 void
176  SparseMatrix<Number> & jacobian,
177  TagID tag)
178 {
179  TIME_SECTION("computeJacobianTag", 3);
180 
181  // Disassociate the default tags because we will associate vectors with only the
182  // specific system tags that we need for this instance
183  _nl_eigen->disassociateDefaultMatrixTags();
184 
185  // Clear FE tags and first add the specific tag associated with the Jacobian
186  _fe_matrix_tags.clear();
187  _fe_matrix_tags.insert(tag);
188 
189  // Add any other user-added matrix tags if they have associated matrices
190  const auto & matrix_tags = getMatrixTags();
191  for (const auto & matrix_tag : matrix_tags)
192  if (_nl_eigen->hasMatrix(matrix_tag.second))
193  _fe_matrix_tags.insert(matrix_tag.second);
194 
195  _nl_eigen->setSolution(soln);
196 
197  _nl_eigen->associateMatrixToTag(jacobian, tag);
198 
201 
202  _nl_eigen->disassociateMatrixFromTag(jacobian, tag);
203 }
204 
205 void
207  const std::vector<SparseMatrix<Number> *> & jacobians,
208  const std::set<TagID> & tags)
209 {
210  TIME_SECTION("computeMatricesTags", 3);
211 
212  if (jacobians.size() != tags.size())
213  mooseError("The number of matrices ",
214  jacobians.size(),
215  " does not equal the number of tags ",
216  tags.size());
217 
218  // Disassociate the default tags because we will associate vectors with only the
219  // specific system tags that we need for this instance
220  _nl_eigen->disassociateDefaultMatrixTags();
221 
222  _fe_matrix_tags.clear();
223 
224  _nl_eigen->setSolution(soln);
225 
226  unsigned int i = 0;
227  for (auto tag : tags)
228  _nl_eigen->associateMatrixToTag(*(jacobians[i++]), tag);
229 
231  computeJacobianTags(tags);
232 
233  i = 0;
234  for (auto tag : tags)
235  _nl_eigen->disassociateMatrixFromTag(*(jacobians[i++]), tag);
236 }
237 
238 void
239 EigenProblem::computeJacobianBlocks(std::vector<JacobianBlock *> & blocks,
240  const unsigned int nl_sys_num)
241 {
242  TIME_SECTION("computeJacobianBlocks", 3);
243  setCurrentNonlinearSystem(nl_sys_num);
244 
245  if (_displaced_problem)
247 
249 
251 
252  _current_nl_sys->computeJacobianBlocks(blocks, {_nl_eigen->precondMatrixTag()});
253 
255 }
256 
257 void
259  SparseMatrix<Number> & jacobianA,
260  SparseMatrix<Number> & jacobianB,
261  TagID tagA,
262  TagID tagB)
263 {
264  TIME_SECTION("computeJacobianAB", 3);
265 
266  // Disassociate the default tags because we will associate vectors with only the
267  // specific system tags that we need for this instance
268  _nl_eigen->disassociateDefaultMatrixTags();
269 
270  // Clear FE tags and first add the specific tags associated with the Jacobian
271  _fe_matrix_tags.clear();
272  _fe_matrix_tags.insert(tagA);
273  _fe_matrix_tags.insert(tagB);
274 
275  // Add any other user-added matrix tags if they have associated matrices
276  const auto & matrix_tags = getMatrixTags();
277  for (const auto & matrix_tag : matrix_tags)
278  if (_nl_eigen->hasMatrix(matrix_tag.second))
279  _fe_matrix_tags.insert(matrix_tag.second);
280 
281  _nl_eigen->setSolution(soln);
282 
283  _nl_eigen->associateMatrixToTag(jacobianA, tagA);
284  _nl_eigen->associateMatrixToTag(jacobianB, tagB);
285 
288 
289  _nl_eigen->disassociateMatrixFromTag(jacobianA, tagA);
290  _nl_eigen->disassociateMatrixFromTag(jacobianB, tagB);
291 }
292 
293 void
295  NumericVector<Number> & residual,
296  TagID tag)
297 {
298  TIME_SECTION("computeResidualTag", 3);
299 
300  // Disassociate the default tags because we will associate vectors with only the
301  // specific system tags that we need for this instance
302  _nl_eigen->disassociateDefaultVectorTags();
303 
304  // add the specific tag associated with the residual
305  mooseAssert(_fe_vector_tags.empty(), "This should be empty indicating a clean starting state");
306  _fe_vector_tags.insert(tag);
307 
308  // Add any other user-added vector residual tags if they have associated vectors
309  const auto & residual_vector_tags = getVectorTags(Moose::VECTOR_TAG_RESIDUAL);
310  for (const auto & vector_tag : residual_vector_tags)
311  if (_nl_eigen->hasVector(vector_tag._id))
312  _fe_vector_tags.insert(vector_tag._id);
313 
314  _nl_eigen->associateVectorToTag(residual, tag);
315 
316  _nl_eigen->setSolution(soln);
317 
320  _fe_vector_tags.clear();
321 
322  _nl_eigen->disassociateVectorFromTag(residual, tag);
323 }
324 
325 void
327  NumericVector<Number> & residualA,
328  NumericVector<Number> & residualB,
329  TagID tagA,
330  TagID tagB)
331 {
332  TIME_SECTION("computeResidualAB", 3);
333 
334  // Disassociate the default tags because we will associate vectors with only the
335  // specific system tags that we need for this instance
336  _nl_eigen->disassociateDefaultVectorTags();
337 
338  // add the specific tags associated with the residual
339  mooseAssert(_fe_vector_tags.empty(), "This should be empty indicating a clean starting state");
340  _fe_vector_tags.insert(tagA);
341  _fe_vector_tags.insert(tagB);
342 
343  // Add any other user-added vector residual tags if they have associated vectors
344  const auto & residual_vector_tags = getVectorTags(Moose::VECTOR_TAG_RESIDUAL);
345  for (const auto & vector_tag : residual_vector_tags)
346  if (_nl_eigen->hasVector(vector_tag._id))
347  _fe_vector_tags.insert(vector_tag._id);
348 
349  _nl_eigen->associateVectorToTag(residualA, tagA);
350  _nl_eigen->associateVectorToTag(residualB, tagB);
351 
352  _nl_eigen->setSolution(soln);
353 
355  _fe_vector_tags.clear();
356 
357  _nl_eigen->disassociateVectorFromTag(residualA, tagA);
358  _nl_eigen->disassociateVectorFromTag(residualB, tagB);
359 }
360 
361 Real
363 {
364  computeResidualAB(*_nl_eigen->currentSolution(),
365  _nl_eigen->residualVectorAX(),
366  _nl_eigen->residualVectorBX(),
367  _nl_eigen->nonEigenVectorTag(),
368  _nl_eigen->eigenVectorTag());
369 
370  Real eigenvalue = 1.0;
371 
372  if (_active_eigen_index < _nl_eigen->getNumConvergedEigenvalues())
373  eigenvalue = _nl_eigen->getConvergedEigenvalue(_active_eigen_index).first;
374 
375  // Scale BX with eigenvalue
376  _nl_eigen->residualVectorBX() *= eigenvalue;
377 
378  // Compute entire residual
380  _nl_eigen->residualVectorAX() += _nl_eigen->residualVectorBX();
381  else
382  _nl_eigen->residualVectorAX() -= _nl_eigen->residualVectorBX();
383 
384  return _nl_eigen->residualVectorAX().l2_norm();
385 }
386 
387 void
388 EigenProblem::adjustEigenVector(const Real value, bool scaling)
389 {
390  std::vector<VariableName> var_names = getVariableNames();
391  for (auto & vn : var_names)
392  {
393  MooseVariableBase * var = nullptr;
394  if (hasScalarVariable(vn))
395  var = &getScalarVariable(0, vn);
396  else
397  var = &getVariable(0, vn);
398  // Do operations for only eigen variable
399  if (var->eigen())
400  for (unsigned int vc = 0; vc < var->count(); ++vc)
401  {
402  std::set<dof_id_type> var_indices;
403  _nl_eigen->system().local_dof_indices(var->number() + vc, var_indices);
404  for (const auto & dof : var_indices)
405  _nl_eigen->solution().set(dof, scaling ? (_nl_eigen->solution()(dof) * value) : value);
406  }
407  }
408 
409  _nl_eigen->solution().close();
410  _nl_eigen->update();
411 }
412 
413 void
414 EigenProblem::scaleEigenvector(const Real scaling_factor)
415 {
416  adjustEigenVector(scaling_factor, true);
417 }
418 
419 void
420 EigenProblem::initEigenvector(const Real initial_value)
421 {
422  // Yaqi's note: the following code will set a flat solution for lagrange and
423  // constant monomial variables. For the first or higher order elemental variables,
424  // the solution is not flat. Fortunately, the initial guess does not affect
425  // the final solution as long as it is not perpendicular to the true solution.
426  // We, in general, do not need to worry about that.
427 
429 }
430 
431 void
432 EigenProblem::preScaleEigenVector(const std::pair<Real, Real> & eig)
433 {
434  // pre-scale the solution to make sure ||Bx||_2 is equal to inverse of eigenvalue
436  *_nl_eigen->currentSolution(), _nl_eigen->residualVectorBX(), _nl_eigen->eigenVectorTag());
437 
438  // Eigenvalue magnitude
439  Real v = std::sqrt(eig.first * eig.first + eig.second * eig.second);
440  // Scaling factor
441  Real factor = 1 / v / (bxNormProvided() ? formNorm() : _nl_eigen->residualVectorBX().l2_norm());
442  // Scale eigenvector
443  if (!MooseUtils::absoluteFuzzyEqual(factor, 1))
444  scaleEigenvector(factor);
445 }
446 
447 void
449 {
450  if (_has_normalization)
451  {
452  Real v;
454  {
455  if (_active_eigen_index >= _nl_eigen->getNumConvergedEigenvalues())
456  mooseError("Number of converged eigenvalues ",
457  _nl_eigen->getNumConvergedEigenvalues(),
458  " but you required eigenvalue ",
460 
461  // when normal factor is not provided, we use the inverse of the norm of
462  // the active eigenvalue for normalization
463  auto eig = _nl_eigen->getAllConvergedEigenvalues()[_active_eigen_index];
464  v = 1 / std::sqrt(eig.first * eig.first + eig.second * eig.second);
465  }
466  else
467  v = _normal_factor;
468 
470 
471  // We scale SLEPc eigen vector here, so we need to scale it back for optimal
472  // convergence if we call EPS solver again
473  mooseAssert(v != 0., "normal factor can not be zero");
474 
475  unsigned int itr = 0;
476 
477  while (!MooseUtils::relativeFuzzyEqual(v, c))
478  {
479  // If postprocessor is not defined on eigen variables, scaling might not work
480  if (itr > 10)
481  mooseError("Can not scale eigenvector to the required factor ",
482  v,
483  " please check if postprocessor is defined on only eigen variables");
484 
485  mooseAssert(c != 0., "postprocessor value used for scaling can not be zero");
486 
487  scaleEigenvector(v / c);
488 
489  // update all aux variables and user objects on linear
491 
493 
494  itr++;
495  }
496  }
497 }
498 
499 void
501 {
503  _nl_eigen->checkIntegrity();
504  if (_bx_norm_name)
505  {
507  paramWarning("bx_norm", "This parameter is only used for nonlinear solve types");
508  else if (auto & pp = getUserObjectBase(_bx_norm_name.value());
510  pp.paramError("execute_on",
511  "If providing the Bx norm, this postprocessor must execute on linear e.g. "
512  "during residual evaluations");
513  }
514 }
515 
516 void
517 EigenProblem::doFreeNonlinearPowerIterations(unsigned int free_power_iterations)
518 {
519  mooseAssert(_current_nl_sys, "This needs to be non-null");
520 
521  doFreePowerIteration(true);
522  // Set free power iterations
524 
525  // Call solver
528 
529  // Clear free power iterations
530  auto executioner = getMooseApp().getExecutioner();
531  if (executioner)
533  else
534  mooseError("There is no executioner for this moose app");
535 
536  doFreePowerIteration(false);
537 }
538 
539 void
540 EigenProblem::solve(const unsigned int nl_sys_num)
541 {
542 #if !PETSC_RELEASE_LESS_THAN(3, 12, 0)
543  // Master has the default database
544  if (!_app.isUltimateMaster())
545  LibmeshPetscCall(PetscOptionsPush(_petsc_option_data_base));
546 #endif
547 
548  setCurrentNonlinearSystem(nl_sys_num);
549 
550  if (_solve)
551  {
552  TIME_SECTION("solve", 1);
553 
554  // Set necessary slepc callbacks
555  // We delay this call as much as possible because libmesh
556  // could rebuild matrices due to mesh changes or something else.
557  _nl_eigen->attachSLEPcCallbacks();
558 
559  // If there is an eigenvalue, we scale 1/|Bx| to eigenvalue
560  if (_active_eigen_index < _nl_eigen->getNumConvergedEigenvalues())
561  {
562  std::pair<Real, Real> eig = _nl_eigen->getConvergedEigenvalue(_active_eigen_index);
563  preScaleEigenVector(eig);
564  }
565 
566  if (isNonlinearEigenvalueSolver(nl_sys_num) &&
567  solverParams(nl_sys_num)._eigen_solve_type != Moose::EST_NONLINEAR_POWER)
568  {
569  // Let do an initial solve if a nonlinear eigen solver but not power is used.
570  // The initial solver is a Inverse Power, and it is used to compute a good initial
571  // guess for Newton
572  if (solverParams(nl_sys_num)._free_power_iterations && _first_solve)
573  {
574  _console << std::endl << " -------------------------------" << std::endl;
575  _console << " Free power iteration starts ..." << std::endl;
576  _console << " -------------------------------" << std::endl << std::endl;
577  doFreeNonlinearPowerIterations(solverParams(nl_sys_num)._free_power_iterations);
578  _first_solve = false;
579  }
580 
581  // Let us do extra power iterations here if necessary
582  if (solverParams(nl_sys_num)._extra_power_iterations)
583  {
584  _console << std::endl << " --------------------------------------" << std::endl;
585  _console << " Extra Free power iteration starts ..." << std::endl;
586  _console << " --------------------------------------" << std::endl << std::endl;
587  doFreeNonlinearPowerIterations(solverParams(nl_sys_num)._extra_power_iterations);
588  }
589  }
590 
591  // We print this for only nonlinear solver
592  if (isNonlinearEigenvalueSolver(nl_sys_num))
593  {
594  _console << std::endl << " -------------------------------------" << std::endl;
595 
596  if (solverParams(nl_sys_num)._eigen_solve_type != Moose::EST_NONLINEAR_POWER)
597  _console << " Nonlinear Newton iteration starts ..." << std::endl;
598  else
599  _console << " Nonlinear power iteration starts ..." << std::endl;
600 
601  _console << " -------------------------------------" << std::endl << std::endl;
602  }
603 
606 
607  // with PJFNKMO solve type, we need to evaluate the linear objects to bring them up-to-date
608  if (solverParams(nl_sys_num)._eigen_solve_type == Moose::EST_PJFNKMO)
610 
611  // Scale eigen vector if users ask
613  }
614 
615 #if !PETSC_RELEASE_LESS_THAN(3, 12, 0)
616  if (!_app.isUltimateMaster())
617  LibmeshPetscCall(PetscOptionsPop());
618 #endif
619 
620  // sync solutions in displaced problem
621  if (_displaced_problem)
622  _displaced_problem->syncSolutions();
623 
624  // Reset the matrix flag, so that we reform matrix in next picard iteration
625  _matrices_formed = false;
626 }
627 
628 void
629 EigenProblem::setNormalization(const PostprocessorName & pp, const Real value)
630 {
631  _has_normalization = true;
632  _normalization = pp;
634 }
635 
636 void
638 {
639 #if PETSC_RELEASE_LESS_THAN(3, 13, 0)
640  // Prior to Slepc 3.13 we did not have a nonlinear eigenvalue solver so we must always assemble
641  // before the solve
642  _nl_eigen->sys().attach_assemble_function(Moose::assemble_matrix);
643 #else
644  mooseAssert(
645  numNonlinearSystems() == 1,
646  "We should have errored during construction if we had more than one nonlinear system");
647  mooseAssert(numLinearSystems() == 0,
648  "We should have errored during construction if we had any linear systems");
650  // We don't need to assemble before the solve
651  _nl_eigen->sys().assemble_before_solve = false;
652  else
653  _nl_eigen->sys().attach_assemble_function(Moose::assemble_matrix);
654 
655  // If matrix_free=true, this tells Libmesh to use shell matrices
656  _nl_eigen->sys().use_shell_matrices(solverParams(0)._eigen_matrix_free &&
657  !solverParams(0)._eigen_matrix_vector_mult);
658  // We need to tell libMesh if we are using a shell preconditioning matrix
659  _nl_eigen->sys().use_shell_precond_matrix(solverParams(0)._precond_matrix_free);
660 #endif
661 
663 }
664 
665 bool
667 {
668  if (_solve)
669  return _nl_eigen->converged();
670  else
671  return true;
672 }
673 
674 bool
675 EigenProblem::isNonlinearEigenvalueSolver(const unsigned int eigen_sys_num) const
676 {
677  const auto & solver_params = solverParams(eigen_sys_num);
678  return solver_params._eigen_solve_type == Moose::EST_NONLINEAR_POWER ||
679  solver_params._eigen_solve_type == Moose::EST_NEWTON ||
680  solver_params._eigen_solve_type == Moose::EST_PJFNK ||
681  solver_params._eigen_solve_type == Moose::EST_JFNK ||
682  solver_params._eigen_solve_type == Moose::EST_PJFNKMO;
683 }
684 
685 void
687 {
689 }
690 
691 Real
693 {
694  mooseAssert(_bx_norm_name,
695  "We should not get here unless a bx_norm postprocessor has been provided");
697 }
698 
699 std::string
700 EigenProblem::solverTypeString(const unsigned int solver_sys_num)
701 {
702  return Moose::stringify(solverParams(solver_sys_num)._eigen_solve_type);
703 }
704 #endif
Nonlinear eigenvalue system to be solved.
Generalized Non-Hermitian.
Definition: MooseTypes.h:870
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:294
static InputParameters validParams()
Definition: EigenProblem.C:35
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:260
Generalized Hermitian indefinite.
Definition: MooseTypes.h:869
Newton-based eigensolver with an assembled Jacobian matrix (fully coupled by default) ...
Definition: MooseTypes.h:855
bool isUltimateMaster() const
Whether or not this app is the ultimate master app.
Definition: MooseApp.h:847
virtual void initPetscOutputAndSomeSolverSettings() override
Hook up monitors for SNES and KSP.
Definition: EigenProblem.C:686
PostprocessorName _normalization
Postprocessor used to compute a factor from eigenvector.
Definition: EigenProblem.h:266
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:372
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:239
unsigned int TagID
Definition: MooseTypes.h:206
virtual std::size_t numNonlinearSystems() const override
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:1101
virtual void init() override
The same as PJFNK except that matrix-vector multiplication is employed to replace residual evaluation...
Definition: MooseTypes.h:857
void initEigenvector(const Real initial_value)
For nonlinear eigen solver, a good initial value can help convergence.
Definition: EigenProblem.C:420
void clearFreeNonlinearPowerIterations(const InputParameters &params)
Definition: SlepcSupport.C:379
virtual void newAssemblyArray(std::vector< std::shared_ptr< SolverSystem >> &solver_systems)
bool _has_normalization
Whether or not we normalize eigenvector.
Definition: EigenProblem.h:264
EigenProblem(const InputParameters &parameters)
Definition: EigenProblem.C:57
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:164
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:388
void doFreeNonlinearPowerIterations(unsigned int free_power_iterations)
Do some free/extra power iterations.
Definition: EigenProblem.C:517
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::vector< std::shared_ptr< SolverSystem > > _solver_systems
Combined container to base pointer of every solver system.
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:872
bool _negative_sign_eigen_kernel
Whether or not use negative sign for Bx.
Definition: EigenProblem.h:246
bool isRestarting() const
Whether or not this is a "restart" calculation.
Definition: MooseApp.C:1645
Generalized Non-Hermitian with positive (semi-)definite B.
Definition: MooseTypes.h:871
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:432
MooseApp & getMooseApp() const
Get the MooseApp this class is associated with.
Definition: MooseBase.h:45
bool isNonlinearEigenvalueSolver(unsigned int eigen_sys_num) const
Definition: EigenProblem.C:675
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)
std::shared_ptr< NonlinearEigenSystem > _nl_eigen
Definition: EigenProblem.h:242
bool eigen() const
Whether or not this variable operates on an eigen kernel.
bool _generalized_eigenvalue_problem
Definition: EigenProblem.h:241
void update()
Update the system (doing libMesh magic)
Definition: SystemBase.C:1216
Real formNorm()
Form the Bx norm.
Definition: EigenProblem.C:692
bool & _first_solve
A flag to indicate if it is the first time calling the solve.
Definition: EigenProblem.h:271
std::vector< std::shared_ptr< NonlinearSystemBase > > _nl
The nonlinear systems.
void createTagSolutions()
Create extra tagged solution vectors.
bool contains(const std::string &value) const
Methods for seeing if a value is set in the MultiMooseEnum.
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:362
Preconditioned Jacobian-free Newton Krylov.
Definition: MooseTypes.h:856
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
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:637
const ExecFlagEnum & getExecuteOnEnum() const
Return the execute on MultiMooseEnum for this object.
virtual libMesh::EquationSystems & es() override
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:326
virtual MooseVariableScalar & getScalarVariable(const THREAD_ID tid, const std::string &var_name) override
Returns the scalar variable reference from whichever system contains it.
std::vector< VectorTag > getVectorTags(const std::set< TagID > &tag_ids) const
Definition: SubProblem.C:173
registerMooseObject("MooseApp", EigenProblem)
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 ...
void assemble_matrix(EquationSystems &es, const std::string &system_name)
const ExecFlagType EXEC_LINEAR
Definition: Moose.C:29
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:64
virtual void checkProblemIntegrity()
Method called to perform a series of sanity checks before a simulation is run.
void computeMatricesTags(const NumericVector< Number > &soln, const std::vector< SparseMatrix< Number > *> &jacobians, const std::set< TagID > &tags)
Form several matrices simultaneously.
Definition: EigenProblem.C:206
Nonlinear inverse power.
Definition: MooseTypes.h:854
Real _initial_eigenvalue
A value used for initial normalization.
Definition: EigenProblem.h:273
unsigned int _active_eigen_index
Which eigenvalue is used to compute residual.
Definition: EigenProblem.h:249
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:249
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:1954
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:45
const std::vector< NonlinearSystemName > _nl_sys_names
The nonlinear system names.
const ExecFlagType EXEC_NONLINEAR
Definition: Moose.C:31
std::set< TagID > _fe_matrix_tags
void scaleEigenvector(const Real scaling_factor)
Scale eigenvector.
Definition: EigenProblem.C:414
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Class for containing MooseEnum item information.
Definition: MooseEnumItem.h:18
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
void setFreeNonlinearPowerIterations(unsigned int free_power_iterations)
Set SLEPc/PETSc options to trigger free power iteration.
Definition: SlepcSupport.C:364
void postScaleEigenVector()
Normalize eigen vector.
Definition: EigenProblem.C:448
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:484
T & set(const std::string &)
Jacobian-free Newton Krylov.
Definition: MooseTypes.h:858
const std::vector< LinearSystemName > _linear_sys_names
The linear system names.
Non-Hermitian.
Definition: MooseTypes.h:867
virtual std::string solverTypeString(unsigned int solver_sys_num=0) override
Return solver type as a human readable string.
Definition: EigenProblem.C:700
std::set< TagID > _fe_vector_tags
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
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...
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:269
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...
static InputParameters validParams()
virtual std::size_t numLinearSystems() const override
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:289
void paramWarning(const std::string &param, Args... args) const
Emits a warning prefixed with the file and line number of the given param (from the input file) along...
const UserObject & getUserObjectBase(const std::string &name, const THREAD_ID tid=0) const
Get the user object by its name.
Problem for solving eigenvalue problems.
Definition: EigenProblem.h:21
bool bxNormProvided() const
Whether a Bx norm postprocessor has been provided.
Definition: EigenProblem.h:232
virtual void checkProblemIntegrity() override
Method called to perform a series of sanity checks before a simulation is run.
Definition: EigenProblem.C:500
EigenProblemType
Type of the eigen problem.
Definition: MooseTypes.h:864
bool doFreePowerIteration() const
Whether or not we are doing free power iteration.
Definition: EigenProblem.h:79
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:540
auto index_range(const T &sizable)
Generalized Hermitian.
Definition: MooseTypes.h:868
OutputWarehouse & getOutputWarehouse()
Get the OutputWarehouse objects.
Definition: MooseApp.C:2250
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:258
void computeSystems(const ExecFlagType &type)
Do generic system computations.
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:175
virtual bool solverSystemConverged(const unsigned int solver_sys_num) override
Definition: EigenProblem.C:666
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