https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Functions | Variables
Moose::SlepcSupport Namespace Reference

Functions

InputParameters getSlepcValidParams (InputParameters &params)
 
InputParameters getSlepcEigenProblemValidParams ()
 Retrieve valid params that allow users to specify eigen problem configuration.
 
void storeSolveType (FEProblemBase &fe_problem, const InputParameters &params)
 Set solve type into eigen problem (solverParams)
 
void setEigenProblemSolverParams (EigenProblem &eigen_problem, const InputParameters &params)
 Retrieve eigen problem params from 'params', and then set these params into SolverParams.
 
void slepcSetOptions (EigenProblem &eigen_problem, SolverParams &solver_params, const InputParameters &params)
 Push all SLEPc/PETSc options into SLEPc/PETSc side.
 
void setSlepcEigenSolverTolerances (EigenProblem &eigen_problem, const SolverParams &solver_params, const InputParameters &params)
 Control eigen solver tolerances via SLEPc options.
 
void setFreeNonlinearPowerIterations (unsigned int free_power_iterations)
 Set SLEPc/PETSc options to trigger free power iteration.
 
void clearFreeNonlinearPowerIterations (const InputParameters &params)
 
void moosePetscSNESFormMatrixTag (SNES snes, Vec x, Mat eigen_mat, SparseMatrix< Number > &all_dofs_mat, void *ctx, TagID tag)
 Form matrix according to tag.
 
void moosePetscSNESFormMatricesTags (SNES snes, Vec x, std::vector< Mat > &eigen_mats, std::vector< SparseMatrix< Number > * > &all_dofs_mats, void *ctx, const std::set< TagID > &tags)
 Form multiple matrices for multiple tags.
 
PetscErrorCode mooseSlepcEigenFormJacobianA (SNES snes, Vec x, Mat jac, Mat pc, void *ctx)
 Form Jacobian matrix A.
 
PetscErrorCode mooseSlepcEigenFormJacobianB (SNES snes, Vec x, Mat jac, Mat pc, void *ctx)
 Form Jacobian matrix B.
 
PetscErrorCode mooseSlepcEigenFormFunctionA (SNES snes, Vec x, Vec r, void *ctx)
 Form function residual Ax.
 
PetscErrorCode mooseSlepcEigenFormFunctionB (SNES snes, Vec x, Vec r, void *ctx)
 Form function residual Bx.
 
PetscErrorCode mooseSlepcEigenFormFunctionAB (SNES snes, Vec x, Vec Ax, Vec Bx, void *ctx)
 Form function residual Ax-Bx.
 
PetscErrorCode mooseSlepcStoppingTest (EPS eps, PetscInt its, PetscInt max_it, PetscInt nconv, PetscInt nev, EPSConvergedReason *reason, void *ctx)
 A customized convergence checker.
 
PetscErrorCode mooseSlepcEPSGetSNES (EPS eps, SNES *snes)
 Retrieve SNES from EPS.
 
PetscErrorCode mooseSlepcEPSMonitor (EPS eps, PetscInt its, PetscInt nconv, PetscScalar *eigr, PetscScalar *eigi, PetscReal *errest, PetscInt nest, void *mctx)
 A customized solver monitor to print out eigenvalue.
 
PetscErrorCode mooseSlepcEPSSNESSetUpOptionPrefix (EPS eps)
 Get rid of prefix "-eps_power" for SNES, KSP, PC, etc.
 
PetscErrorCode mooseSlepcEPSSNESSetCustomizePC (EPS eps)
 Attach a customized PC.
 
PetscErrorCode mooseSlepcEPSSNESKSPSetPCSide (FEProblemBase &problem, EPS eps)
 Allow users to specify PC side.
 
void attachCallbacksToMat (EigenProblem &eigen_problem, Mat mat, bool eigen)
 Attach call backs to mat.
 
PetscErrorCode mooseMatMult_Eigen (Mat mat, Vec x, Vec y)
 Implement MatMult via function evaluation for Bx.
 
PetscErrorCode mooseMatMult_NonEigen (Mat mat, Vec x, Vec y)
 Implement MatMult via function evaluation for Ax.
 
void setOperationsForShellMat (EigenProblem &eigen_problem, Mat mat, bool eigen)
 Set operations to shell mat.
 
PETSC_EXTERN PetscErrorCode PCCreate_MoosePC (PC pc)
 Create a preconditioner from moose side.
 
PETSC_EXTERN PetscErrorCode registerPCToPETSc ()
 Let PETSc know there is a preconditioner.
 
PetscErrorCode PCDestroy_MoosePC (PC pc)
 Destroy preconditioner.
 
PetscErrorCode PCView_MoosePC (PC pc, PetscViewer viewer)
 View preconditioner.
 
PetscErrorCode PCApply_MoosePC (PC pc, Vec x, Vec y)
 Preconditioner application.
 
PetscErrorCode PCSetUp_MoosePC (PC pc)
 Setup preconditioner.
 
PetscErrorCode mooseSlepcEigenFormFunctionMFFD (void *ctx, Vec x, Vec r)
 Function call for MFFD.
 
void setEigenProblemOptions (SolverParams &solver_params, const MultiMooseEnum &dont_add_these_options)
 
void setWhichEigenPairsOptions (SolverParams &solver_params, const MultiMooseEnum &dont_add_these_options)
 
void setNewtonPetscOptions (SolverParams &solver_params, const InputParameters &params)
 
void setNonlinearPowerOptions (SolverParams &solver_params)
 
void setEigenSolverOptions (SolverParams &solver_params, const InputParameters &params)
 
PetscErrorCode mooseEPSFormMatrices (EigenProblem &eigen_problem, EPS eps, Vec x, void *ctx)
 
void moosePetscSNESFormFunction (SNES, Vec x, Vec r, void *ctx, TagID tag)
 
PetscErrorCode mooseSlepcEigenFormNorm (SNES, Vec, PetscReal *norm, void *ctx)
 

Variables

const int subspace_factor = 2
 

Function Documentation

◆ attachCallbacksToMat()

void Moose::SlepcSupport::attachCallbacksToMat ( EigenProblem eigen_problem,
Mat  mat,
bool  eigen 
)

Attach call backs to mat.

SLEPc solver will retrieve callbacks we attached here

Definition at line 1060 of file SlepcSupport.C.

1061{
1062 // Recall that we are solving the potentially nonlinear problem:
1063 // F(x) = A(x) - \lambda B(x) = 0
1064 //
1065 // To solve this, we can use Newton's method: J \Delta x = -F
1066 // Generally we will approximate J using matrix free methods. However, in order to solve the
1067 // linearized system efficiently, we typically will need preconditioning. Typically we will build
1068 // the preconditioner only from A, but we also have the option to include information from B
1069
1070 // Attach the Jacobian computation function. If \p mat is the "eigen" matrix corresponding to B,
1071 // then attach our JacobianB computation routine, else the matrix corresponds to A, and we attach
1072 // the JacobianA computation routine
1073 LibmeshPetscCallA(
1074 eigen_problem.comm().get(),
1075 PetscObjectComposeFunction((PetscObject)mat,
1076 "formJacobian",
1078 : Moose::SlepcSupport::mooseSlepcEigenFormJacobianA));
1079
1080 // Attach the residual computation function. If \p mat is the "eigen" matrix corresponding to B,
1081 // then attach our FunctionB computation routine, else the matrix corresponds to A, and we attach
1082 // the FunctionA computation routine
1083 LibmeshPetscCallA(
1084 eigen_problem.comm().get(),
1085 PetscObjectComposeFunction((PetscObject)mat,
1086 "formFunction",
1088 : Moose::SlepcSupport::mooseSlepcEigenFormFunctionA));
1089
1090 // It's also beneficial to be able to evaluate both A and B residuals at once
1091 LibmeshPetscCallA(eigen_problem.comm().get(),
1092 PetscObjectComposeFunction((PetscObject)mat,
1093 "formFunctionAB",
1095
1096 // Users may choose to provide a custom measure of the norm of B (Bx for a linear system)
1097 if (eigen_problem.bxNormProvided())
1098 LibmeshPetscCallA(eigen_problem.comm().get(),
1099 PetscObjectComposeFunction((PetscObject)mat,
1100 "formNorm",
1102
1103 // Finally we need to attach the "context" object, which is our EigenProblem, to the matrices so
1104 // that eventually when we get callbacks from SLEPc we can call methods on the EigenProblem
1105 PetscContainer container;
1106 LibmeshPetscCallA(eigen_problem.comm().get(),
1107 PetscContainerCreate(eigen_problem.comm().get(), &container));
1108 LibmeshPetscCallA(eigen_problem.comm().get(),
1109 PetscContainerSetPointer(container, &eigen_problem));
1110 LibmeshPetscCallA(
1111 eigen_problem.comm().get(),
1112 PetscObjectCompose((PetscObject)mat, "formJacobianCtx", (PetscObject)container));
1113 LibmeshPetscCallA(
1114 eigen_problem.comm().get(),
1115 PetscObjectCompose((PetscObject)mat, "formFunctionCtx", (PetscObject)container));
1116 if (eigen_problem.bxNormProvided())
1117 LibmeshPetscCallA(eigen_problem.comm().get(),
1118 PetscObjectCompose((PetscObject)mat, "formNormCtx", (PetscObject)container));
1119
1120 LibmeshPetscCallA(eigen_problem.comm().get(), PetscContainerDestroy(&container));
1121}
bool bxNormProvided() const
Whether a Bx norm postprocessor has been provided.
const Parallel::Communicator & comm() const
PetscErrorCode mooseSlepcEigenFormNorm(SNES, Vec, PetscReal *norm, void *ctx)
PetscErrorCode mooseSlepcEigenFormFunctionB(SNES snes, Vec x, Vec r, void *ctx)
Form function residual Bx.
PetscErrorCode mooseSlepcEigenFormFunctionAB(SNES snes, Vec x, Vec Ax, Vec Bx, void *ctx)
Form function residual Ax-Bx.
PetscErrorCode mooseSlepcEigenFormJacobianA(SNES snes, Vec x, Mat jac, Mat pc, void *ctx)
Form Jacobian matrix A.
PetscErrorCode mooseSlepcEigenFormFunctionA(SNES snes, Vec x, Vec r, void *ctx)
Form function residual Ax.
PetscErrorCode mooseSlepcEigenFormJacobianB(SNES snes, Vec x, Mat jac, Mat pc, void *ctx)
Form Jacobian matrix B.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...

Referenced by NonlinearEigenSystem::attachSLEPcCallbacks().

◆ clearFreeNonlinearPowerIterations()

void Moose::SlepcSupport::clearFreeNonlinearPowerIterations ( const InputParameters params)

Definition at line 417 of file SlepcSupport.C.

418{
419 Moose::PetscSupport::setSinglePetscOption("-eps_power_update", "1");
422 stringify(params.get<unsigned int>("nl_max_its")));
424 stringify(params.get<Real>("nl_rel_tol")));
425 Moose::PetscSupport::setSinglePetscOption("-eps_tol", stringify(params.get<Real>("eigen_tol")));
426}
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
void setSinglePetscOption(const std::string &name, const std::string &value="", FEProblemBase *const problem=nullptr)
A wrapper function for dealing with different versions of PetscOptionsSetValue.

Referenced by EigenProblem::doFreeNonlinearPowerIterations().

◆ getSlepcEigenProblemValidParams()

InputParameters Moose::SlepcSupport::getSlepcEigenProblemValidParams ( )

Retrieve valid params that allow users to specify eigen problem configuration.

Definition at line 64 of file SlepcSupport.C.

65{
67
68 // We are solving a Non-Hermitian eigenvalue problem by default
69 MooseEnum eigen_problem_type("HERMITIAN NON_HERMITIAN GEN_HERMITIAN GEN_NON_HERMITIAN "
70 "GEN_INDEFINITE POS_GEN_NON_HERMITIAN SLEPC_DEFAULT",
71 "GEN_NON_HERMITIAN");
72 params.addParam<MooseEnum>(
73 "eigen_problem_type",
74 eigen_problem_type,
75 "Type of the eigenvalue problem we are solving "
76 "HERMITIAN: Hermitian "
77 "NON_HERMITIAN: Non-Hermitian "
78 "GEN_HERMITIAN: Generalized Hermitian "
79 "GEN_NON_HERMITIAN: Generalized Non-Hermitian "
80 "GEN_INDEFINITE: Generalized indefinite Hermitian "
81 "POS_GEN_NON_HERMITIAN: Generalized Non-Hermitian with positive (semi-)definite B "
82 "SLEPC_DEFAULT: Use whatever SLEPC has by default ");
83
84 // Which eigenvalues are we interested in
85 MooseEnum which_eigen_pairs("LARGEST_MAGNITUDE SMALLEST_MAGNITUDE LARGEST_REAL SMALLEST_REAL "
86 "LARGEST_IMAGINARY SMALLEST_IMAGINARY TARGET_MAGNITUDE TARGET_REAL "
87 "TARGET_IMAGINARY ALL_EIGENVALUES SLEPC_DEFAULT");
88 params.addParam<MooseEnum>("which_eigen_pairs",
89 which_eigen_pairs,
90 "Which eigenvalue pairs to obtain from the solution "
91 "LARGEST_MAGNITUDE "
92 "SMALLEST_MAGNITUDE "
93 "LARGEST_REAL "
94 "SMALLEST_REAL "
95 "LARGEST_IMAGINARY "
96 "SMALLEST_IMAGINARY "
97 "TARGET_MAGNITUDE "
98 "TARGET_REAL "
99 "TARGET_IMAGINARY "
100 "ALL_EIGENVALUES "
101 "SLEPC_DEFAULT ");
102
103 params.addParam<unsigned int>("n_eigen_pairs", 1, "The number of eigen pairs");
104 params.addParam<unsigned int>("n_basis_vectors", 3, "The dimension of eigen subspaces");
105
106 params.addParam<Real>("eigen_tol", 1.0e-4, "Relative Tolerance for Eigen Solver");
107 params.addParam<unsigned int>("eigen_max_its", 10000, "Max Iterations for Eigen Solver");
108
109 params.addParam<Real>("l_abs_tol", 1e-50, "Absolute Tolerances for Linear Solver");
110
111 params.addParam<unsigned int>("free_power_iterations", 4, "The number of free power iterations");
112
113 params.addParam<unsigned int>(
114 "extra_power_iterations", 0, "The number of extra free power iterations");
115
117 "eigen_problem_type which_eigen_pairs n_eigen_pairs n_basis_vectors eigen_tol eigen_max_its "
118 "free_power_iterations extra_power_iterations",
119 "Eigen Solver");
120 params.addParamNamesToGroup("l_abs_tol", "Linear solver");
121
122 return params;
123}
InputParameters emptyInputParameters()
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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...
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.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55

Referenced by EigenProblemSolve::validParams().

◆ getSlepcValidParams()

InputParameters Moose::SlepcSupport::getSlepcValidParams ( InputParameters params)
Returns
InputParameters object containing the SLEPC related parameters

The output of this function should be added to the the parameters object of the overarching class

See also
EigenProblem

Definition at line 35 of file SlepcSupport.C.

36{
37 MooseEnum solve_type("POWER ARNOLDI KRYLOVSCHUR JACOBI_DAVIDSON "
38 "NONLINEAR_POWER NEWTON PJFNK PJFNKMO JFNK",
39 "PJFNK");
40 params.set<MooseEnum>("solve_type") = solve_type;
41
42 params.setDocString("solve_type",
43 "POWER: Power / Inverse / RQI "
44 "ARNOLDI: Arnoldi "
45 "KRYLOVSCHUR: Krylov-Schur "
46 "JACOBI_DAVIDSON: Jacobi-Davidson "
47 "NONLINEAR_POWER: Nonlinear Power "
48 "NEWTON: Newton "
49 "PJFNK: Preconditioned Jacobian-free Newton-Kyrlov"
50 "JFNK: Jacobian-free Newton-Kyrlov"
51 "PJFNKMO: Preconditioned Jacobian-free Newton-Kyrlov with Matrix Only");
52
53 // When the eigenvalue problems is reformed as a coupled nonlinear system,
54 // we use part of Jacobian as the preconditioning matrix.
55 // Because the difference between the Jacobian and the preconditioning matrix is not small,
56 // the linear solver KSP can not reduce the residual much. After several tests,
57 // we find 1e-2 is a reasonable choice.
58 params.set<Real>("l_tol") = 1e-2;
59
60 return params;
61}
void setDocString(const std::string &name, const std::string &doc)
Set the doc string of a parameter.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.

Referenced by EigenProblemSolve::validParams().

◆ mooseEPSFormMatrices()

PetscErrorCode Moose::SlepcSupport::mooseEPSFormMatrices ( EigenProblem eigen_problem,
EPS  eps,
Vec  x,
void *  ctx 
)

Definition at line 571 of file SlepcSupport.C.

572{
573 ST st;
574 Mat A, B;
575 PetscBool aisshell, bisshell;
577
578 if (eigen_problem.constantMatrices() && eigen_problem.wereMatricesFormed())
579 PetscFunctionReturn(PETSC_SUCCESS);
580
581 if (eigen_problem.onLinearSolver())
582 // We reach here during linear iteration when solve type is PJFNKMO.
583 // We will use the matrices assembled at the beginning of this Newton
584 // iteration for the following residual evaluation.
585 PetscFunctionReturn(PETSC_SUCCESS);
586
587 NonlinearEigenSystem & eigen_nl = eigen_problem.getCurrentNonlinearEigenSystem();
588 auto & sys = eigen_nl.sys();
589 SNES snes = eigen_nl.getSNES();
590 // Rest ST state so that we can retrieve matrices
591 LibmeshPetscCallQ(EPSGetST(eps, &st));
592 LibmeshPetscCallQ(STResetMatrixState(st));
593 LibmeshPetscCallQ(EPSGetOperators(eps, &A, &B));
594 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)A, MATSHELL, &aisshell));
595 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)B, MATSHELL, &bisshell));
596 if (aisshell || bisshell)
597 {
598 SETERRQ(PetscObjectComm((PetscObject)eps),
599 PETSC_ERR_ARG_INCOMP,
600 "A and B matrices can not be shell matrices when using PJFNKMO \n");
601 }
602 // Form A and B
603 std::vector<Mat> mats = {A, B};
604 std::vector<SparseMatrix<Number> *> libmesh_mats = {&sys.get_matrix_A(), &sys.get_matrix_B()};
606 snes, x, mats, libmesh_mats, ctx, {eigen_nl.nonEigenMatrixTag(), eigen_nl.eigenMatrixTag()});
607 eigen_problem.wereMatricesFormed(true);
608 PetscFunctionReturn(PETSC_SUCCESS);
609}
LibmeshPetscCallQ(DMMooseValidityCheck(dm))
PetscFunctionReturn(PETSC_SUCCESS)
PetscFunctionBegin
bool onLinearSolver() const
Whether or not we are in a linear solver iteration.
bool constantMatrices() const
Whether or not matrices are constant.
NonlinearEigenSystem & getCurrentNonlinearEigenSystem()
bool wereMatricesFormed() const
Whether or not constant matrices were already formed.
Nonlinear eigenvalue system to be solved.
virtual SNES getSNES() override
Retrieve snes from slepc eigen solver.
TagID nonEigenMatrixTag() const
Matrix tag ID of left hand side.
TagID eigenMatrixTag() const
Matrix tag ID of right hand side.
libMesh::CondensedEigenSystem & sys()
void moosePetscSNESFormMatricesTags(SNES snes, Vec x, std::vector< Mat > &eigen_mats, std::vector< SparseMatrix< Number > * > &all_dofs_mats, void *ctx, const std::set< TagID > &tags)
Form multiple matrices for multiple tags.

Referenced by mooseSlepcEigenFormFunctionA(), mooseSlepcEigenFormFunctionAB(), mooseSlepcEigenFormFunctionB(), and mooseSlepcEigenFormJacobianA().

◆ mooseMatMult_Eigen()

PetscErrorCode Moose::SlepcSupport::mooseMatMult_Eigen ( Mat  mat,
Vec  x,
Vec  y 
)

Implement MatMult via function evaluation for Bx.

Definition at line 1124 of file SlepcSupport.C.

1125{
1127 void * ctx = nullptr;
1128 LibmeshPetscCallQ(MatShellGetContext(mat, &ctx));
1129
1130 if (!ctx)
1131 mooseError("No context is set for shell matrix ");
1132
1133 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
1134 NonlinearEigenSystem & eigen_nl = eigen_problem->getCurrentNonlinearEigenSystem();
1135
1136 evaluateResidual(*eigen_problem, x, r, eigen_nl.eigenVectorTag());
1137
1138 if (eigen_problem->negativeSignEigenKernel())
1139 LibmeshPetscCallQ(VecScale(r, -1.));
1140
1141 PetscFunctionReturn(PETSC_SUCCESS);
1142}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
Problem for solving eigenvalue problems.
bool negativeSignEigenKernel() const
A flag indicates if a negative sign is used in eigen kernels.
TagID eigenVectorTag() const
Vector tag ID of right hand side.

Referenced by setOperationsForShellMat().

◆ mooseMatMult_NonEigen()

PetscErrorCode Moose::SlepcSupport::mooseMatMult_NonEigen ( Mat  mat,
Vec  x,
Vec  y 
)

Implement MatMult via function evaluation for Ax.

Definition at line 1145 of file SlepcSupport.C.

1146{
1148 void * ctx = nullptr;
1149 LibmeshPetscCallQ(MatShellGetContext(mat, &ctx));
1150
1151 if (!ctx)
1152 mooseError("No context is set for shell matrix ");
1153
1154 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
1155 NonlinearEigenSystem & eigen_nl = eigen_problem->getCurrentNonlinearEigenSystem();
1156
1157 evaluateResidual(*eigen_problem, x, r, eigen_nl.nonEigenVectorTag());
1158
1159 PetscFunctionReturn(PETSC_SUCCESS);
1160}
TagID nonEigenVectorTag() const
Vector tag ID of left hand side.

Referenced by setOperationsForShellMat().

◆ moosePetscSNESFormFunction()

void Moose::SlepcSupport::moosePetscSNESFormFunction ( SNES  ,
Vec  x,
Vec  r,
void *  ctx,
TagID  tag 
)

Definition at line 902 of file SlepcSupport.C.

903{
904 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
905 evaluateResidual(*eigen_problem, x, r, tag);
906}

Referenced by mooseSlepcEigenFormFunctionA(), and mooseSlepcEigenFormFunctionB().

◆ moosePetscSNESFormMatricesTags()

void Moose::SlepcSupport::moosePetscSNESFormMatricesTags ( SNES  snes,
Vec  x,
std::vector< Mat > &  eigen_mats,
std::vector< SparseMatrix< Number > * > &  all_dofs_mats,
void *  ctx,
const std::set< TagID > &  tags 
)

Form multiple matrices for multiple tags.

This function is conceptually the same as moosePetscSNESForMatrixTag() but allows passing in multiple matrices to be formed

Definition at line 710 of file SlepcSupport.C.

716{
717 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
718 auto & nl = eigen_problem->getCurrentNonlinearEigenSystem();
719 auto & sys = nl.sys();
720 auto & dof_map = sys.get_dof_map();
721
722#ifndef NDEBUG
723 for (const auto i : index_range(eigen_mats))
724 mooseAssert(!dof_map.n_constrained_dofs() ==
725 (eigen_mats[i] == cast_ptr<PetscMatrix<Number> *>(all_dofs_mats[i])->mat()),
726 "If we do not have constrained dofs, then mat and libmesh_mat should be the same. "
727 "Conversely, if we do have constrained dofs, they must be different");
728#endif
729
730 updateCurrentLocalSolution(sys, x);
731
732 for (auto * const all_dofs_mat : all_dofs_mats)
733 if (!eigen_problem->constJacobian())
734 all_dofs_mat->zero();
735
736 eigen_problem->computeMatricesTags(*sys.current_local_solution.get(), all_dofs_mats, tags);
737
738 if (dof_map.n_constrained_dofs())
739 for (const auto i : index_range(eigen_mats))
740 {
741 PetscMatrix<Number> wrapped_eigen_mat(eigen_mats[i], sys.comm());
742 sys.copy_super_to_sub(*all_dofs_mats[i], wrapped_eigen_mat);
743 }
744}
if(!dmm->_nl) SETERRQ(PETSC_COMM_WORLD
void computeMatricesTags(const NumericVector< Number > &soln, const std::vector< SparseMatrix< Number > * > &jacobians, const std::set< TagID > &tags)
Form several matrices simultaneously.
const DofMap & get_dof_map() const

Referenced by mooseEPSFormMatrices(), and mooseSlepcEigenFormJacobianA().

◆ moosePetscSNESFormMatrixTag()

void Moose::SlepcSupport::moosePetscSNESFormMatrixTag ( SNES  snes,
Vec  x,
Mat  eigen_mat,
SparseMatrix< Number > &  all_dofs_mat,
void *  ctx,
TagID  tag 
)

Form matrix according to tag.

Parameters
snesThe PETSc nonlinear solver context associated with the eigensolver
xThe current eigen solution vector from SLEPc. This vector will have a size corresponding to the number of unconstrained degrees of freedom
eigen_matThe matrix we want to form coming from SLEPc. As for x, this will be sized corresponding to the number of unconstrained degrees of freedom
all_dofs_matThis matrix corresponds to the "global" matrix, representing both unconstrained and constrained degrees of freedom. We will pass this matrix to MOOSE's assembly framework and then if the problem has constraints we will selectively copy the submatrix representing unconstrained dofs to eigen_mat. (Else this matrix and eigen_mat are the same so no copy is required)
ctxThe eigensolver context which corresponds to the MOOSE EigenProblem
tagThe MOOSE TagID for the matrix

Definition at line 679 of file SlepcSupport.C.

681{
682 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
683 auto & nl = eigen_problem->getCurrentNonlinearEigenSystem();
684 auto & sys = nl.sys();
685 auto & dof_map = sys.get_dof_map();
686
687#ifndef NDEBUG
688 auto & petsc_all_dofs_mat = cast_ref<PetscMatrix<Number> &>(all_dofs_mat);
689 mooseAssert(
690 !dof_map.n_constrained_dofs() == (eigen_mat == petsc_all_dofs_mat.mat()),
691 "If we do not have constrained dofs, then eigen_mat and all_dofs_mat should be the same. "
692 "Conversely, if we do have constrained dofs, they must be different");
693#endif
694
695 updateCurrentLocalSolution(sys, x);
696
697 if (!eigen_problem->constJacobian())
698 all_dofs_mat.zero();
699
700 eigen_problem->computeJacobianTag(*sys.current_local_solution.get(), all_dofs_mat, tag);
701
702 if (dof_map.n_constrained_dofs())
703 {
704 PetscMatrix<Number> wrapped_eigen_mat(eigen_mat, sys.comm());
705 sys.copy_super_to_sub(all_dofs_mat, wrapped_eigen_mat);
706 }
707}
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.
bool constJacobian() const
Returns _const_jacobian (whether a MOOSE object has specified that the Jacobian is the same as the pr...
virtual void zero()=0

Referenced by mooseSlepcEigenFormJacobianA(), and mooseSlepcEigenFormJacobianB().

◆ mooseSlepcEigenFormFunctionA()

PetscErrorCode Moose::SlepcSupport::mooseSlepcEigenFormFunctionA ( SNES  snes,
Vec  x,
Vec  r,
void *  ctx 
)

Form function residual Ax.

It is a SLEPc callback

Definition at line 909 of file SlepcSupport.C.

910{
912
913 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
914 NonlinearEigenSystem & eigen_nl = eigen_problem->getCurrentNonlinearEigenSystem();
915
916 if (eigen_problem->solverParams(eigen_nl.number())._eigen_matrix_vector_mult &&
917 (eigen_problem->onLinearSolver() || eigen_problem->constantMatrices()))
918 {
919 EPS eps = eigen_nl.getEPS();
920 Mat A;
921 ST st;
922
923 LibmeshPetscCallQ(mooseEPSFormMatrices(*eigen_problem, eps, x, ctx));
924
925 // Rest ST state so that we can restrieve matrices
926 LibmeshPetscCallQ(EPSGetST(eps, &st));
927 LibmeshPetscCallQ(STResetMatrixState(st));
928 LibmeshPetscCallQ(EPSGetOperators(eps, &A, NULL));
929
930 LibmeshPetscCallQ(MatMult(A, x, r));
931
932 PetscFunctionReturn(PETSC_SUCCESS);
933 }
934
935 moosePetscSNESFormFunction(snes, x, r, ctx, eigen_nl.nonEigenVectorTag());
936
937 PetscFunctionReturn(PETSC_SUCCESS);
938}
SolverParams & solverParams(unsigned int solver_sys_num=0)
Get the solver parameters.
virtual EPS getEPS()
Retrieve EPS (SLEPc eigen solver)
bool _eigen_matrix_vector_mult
unsigned int number() const
Gets the number of this system.
PetscErrorCode mooseEPSFormMatrices(EigenProblem &eigen_problem, EPS eps, Vec x, void *ctx)

Referenced by attachCallbacksToMat().

◆ mooseSlepcEigenFormFunctionAB()

PetscErrorCode Moose::SlepcSupport::mooseSlepcEigenFormFunctionAB ( SNES  snes,
Vec  x,
Vec  Ax,
Vec  Bx,
void *  ctx 
)

Form function residual Ax-Bx.

It is a SLEPc callback

Definition at line 983 of file SlepcSupport.C.

984{
986
987 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
988 NonlinearEigenSystem & eigen_nl = eigen_problem->getCurrentNonlinearEigenSystem();
989 auto & sys = eigen_nl.sys();
990 auto & dof_map = sys.get_dof_map();
991
992 if (eigen_problem->solverParams(eigen_nl.number())._eigen_matrix_vector_mult &&
993 (eigen_problem->onLinearSolver() || eigen_problem->constantMatrices()))
994 {
995 EPS eps = eigen_nl.getEPS();
996 ST st;
997 Mat A, B;
998
999 LibmeshPetscCallQ(mooseEPSFormMatrices(*eigen_problem, eps, x, ctx));
1000
1001 // Rest ST state so that we can restrieve matrices
1002 LibmeshPetscCallQ(EPSGetST(eps, &st));
1003 LibmeshPetscCallQ(STResetMatrixState(st));
1004
1005 LibmeshPetscCallQ(EPSGetOperators(eps, &A, &B));
1006
1007 LibmeshPetscCallQ(MatMult(A, x, Ax));
1008 LibmeshPetscCallQ(MatMult(B, x, Bx));
1009
1010 if (eigen_problem->negativeSignEigenKernel())
1011 LibmeshPetscCallQ(VecScale(Bx, -1.));
1012
1013 if (eigen_problem->bxNormProvided())
1014 {
1015 // User has provided a postprocessor. We need it updated
1016 updateCurrentLocalSolution(sys, x);
1017 eigen_problem->execute(EXEC_LINEAR);
1018 }
1019
1020 PetscFunctionReturn(PETSC_SUCCESS);
1021 }
1022
1023 updateCurrentLocalSolution(sys, x);
1024 auto AX = createWrappedResidual(sys, Ax);
1025 auto BX = createWrappedResidual(sys, Bx);
1026
1027 eigen_problem->computeResidualAB(*sys.current_local_solution.get(),
1028 *AX,
1029 *BX,
1030 eigen_nl.nonEigenVectorTag(),
1031 eigen_nl.eigenVectorTag());
1032
1033 AX->close();
1034 BX->close();
1035
1036 if (dof_map.n_constrained_dofs())
1037 {
1038 PetscVector<Number> sub_Ax(Ax, sys.comm());
1039 sys.copy_super_to_sub(*AX, sub_Ax);
1040 PetscVector<Number> sub_Bx(Bx, sys.comm());
1041 sys.copy_super_to_sub(*BX, sub_Bx);
1042 }
1043
1044 if (eigen_problem->negativeSignEigenKernel())
1045 LibmeshPetscCallQ(VecScale(Bx, -1.));
1046
1047 PetscFunctionReturn(PETSC_SUCCESS);
1048}
const ExecFlagType EXEC_LINEAR
Definition Moose.C:32
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.
virtual void execute(const ExecFlagType &exec_type) override
Convenience function for performing execution of MOOSE systems.

Referenced by attachCallbacksToMat().

◆ mooseSlepcEigenFormFunctionB()

PetscErrorCode Moose::SlepcSupport::mooseSlepcEigenFormFunctionB ( SNES  snes,
Vec  x,
Vec  r,
void *  ctx 
)

Form function residual Bx.

It is a SLEPc callback

Definition at line 941 of file SlepcSupport.C.

942{
944
945 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
946 NonlinearEigenSystem & eigen_nl = eigen_problem->getCurrentNonlinearEigenSystem();
947
948 if (eigen_problem->solverParams(eigen_nl.number())._eigen_matrix_vector_mult &&
949 (eigen_problem->onLinearSolver() || eigen_problem->constantMatrices()))
950 {
951 EPS eps = eigen_nl.getEPS();
952 ST st;
953 Mat B;
954
955 LibmeshPetscCallQ(mooseEPSFormMatrices(*eigen_problem, eps, x, ctx));
956
957 // Rest ST state so that we can restrieve matrices
958 LibmeshPetscCallQ(EPSGetST(eps, &st));
959 LibmeshPetscCallQ(STResetMatrixState(st));
960 LibmeshPetscCallQ(EPSGetOperators(eps, NULL, &B));
961
962 LibmeshPetscCallQ(MatMult(B, x, r));
963
964 if (eigen_problem->bxNormProvided())
965 {
966 // User has provided a postprocessor. We need it updated
967 updateCurrentLocalSolution(eigen_nl.sys(), x);
968 eigen_problem->execute(EXEC_LINEAR);
969 }
970 }
971 else
972 moosePetscSNESFormFunction(snes, x, r, ctx, eigen_nl.eigenVectorTag());
973
974 if (eigen_problem->negativeSignEigenKernel())
975 {
976 LibmeshPetscCallQ(VecScale(r, -1.));
977 }
978
979 PetscFunctionReturn(PETSC_SUCCESS);
980}

Referenced by attachCallbacksToMat().

◆ mooseSlepcEigenFormFunctionMFFD()

PetscErrorCode Moose::SlepcSupport::mooseSlepcEigenFormFunctionMFFD ( void *  ctx,
Vec  x,
Vec  r 
)

Function call for MFFD.

Definition at line 747 of file SlepcSupport.C.

748{
749 PetscErrorCode (*func)(SNES, Vec, Vec, void *);
750 void * fctx;
752
753 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
754 NonlinearEigenSystem & eigen_nl = eigen_problem->getCurrentNonlinearEigenSystem();
755 SNES snes = eigen_nl.getSNES();
756
757 eigen_problem->onLinearSolver(true);
758
759 LibmeshPetscCallQ(SNESGetFunction(snes, NULL, &func, &fctx));
760 if (fctx != ctx)
761 {
762 SETERRQ(
763 PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_INCOMP, "Contexts are not consistent \n");
764 }
765 LibmeshPetscCallQ((*func)(snes, x, r, ctx));
766
767 eigen_problem->onLinearSolver(false);
768
769 PetscFunctionReturn(PETSC_SUCCESS);
770}

Referenced by mooseSlepcEigenFormJacobianA().

◆ mooseSlepcEigenFormJacobianA()

PetscErrorCode Moose::SlepcSupport::mooseSlepcEigenFormJacobianA ( SNES  snes,
Vec  x,
Mat  jac,
Mat  pc,
void *  ctx 
)

Form Jacobian matrix A.

It is a SLEPc callback

Definition at line 773 of file SlepcSupport.C.

774{
775 PetscBool jisshell, pisshell;
776 PetscBool jismffd;
777
779
780 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
781 NonlinearEigenSystem & eigen_nl = eigen_problem->getCurrentNonlinearEigenSystem();
782 auto & sys = eigen_nl.sys();
783
784 // If both jacobian and preconditioning are shell matrices,
785 // and then assemble them and return
786 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)jac, MATSHELL, &jisshell));
787 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)jac, MATMFFD, &jismffd));
788
789 if (jismffd && eigen_problem->solverParams(eigen_nl.number())._eigen_matrix_vector_mult)
790 {
792 MatMFFDSetFunction(jac, Moose::SlepcSupport::mooseSlepcEigenFormFunctionMFFD, ctx));
793
794 EPS eps = eigen_nl.getEPS();
795
796 LibmeshPetscCallQ(mooseEPSFormMatrices(*eigen_problem, eps, x, ctx));
797
798 if (pc != jac)
799 {
800 LibmeshPetscCallQ(MatAssemblyBegin(jac, MAT_FINAL_ASSEMBLY));
801 LibmeshPetscCallQ(MatAssemblyEnd(jac, MAT_FINAL_ASSEMBLY));
802 }
803 PetscFunctionReturn(PETSC_SUCCESS);
804 }
805
806 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)pc, MATSHELL, &pisshell));
807 if ((jisshell || jismffd) && pisshell)
808 {
809 // Just assemble matrices and return
810 LibmeshPetscCallQ(MatAssemblyBegin(jac, MAT_FINAL_ASSEMBLY));
811 LibmeshPetscCallQ(MatAssemblyBegin(pc, MAT_FINAL_ASSEMBLY));
812 LibmeshPetscCallQ(MatAssemblyEnd(jac, MAT_FINAL_ASSEMBLY));
813 LibmeshPetscCallQ(MatAssemblyEnd(pc, MAT_FINAL_ASSEMBLY));
814
815 PetscFunctionReturn(PETSC_SUCCESS);
816 }
817
818 // Jacobian and precond matrix are the same
819 if (jac == pc)
820 {
821 if (!pisshell)
823 snes, x, pc, sys.get_matrix_A(), ctx, eigen_nl.precondMatrixTag());
824
825 PetscFunctionReturn(PETSC_SUCCESS);
826 }
827 else
828 {
829 if (!jisshell && !jismffd && !pisshell) // We need to form both Jacobian and precond matrix
830 {
831 std::vector<Mat> mats = {jac, pc};
832 std::vector<SparseMatrix<Number> *> libmesh_mats = {&sys.get_matrix_A(),
833 &sys.get_precond_matrix()};
834 std::set<TagID> tags = {eigen_nl.nonEigenMatrixTag(), eigen_nl.precondMatrixTag()};
835 moosePetscSNESFormMatricesTags(snes, x, mats, libmesh_mats, ctx, tags);
836 PetscFunctionReturn(PETSC_SUCCESS);
837 }
838 if (!pisshell) // We need to form only precond matrix
839 {
841 snes, x, pc, sys.get_precond_matrix(), ctx, eigen_nl.precondMatrixTag());
842 LibmeshPetscCallQ(MatAssemblyBegin(jac, MAT_FINAL_ASSEMBLY));
843 LibmeshPetscCallQ(MatAssemblyEnd(jac, MAT_FINAL_ASSEMBLY));
844 PetscFunctionReturn(PETSC_SUCCESS);
845 }
846 if (!jisshell && !jismffd) // We need to form only Jacobian matrix
847 {
849 snes, x, jac, sys.get_matrix_A(), ctx, eigen_nl.nonEigenMatrixTag());
850 LibmeshPetscCallQ(MatAssemblyBegin(pc, MAT_FINAL_ASSEMBLY));
851 LibmeshPetscCallQ(MatAssemblyEnd(pc, MAT_FINAL_ASSEMBLY));
852 PetscFunctionReturn(PETSC_SUCCESS);
853 }
854 }
855 PetscFunctionReturn(PETSC_SUCCESS);
856}
PetscErrorCode mooseSlepcEigenFormFunctionMFFD(void *ctx, Vec x, Vec r)
Function call for MFFD.
void moosePetscSNESFormMatrixTag(SNES snes, Vec x, Mat eigen_mat, SparseMatrix< Number > &all_dofs_mat, void *ctx, TagID tag)
Form matrix according to tag.

Referenced by attachCallbacksToMat().

◆ mooseSlepcEigenFormJacobianB()

PetscErrorCode Moose::SlepcSupport::mooseSlepcEigenFormJacobianB ( SNES  snes,
Vec  x,
Mat  jac,
Mat  pc,
void *  ctx 
)

Form Jacobian matrix B.

It is a SLEPc callback

Definition at line 859 of file SlepcSupport.C.

860{
861 PetscBool jshell, pshell;
862 PetscBool jismffd;
863
865
866 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
867 NonlinearEigenSystem & eigen_nl = eigen_problem->getCurrentNonlinearEigenSystem();
868 auto & sys = eigen_nl.sys();
869
870 // If both jacobian and preconditioning are shell matrices,
871 // and then assemble them and return
872 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)jac, MATSHELL, &jshell));
873 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)jac, MATMFFD, &jismffd));
874 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)pc, MATSHELL, &pshell));
875 if ((jshell || jismffd) && pshell)
876 {
877 // Just assemble matrices and return
878 LibmeshPetscCallQ(MatAssemblyBegin(jac, MAT_FINAL_ASSEMBLY));
879 LibmeshPetscCallQ(MatAssemblyBegin(pc, MAT_FINAL_ASSEMBLY));
880 LibmeshPetscCallQ(MatAssemblyEnd(jac, MAT_FINAL_ASSEMBLY));
881 LibmeshPetscCallQ(MatAssemblyEnd(pc, MAT_FINAL_ASSEMBLY));
882
883 PetscFunctionReturn(PETSC_SUCCESS);
884 }
885
886 if (jac != pc && (!jshell && !jshell))
887 SETERRQ(PetscObjectComm((PetscObject)snes),
888 PETSC_ERR_ARG_INCOMP,
889 "Jacobian and precond matrices should be the same for eigen kernels \n");
890
891 moosePetscSNESFormMatrixTag(snes, x, pc, sys.get_matrix_B(), ctx, eigen_nl.eigenMatrixTag());
892
893 if (eigen_problem->negativeSignEigenKernel())
894 {
895 LibmeshPetscCallQ(MatScale(pc, -1.));
896 }
897
898 PetscFunctionReturn(PETSC_SUCCESS);
899}

Referenced by attachCallbacksToMat().

◆ mooseSlepcEigenFormNorm()

PetscErrorCode Moose::SlepcSupport::mooseSlepcEigenFormNorm ( SNES  ,
Vec  ,
PetscReal *  norm,
void *  ctx 
)

Definition at line 1051 of file SlepcSupport.C.

1052{
1054 auto * const eigen_problem = static_cast<EigenProblem *>(ctx);
1055 *norm = eigen_problem->formNorm();
1056 PetscFunctionReturn(PETSC_SUCCESS);
1057}

Referenced by attachCallbacksToMat().

◆ mooseSlepcEPSGetSNES()

PetscErrorCode Moose::SlepcSupport::mooseSlepcEPSGetSNES ( EPS  eps,
SNES *  snes 
)

Retrieve SNES from EPS.

It makes sense only for Newton eigenvalue solvers

Definition at line 1309 of file SlepcSupport.C.

1310{
1311 PetscBool same, nonlinear;
1312
1314 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)eps, EPSPOWER, &same));
1315
1316 if (!same)
1317 mooseError("It is not eps power, and there is no snes");
1318
1319 LibmeshPetscCallQ(EPSPowerGetNonlinear(eps, &nonlinear));
1320
1321 if (!nonlinear)
1322 mooseError("It is not a nonlinear eigen solver");
1323
1324 LibmeshPetscCallQ(EPSPowerGetSNES(eps, snes));
1325
1326 PetscFunctionReturn(PETSC_SUCCESS);
1327}

Referenced by NonlinearEigenSystem::getSNES(), mooseSlepcEPSSNESKSPSetPCSide(), mooseSlepcEPSSNESSetCustomizePC(), and mooseSlepcEPSSNESSetUpOptionPrefix().

◆ mooseSlepcEPSMonitor()

PetscErrorCode Moose::SlepcSupport::mooseSlepcEPSMonitor ( EPS  eps,
PetscInt  its,
PetscInt  nconv,
PetscScalar *  eigr,
PetscScalar *  eigi,
PetscReal *  errest,
PetscInt  nest,
void *  mctx 
)

A customized solver monitor to print out eigenvalue.

Definition at line 1385 of file SlepcSupport.C.

1393{
1394 ST st;
1395 PetscScalar eigenr, eigeni;
1396
1398 EigenProblem * eigen_problem = static_cast<EigenProblem *>(mctx);
1399 auto & console = eigen_problem->console();
1400
1401 auto inverse = eigen_problem->outputInverseEigenvalue();
1402 LibmeshPetscCallQ(EPSGetST(eps, &st));
1403 eigenr = eigr[0];
1404 eigeni = eigi[0];
1405 // Make the eigenvalue consistent with shift type
1406 LibmeshPetscCallQ(STBackTransform(st, 1, &eigenr, &eigeni));
1407
1408 auto eigenvalue = inverse ? 1.0 / eigenr : eigenr;
1409
1410 // The term "k-eigenvalue" is adopted from the neutronics community.
1411 console << " Iteration " << its << std::setprecision(10) << std::fixed
1412 << (inverse ? " k-eigenvalue = " : " eigenvalue = ") << eigenvalue << std::endl;
1413
1414 PetscFunctionReturn(PETSC_SUCCESS);
1415}
bool outputInverseEigenvalue() const
Whether or not to output eigenvalue inverse.
const ConsoleStream & console() const
Return console handle.
Definition Problem.h:48

Referenced by SlepcEigenSolverConfiguration::configure_solver().

◆ mooseSlepcEPSSNESKSPSetPCSide()

PetscErrorCode Moose::SlepcSupport::mooseSlepcEPSSNESKSPSetPCSide ( FEProblemBase problem,
EPS  eps 
)

Allow users to specify PC side.

By default, we apply PC from the right side. It is consistent with the nonlinear solver.

Definition at line 1367 of file SlepcSupport.C.

1368{
1369 SNES snes;
1370 KSP ksp;
1371
1373 // Get SNES from EPS
1375 // Get KSP from SNES
1376 LibmeshPetscCallQ(SNESGetKSP(snes, &ksp));
1377
1379
1381 PetscFunctionReturn(PETSC_SUCCESS);
1382}
void petscSetDefaultKSPNormType(FEProblemBase &problem, KSP ksp)
Set norm type.
void petscSetDefaultPCSide(FEProblemBase &problem, KSP ksp)
Setup which side we want to apply preconditioner.
PetscErrorCode mooseSlepcEPSGetSNES(EPS eps, SNES *snes)
Retrieve SNES from EPS.

Referenced by SlepcEigenSolverConfiguration::configure_solver().

◆ mooseSlepcEPSSNESSetCustomizePC()

PetscErrorCode Moose::SlepcSupport::mooseSlepcEPSSNESSetCustomizePC ( EPS  eps)

Attach a customized PC.

It is useful when you want to use PBP or other customized preconditioners

Definition at line 1348 of file SlepcSupport.C.

1349{
1350 SNES snes;
1351 KSP ksp;
1352 PC pc;
1353
1355 // Get SNES from EPS
1357 // Get KSP from SNES
1358 LibmeshPetscCallQ(SNESGetKSP(snes, &ksp));
1359 // Get PC from KSP
1360 LibmeshPetscCallQ(KSPGetPC(ksp, &pc));
1361 // Set PC type
1362 LibmeshPetscCallQ(PCSetType(pc, "moosepc"));
1363 PetscFunctionReturn(PETSC_SUCCESS);
1364}

Referenced by SlepcEigenSolverConfiguration::configure_solver().

◆ mooseSlepcEPSSNESSetUpOptionPrefix()

PetscErrorCode Moose::SlepcSupport::mooseSlepcEPSSNESSetUpOptionPrefix ( EPS  eps)

Get rid of prefix "-eps_power" for SNES, KSP, PC, etc.

Definition at line 1330 of file SlepcSupport.C.

1331{
1332 SNES snes;
1333 const char * prefix = nullptr;
1334
1337 // There is an extra "eps_power" in snes that users do not like it.
1338 // Let us remove that from snes.
1339 // Retrieve option prefix from EPS
1340 LibmeshPetscCallQ(PetscObjectGetOptionsPrefix((PetscObject)eps, &prefix));
1341 // Set option prefix to SNES
1342 LibmeshPetscCallQ(SNESSetOptionsPrefix(snes, prefix));
1343
1344 PetscFunctionReturn(PETSC_SUCCESS);
1345}

Referenced by SlepcEigenSolverConfiguration::configure_solver().

◆ mooseSlepcStoppingTest()

PetscErrorCode Moose::SlepcSupport::mooseSlepcStoppingTest ( EPS  eps,
PetscInt  its,
PetscInt  max_it,
PetscInt  nconv,
PetscInt  nev,
EPSConvergedReason *  reason,
void *  ctx 
)

A customized convergence checker.

We need to make solver as converged when doing free power iteration.

Definition at line 1281 of file SlepcSupport.C.

1288{
1289 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
1290
1292 LibmeshPetscCallQ(EPSStoppingBasic(eps, its, max_it, nconv, nev, reason, NULL));
1293
1294 // If we do free power iteration, we need to mark the solver as converged.
1295 // It is because SLEPc does not offer a way to copy unconverged solution.
1296 // If the solver is not marked as "converged", we have no way to get solution
1297 // from slepc. Note marking as "converged" has no side-effects at all for us.
1298 // If free power iteration is used as a stand-alone solver, we won't trigger
1299 // as "doFreePowerIteration()" is false.
1300 if (eigen_problem->doFreePowerIteration() && its == max_it && *reason <= 0)
1301 {
1302 *reason = EPS_CONVERGED_USER;
1303 eps->nconv = 1;
1304 }
1305 PetscFunctionReturn(PETSC_SUCCESS);
1306}
bool doFreePowerIteration() const
Whether or not we are doing free power iteration.

Referenced by SlepcEigenSolverConfiguration::configure_solver().

◆ PCApply_MoosePC()

PetscErrorCode Moose::SlepcSupport::PCApply_MoosePC ( PC  pc,
Vec  x,
Vec  y 
)

Preconditioner application.

It call libMesh preconditioner to implement this.

Definition at line 1219 of file SlepcSupport.C.

1220{
1221 void * ctx;
1222 Mat Amat, Pmat;
1223 PetscContainer container;
1224
1226 LibmeshPetscCallQ(PCGetOperators(pc, &Amat, &Pmat));
1228 PetscObjectQuery((PetscObject)Pmat, "formFunctionCtx", (PetscObject *)&container));
1229 if (container)
1230 LibmeshPetscCallQ(PetscContainerGetPointer(container, &ctx));
1231 else
1232 mooseError(" Can not find a context \n");
1233
1234 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
1235 NonlinearEigenSystem & nl_eigen = eigen_problem->getCurrentNonlinearEigenSystem();
1236 auto preconditioner = nl_eigen.preconditioner();
1237
1238 if (!preconditioner)
1239 mooseError("There is no moose preconditioner in nonlinear eigen system \n");
1240
1241 PetscVector<Number> x_vec(x, preconditioner->comm());
1242 PetscVector<Number> y_vec(y, preconditioner->comm());
1243
1244 preconditioner->apply(x_vec, y_vec);
1245
1246 PetscFunctionReturn(PETSC_SUCCESS);
1247}
libMesh::Preconditioner< Number > * preconditioner() const

Referenced by PCCreate_MoosePC().

◆ PCCreate_MoosePC()

PETSC_EXTERN PetscErrorCode Moose::SlepcSupport::PCCreate_MoosePC ( PC  pc)

Create a preconditioner from moose side.

It is used to attach moose preconditioner

Definition at line 1184 of file SlepcSupport.C.

1185{
1187
1188 pc->ops->view = PCView_MoosePC;
1189 pc->ops->destroy = PCDestroy_MoosePC;
1190 pc->ops->setup = PCSetUp_MoosePC;
1191 pc->ops->apply = PCApply_MoosePC;
1192
1193 PetscFunctionReturn(PETSC_SUCCESS);
1194}
PetscErrorCode PCSetUp_MoosePC(PC pc)
Setup preconditioner.
PetscErrorCode PCDestroy_MoosePC(PC pc)
Destroy preconditioner.
PetscErrorCode PCApply_MoosePC(PC pc, Vec x, Vec y)
Preconditioner application.
PetscErrorCode PCView_MoosePC(PC pc, PetscViewer viewer)
View preconditioner.

Referenced by registerPCToPETSc().

◆ PCDestroy_MoosePC()

PetscErrorCode Moose::SlepcSupport::PCDestroy_MoosePC ( PC  pc)

Destroy preconditioner.

Definition at line 1197 of file SlepcSupport.C.

1198{
1200 /* We do not need to do anything right now, but later we may have some data we need to free here
1201 */
1202 PetscFunctionReturn(PETSC_SUCCESS);
1203}

Referenced by PCCreate_MoosePC().

◆ PCSetUp_MoosePC()

PetscErrorCode Moose::SlepcSupport::PCSetUp_MoosePC ( PC  pc)

Setup preconditioner.

Definition at line 1250 of file SlepcSupport.C.

1251{
1252 void * ctx;
1253 Mat Amat, Pmat;
1254 PetscContainer container;
1255
1257 LibmeshPetscCallQ(PCGetOperators(pc, &Amat, &Pmat));
1259 PetscObjectQuery((PetscObject)Pmat, "formFunctionCtx", (PetscObject *)&container));
1260 if (container)
1261 LibmeshPetscCallQ(PetscContainerGetPointer(container, &ctx));
1262 else
1263 mooseError(" Can not find a context \n");
1264
1265 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
1266 NonlinearEigenSystem & nl_eigen = eigen_problem->getCurrentNonlinearEigenSystem();
1267 Preconditioner<Number> * preconditioner = nl_eigen.preconditioner();
1268
1269 if (!preconditioner)
1270 mooseError("There is no moose preconditioner in nonlinear eigen system \n");
1271
1272 if (!preconditioner->initialized())
1273 preconditioner->init();
1274
1275 preconditioner->setup();
1276
1277 PetscFunctionReturn(PETSC_SUCCESS);
1278}

Referenced by PCCreate_MoosePC().

◆ PCView_MoosePC()

PetscErrorCode Moose::SlepcSupport::PCView_MoosePC ( PC  pc,
PetscViewer  viewer 
)

View preconditioner.

Definition at line 1206 of file SlepcSupport.C.

1207{
1208 PetscBool iascii;
1209
1211 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
1212 if (iascii)
1213 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, " %s\n", "moosepc"));
1214
1215 PetscFunctionReturn(PETSC_SUCCESS);
1216}

Referenced by PCCreate_MoosePC().

◆ registerPCToPETSc()

PETSC_EXTERN PetscErrorCode Moose::SlepcSupport::registerPCToPETSc ( )

Let PETSc know there is a preconditioner.

Definition at line 1174 of file SlepcSupport.C.

1175{
1177
1178 LibmeshPetscCallQ(PCRegister("moosepc", PCCreate_MoosePC));
1179
1180 PetscFunctionReturn(PETSC_SUCCESS);
1181}

Referenced by NonlinearEigenSystem::attachPreconditioner().

◆ setEigenProblemOptions()

void Moose::SlepcSupport::setEigenProblemOptions ( SolverParams solver_params,
const MultiMooseEnum dont_add_these_options 
)

Definition at line 296 of file SlepcSupport.C.

297{
298 switch (solver_params._eigen_problem_type)
299 {
302 "-eps_hermitian");
303 break;
304
307 "-eps_non_hermitian");
308 break;
309
312 "-eps_gen_hermitian");
313 break;
314
317 "-eps_gen_indefinite");
318 break;
319
322 "-eps_gen_non_hermitian");
323 break;
324
327 "-eps_pos_gen_non_hermitian");
328 break;
329
331 break;
332
333 default:
334 mooseError("Unknown eigen solver type \n");
335 }
336}
Moose::EigenProblemType _eigen_problem_type
void setSinglePetscOptionIfAppropriate(const MultiMooseEnum &dont_add_these_options, const std::string &name, const std::string &value="", FEProblemBase *const problem=nullptr)
Same as setSinglePetscOption, but does not set the option if it doesn't make sense for the current si...
@ EPT_GEN_INDEFINITE
Generalized Hermitian indefinite.
Definition MooseTypes.h:929
@ EPT_NON_HERMITIAN
Non-Hermitian.
Definition MooseTypes.h:927
@ EPT_GEN_HERMITIAN
Generalized Hermitian.
Definition MooseTypes.h:928
@ EPT_HERMITIAN
Hermitian.
Definition MooseTypes.h:926
@ EPT_GEN_NON_HERMITIAN
Generalized Non-Hermitian.
Definition MooseTypes.h:930
@ EPT_POS_GEN_NON_HERMITIAN
Generalized Non-Hermitian with positive (semi-)definite B.
Definition MooseTypes.h:931
@ EPT_SLEPC_DEFAULT
use whatever SLPEC has by default
Definition MooseTypes.h:932

Referenced by slepcSetOptions().

◆ setEigenProblemSolverParams()

void Moose::SlepcSupport::setEigenProblemSolverParams ( EigenProblem eigen_problem,
const InputParameters params 
)

Retrieve eigen problem params from 'params', and then set these params into SolverParams.

Definition at line 210 of file SlepcSupport.C.

211{
212 for (const auto i : make_range(eigen_problem.numNonlinearSystems()))
213 {
214 const std::string & eigen_problem_type = params.get<MooseEnum>("eigen_problem_type");
215 if (!eigen_problem_type.empty())
216 eigen_problem.solverParams(i)._eigen_problem_type =
217 Moose::stringToEnum<Moose::EigenProblemType>(eigen_problem_type);
218 else
219 mooseError("Have to specify a valid eigen problem type");
220
221 const std::string & which_eigen_pairs = params.get<MooseEnum>("which_eigen_pairs");
222 if (!which_eigen_pairs.empty())
223 eigen_problem.solverParams(i)._which_eigen_pairs =
224 Moose::stringToEnum<Moose::WhichEigenPairs>(which_eigen_pairs);
225
226 // Set necessary parameters used in EigenSystem::solve(),
227 // i.e. the number of requested eigenpairs nev and the number
228 // of basis vectors ncv used in the solution algorithm. Note that
229 // ncv >= nev must hold and ncv >= 2*nev is recommended
230 unsigned int n_eigen_pairs = params.get<unsigned int>("n_eigen_pairs");
231 unsigned int n_basis_vectors = params.get<unsigned int>("n_basis_vectors");
232
233 eigen_problem.setNEigenPairsRequired(n_eigen_pairs);
234
235 eigen_problem.es().parameters.set<unsigned int>("eigenpairs") = n_eigen_pairs;
236
237 // If the subspace dimension is too small, we increase it automatically
238 if (subspace_factor * n_eigen_pairs > n_basis_vectors)
239 {
240 n_basis_vectors = subspace_factor * n_eigen_pairs;
242 "Number of subspaces in Eigensolver is changed by moose because the value you set "
243 "is too small");
244 }
245
246 eigen_problem.es().parameters.set<unsigned int>("basis vectors") = n_basis_vectors;
247
248 // Operators A and B are formed as shell matrices
249 eigen_problem.solverParams(i)._eigen_matrix_free = params.get<bool>("matrix_free");
250
251 // Preconditioning is formed as a shell matrix
252 eigen_problem.solverParams(i)._precond_matrix_free = params.get<bool>("precond_matrix_free");
253
254 if (params.get<MooseEnum>("solve_type") == "PJFNK")
255 {
256 eigen_problem.solverParams(i)._eigen_matrix_free = true;
257 }
258 if (params.get<MooseEnum>("solve_type") == "JFNK")
259 {
260 eigen_problem.solverParams(i)._eigen_matrix_free = true;
261 eigen_problem.solverParams(i)._precond_matrix_free = true;
262 }
263 // We need matrices so that we can implement residual evaluations
264 if (params.get<MooseEnum>("solve_type") == "PJFNKMO")
265 {
266 eigen_problem.solverParams(i)._eigen_matrix_free = true;
267 eigen_problem.solverParams(i)._precond_matrix_free = false;
268 eigen_problem.solverParams(i)._eigen_matrix_vector_mult = true;
269 // By default, we need to form full matrices, otherwise residual
270 // evaluations will not be accurate
271 eigen_problem.setCoupling(Moose::COUPLING_FULL);
272 }
273 }
274
275 eigen_problem.constantMatrices(params.get<bool>("constant_matrices"));
276
277 if (eigen_problem.constantMatrices() && params.get<MooseEnum>("solve_type") != "PJFNKMO")
278 {
279 mooseError("constant_matrices flag is only valid for solve type: PJFNKMO");
280 }
281}
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
Definition MooseError.h:345
void setNEigenPairsRequired(unsigned int n_eigen_pairs)
virtual libMesh::EquationSystems & es() override
void setCoupling(Moose::CouplingType type)
Set the coupling between variables TODO: allow user-defined coupling.
Moose::WhichEigenPairs _which_eigen_pairs
bool _eigen_matrix_free
bool _precond_matrix_free
T & set(const std::string &)
const int subspace_factor
@ COUPLING_FULL
Definition MooseTypes.h:787

Referenced by EigenProblemSolve::EigenProblemSolve().

◆ setEigenSolverOptions()

void Moose::SlepcSupport::setEigenSolverOptions ( SolverParams solver_params,
const InputParameters params 
)

Definition at line 492 of file SlepcSupport.C.

493{
494 // Avoid unused variable warnings when you have SLEPc but not PETSc-dev.
495 libmesh_ignore(params);
496
497 switch (solver_params._eigen_solve_type)
498 {
499 case Moose::EST_POWER:
500 Moose::PetscSupport::setSinglePetscOption("-eps_type", "power");
501 break;
502
504 Moose::PetscSupport::setSinglePetscOption("-eps_type", "arnoldi");
505 break;
506
508 Moose::PetscSupport::setSinglePetscOption("-eps_type", "krylovschur");
509 break;
510
513 break;
514
516 setNonlinearPowerOptions(solver_params);
517 break;
518
520 setNewtonPetscOptions(solver_params, params);
521 break;
522
523 case Moose::EST_PJFNK:
524 solver_params._eigen_matrix_free = true;
525 solver_params._customized_pc_for_eigen = false;
526 setNewtonPetscOptions(solver_params, params);
527 break;
528
529 case Moose::EST_JFNK:
530 solver_params._eigen_matrix_free = true;
531 solver_params._customized_pc_for_eigen = true;
532 setNewtonPetscOptions(solver_params, params);
533 break;
534
536 solver_params._eigen_matrix_free = true;
537 solver_params._customized_pc_for_eigen = false;
538 solver_params._eigen_matrix_vector_mult = true;
539 setNewtonPetscOptions(solver_params, params);
540 break;
541
542 default:
543 mooseError("Unknown eigen solver type \n");
544 }
545}
Moose::EigenSolveType _eigen_solve_type
bool _customized_pc_for_eigen
void setNewtonPetscOptions(SolverParams &solver_params, const InputParameters &params)
void setNonlinearPowerOptions(SolverParams &solver_params)
@ EST_PJFNKMO
The same as PJFNK except that matrix-vector multiplication is employed to replace residual evaluation...
Definition MooseTypes.h:917
@ EST_JACOBI_DAVIDSON
Jacobi-Davidson.
Definition MooseTypes.h:913
@ EST_KRYLOVSCHUR
Krylov-Schur.
Definition MooseTypes.h:912
@ EST_JFNK
Jacobian-free Newton Krylov.
Definition MooseTypes.h:918
@ EST_NEWTON
Newton-based eigensolver with an assembled Jacobian matrix (fully coupled by default)
Definition MooseTypes.h:915
@ EST_POWER
Power / Inverse / RQI.
Definition MooseTypes.h:910
@ EST_NONLINEAR_POWER
Nonlinear inverse power.
Definition MooseTypes.h:914
@ EST_ARNOLDI
Arnoldi.
Definition MooseTypes.h:911
@ EST_PJFNK
Preconditioned Jacobian-free Newton Krylov.
Definition MooseTypes.h:916

Referenced by slepcSetOptions().

◆ setFreeNonlinearPowerIterations()

void Moose::SlepcSupport::setFreeNonlinearPowerIterations ( unsigned int  free_power_iterations)

Set SLEPc/PETSc options to trigger free power iteration.

Definition at line 402 of file SlepcSupport.C.

403{
404 Moose::PetscSupport::setSinglePetscOption("-eps_power_update", "0");
406 // During each power iteration, we want solver converged unless linear solver does not
407 // work. We here use a really loose tolerance for this purpose.
408 // -snes_no_convergence_test is a perfect option, but it was removed from PETSc
409 Moose::PetscSupport::setSinglePetscOption("-snes_rtol", "0.99999999999");
410 Moose::PetscSupport::setSinglePetscOption("-eps_max_it", stringify(free_power_iterations));
411 // We always want the number of free power iterations respected so we don't want to stop early if
412 // we've satisfied a convergence criterion. Consequently we make this tolerance very tight
414}

Referenced by EigenProblem::doFreeNonlinearPowerIterations().

◆ setNewtonPetscOptions()

void Moose::SlepcSupport::setNewtonPetscOptions ( SolverParams solver_params,
const InputParameters params 
)

Definition at line 429 of file SlepcSupport.C.

430{
431#if !SLEPC_VERSION_LESS_THAN(3, 8, 0) || !PETSC_VERSION_RELEASE
432 // Whether or not we need to involve an initial inverse power
433 bool initial_power = params.get<bool>("_newton_inverse_power");
434
435 Moose::PetscSupport::setSinglePetscOption("-eps_type", "power");
436 Moose::PetscSupport::setSinglePetscOption("-eps_power_nonlinear", "1");
437 Moose::PetscSupport::setSinglePetscOption("-eps_power_update", "1");
438 // Only one outer iteration in EPS is allowed when Newton/PJFNK/JFNK
439 // is used as the eigen solver
441 if (initial_power)
442 {
443 Moose::PetscSupport::setSinglePetscOption("-init_eps_power_snes_max_it", "1");
444 Moose::PetscSupport::setSinglePetscOption("-init_eps_power_ksp_rtol", "1e-2");
446 "-init_eps_max_it", stringify(params.get<unsigned int>("free_power_iterations")));
447 }
448 Moose::PetscSupport::setSinglePetscOption("-eps_target_magnitude", "");
449 if (solver_params._eigen_matrix_free)
450 {
451 Moose::PetscSupport::setSinglePetscOption("-snes_mf_operator", "1");
452 if (initial_power)
453 Moose::PetscSupport::setSinglePetscOption("-init_eps_power_snes_mf_operator", "1");
454 }
455 else
456 {
457 Moose::PetscSupport::setSinglePetscOption("-snes_mf_operator", "0");
458 if (initial_power)
459 Moose::PetscSupport::setSinglePetscOption("-init_eps_power_snes_mf_operator", "0");
460 }
461#if PETSC_RELEASE_LESS_THAN(3, 13, 0)
462 Moose::PetscSupport::setSinglePetscOption("-st_type", "sinvert");
463 if (initial_power)
464 Moose::PetscSupport::setSinglePetscOption("-init_st_type", "sinvert");
465#endif
466#else
467 mooseError("Newton-based eigenvalue solver requires SLEPc 3.7.3 or higher");
468#endif
469}

Referenced by setEigenSolverOptions().

◆ setNonlinearPowerOptions()

void Moose::SlepcSupport::setNonlinearPowerOptions ( SolverParams solver_params)

Definition at line 472 of file SlepcSupport.C.

473{
474#if !SLEPC_VERSION_LESS_THAN(3, 8, 0) || !PETSC_VERSION_RELEASE
475 Moose::PetscSupport::setSinglePetscOption("-eps_type", "power");
476 Moose::PetscSupport::setSinglePetscOption("-eps_power_nonlinear", "1");
477 Moose::PetscSupport::setSinglePetscOption("-eps_target_magnitude", "");
478 if (solver_params._eigen_matrix_free)
479 Moose::PetscSupport::setSinglePetscOption("-snes_mf_operator", "1");
480 else
481 Moose::PetscSupport::setSinglePetscOption("-snes_mf_operator", "0");
482
483#if PETSC_RELEASE_LESS_THAN(3, 13, 0)
484 Moose::PetscSupport::setSinglePetscOption("-st_type", "sinvert");
485#endif
486#else
487 mooseError("Nonlinear Inverse Power requires SLEPc 3.7.3 or higher");
488#endif
489}

Referenced by setEigenSolverOptions().

◆ setOperationsForShellMat()

void Moose::SlepcSupport::setOperationsForShellMat ( EigenProblem eigen_problem,
Mat  mat,
bool  eigen 
)

Set operations to shell mat.

Definition at line 1163 of file SlepcSupport.C.

1164{
1165 LibmeshPetscCallA(eigen_problem.comm().get(), MatShellSetContext(mat, &eigen_problem));
1166 LibmeshPetscCallA(eigen_problem.comm().get(),
1167 MatShellSetOperation(mat,
1168 MATOP_MULT,
1169 eigen ? (void (*)(void))mooseMatMult_Eigen
1170 : (void (*)(void))mooseMatMult_NonEigen));
1171}
PetscErrorCode mooseMatMult_NonEigen(Mat mat, Vec x, Vec y)
Implement MatMult via function evaluation for Ax.

Referenced by NonlinearEigenSystem::attachSLEPcCallbacks().

◆ setSlepcEigenSolverTolerances()

void Moose::SlepcSupport::setSlepcEigenSolverTolerances ( EigenProblem eigen_problem,
const SolverParams solver_params,
const InputParameters params 
)

Control eigen solver tolerances via SLEPc options.

Definition at line 126 of file SlepcSupport.C.

129{
130 const auto & dont_add_these_options = eigen_problem.getPetscOptions().dont_add_these_options;
131 const auto prefix_with_dash = '-' + solver_params._prefix;
132
133 mooseAssert(solver_params._solver_sys_num != libMesh::invalid_uint,
134 "The solver system number must be initialized");
135
137 prefix_with_dash + "eps_tol",
138 stringify(params.get<Real>("eigen_tol")));
139
141 dont_add_these_options,
142 prefix_with_dash + "eps_max_it",
143 stringify(params.get<unsigned int>("eigen_max_its")));
144
145 // if it is a nonlinear eigenvalue solver, we need to set tolerances for nonlinear solver and
146 // linear solver
147 if (eigen_problem.isNonlinearEigenvalueSolver(solver_params._solver_sys_num))
148 {
149 // nonlinear solver tolerances
151 dont_add_these_options,
152 prefix_with_dash + "snes_max_it",
153 stringify(params.get<unsigned int>("nl_max_its")));
154
156 dont_add_these_options,
157 prefix_with_dash + "snes_max_funcs",
158 stringify(params.get<unsigned int>("nl_max_funcs")));
159
161 dont_add_these_options,
162 prefix_with_dash + "snes_atol",
163 stringify(params.get<Real>("nl_abs_tol")));
164
166 dont_add_these_options,
167 prefix_with_dash + "snes_rtol",
168 stringify(params.get<Real>("nl_rel_tol")));
169
171 dont_add_these_options,
172 prefix_with_dash + "snes_stol",
173 stringify(params.get<Real>("nl_rel_step_tol")));
174
175 // linear solver
177 dont_add_these_options,
178 prefix_with_dash + "ksp_max_it",
179 stringify(params.get<unsigned int>("l_max_its")));
180
182 prefix_with_dash + "ksp_rtol",
183 stringify(params.get<Real>("l_tol")));
184
186 dont_add_these_options,
187 prefix_with_dash + "ksp_atol",
188 stringify(params.get<Real>("l_abs_tol")));
189 }
190 else
191 { // linear eigenvalue problem
192 // linear solver
194 dont_add_these_options,
195 prefix_with_dash + "st_ksp_max_it",
196 stringify(params.get<unsigned int>("l_max_its")));
197
199 prefix_with_dash + "st_ksp_rtol",
200 stringify(params.get<Real>("l_tol")));
201
203 dont_add_these_options,
204 prefix_with_dash + "st_ksp_atol",
205 stringify(params.get<Real>("l_abs_tol")));
206 }
207}
bool isNonlinearEigenvalueSolver(unsigned int eigen_sys_num) const
Moose::PetscSupport::PetscOptions & getPetscOptions()
Retrieve a writable reference the PETSc options (used by PetscSupport)
MultiMooseEnum dont_add_these_options
Flags to explicitly not set, even if they are specified programmatically.
unsigned int _solver_sys_num
std::string _prefix
const unsigned int invalid_uint

Referenced by slepcSetOptions().

◆ setWhichEigenPairsOptions()

void Moose::SlepcSupport::setWhichEigenPairsOptions ( SolverParams solver_params,
const MultiMooseEnum dont_add_these_options 
)

Definition at line 339 of file SlepcSupport.C.

341{
342 switch (solver_params._which_eigen_pairs)
343 {
346 "-eps_largest_magnitude");
347 break;
348
351 "-eps_smallest_magnitude");
352 break;
353
356 "-eps_largest_real");
357 break;
358
361 "-eps_smallest_real");
362 break;
363
366 "-eps_largest_imaginary");
367 break;
368
371 "-eps_smallest_imaginary");
372 break;
373
376 "-eps_target_magnitude");
377 break;
378
381 "-eps_target_real");
382 break;
383
386 "-eps_target_imaginary");
387 break;
388
390 Moose::PetscSupport::setSinglePetscOptionIfAppropriate(dont_add_these_options, "-eps_all");
391 break;
392
394 break;
395
396 default:
397 mooseError("Unknown type of WhichEigenPairs \n");
398 }
399}
@ WEP_TARGET_MAGNITUDE
target magnitude
Definition MooseTypes.h:946
@ WEP_LARGEST_IMAGINARY
largest imaginary
Definition MooseTypes.h:944
@ WEP_TARGET_IMAGINARY
target imaginary
Definition MooseTypes.h:948
@ WEP_SMALLEST_REAL
smallest real
Definition MooseTypes.h:943
@ WEP_SLEPC_DEFAULT
use whatever we have in SLEPC
Definition MooseTypes.h:950
@ WEP_LARGEST_MAGNITUDE
largest magnitude
Definition MooseTypes.h:940
@ WEP_SMALLEST_MAGNITUDE
smallest magnitude
Definition MooseTypes.h:941
@ WEP_ALL_EIGENVALUES
all eigenvalues
Definition MooseTypes.h:949
@ WEP_SMALLEST_IMAGINARY
smallest imaginary
Definition MooseTypes.h:945
@ WEP_TARGET_REAL
target real
Definition MooseTypes.h:947
@ WEP_LARGEST_REAL
largest real
Definition MooseTypes.h:942

Referenced by slepcSetOptions().

◆ slepcSetOptions()

void Moose::SlepcSupport::slepcSetOptions ( EigenProblem eigen_problem,
SolverParams solver_params,
const InputParameters params 
)

Push all SLEPc/PETSc options into SLEPc/PETSc side.

Options could come from commandline, SolverParams, params, etc.

Definition at line 548 of file SlepcSupport.C.

551{
552 const auto & dont_add_these_options = eigen_problem.getPetscOptions().dont_add_these_options;
553
555 eigen_problem.getPetscOptions(), solver_params, &eigen_problem);
556 // Call "SolverTolerances" first, so some solver specific tolerance such as "eps_max_it"
557 // can be overriden
558 setSlepcEigenSolverTolerances(eigen_problem, solver_params, params);
559 setEigenSolverOptions(solver_params, params);
560 // when Bx norm postprocessor is provided, we switch off the sign normalization
561 if (eigen_problem.bxNormProvided())
563 dont_add_these_options, "-eps_power_sign_normalization", "0", &eigen_problem);
564 setEigenProblemOptions(solver_params, eigen_problem.getPetscOptions().dont_add_these_options);
567}
void petscSetOptions(const PetscOptions &po, const SolverParams &solver_params, FEProblemBase *const problem=nullptr)
A function for setting the PETSc options in PETSc from the options supplied to MOOSE.
void addPetscOptionsFromCommandline(FEProblemBase *const problem=nullptr)
Insert command-line PETSc options into the active PETSc options database.
void setWhichEigenPairsOptions(SolverParams &solver_params, const MultiMooseEnum &dont_add_these_options)
void setSlepcEigenSolverTolerances(EigenProblem &eigen_problem, const SolverParams &solver_params, const InputParameters &params)
Control eigen solver tolerances via SLEPc options.
void setEigenSolverOptions(SolverParams &solver_params, const InputParameters &params)
void setEigenProblemOptions(SolverParams &solver_params, const MultiMooseEnum &dont_add_these_options)

Referenced by EigenProblemSolve::initialSetup().

◆ storeSolveType()

void Moose::SlepcSupport::storeSolveType ( FEProblemBase fe_problem,
const InputParameters params 
)

Set solve type into eigen problem (solverParams)

Definition at line 284 of file SlepcSupport.C.

285{
286 if (!(dynamic_cast<EigenProblem *>(&fe_problem)))
287 return;
288
289 if (params.isParamValid("solve_type"))
290 for (const auto i : make_range(fe_problem.numNonlinearSystems()))
291 fe_problem.solverParams(i)._eigen_solve_type =
292 Moose::stringToEnum<Moose::EigenSolveType>(params.get<MooseEnum>("solve_type"));
293}
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another,...
T stringToEnum(const std::string &s)
EigenSolveType
Type of the eigen solve.
Definition MooseTypes.h:909

Referenced by EigenProblemSolve::EigenProblemSolve().

Variable Documentation

◆ subspace_factor

const int Moose::SlepcSupport::subspace_factor = 2

Definition at line 32 of file SlepcSupport.C.

Referenced by setEigenProblemSolverParams().