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 moosePetscSNESFormMatrixTag (SNES, Vec x, Mat eigen_mat, SparseMatrix< Number > &all_dofs_mat, void *ctx, TagID tag)
 Form matrix according to tag.
 
void moosePetscSNESFormMatricesTags (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.
 
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 1062 of file SlepcSupport.C.

1063{
1064 // Recall that we are solving the potentially nonlinear problem:
1065 // F(x) = A(x) - \lambda B(x) = 0
1066 //
1067 // To solve this, we can use Newton's method: J \Delta x = -F
1068 // Generally we will approximate J using matrix free methods. However, in order to solve the
1069 // linearized system efficiently, we typically will need preconditioning. Typically we will build
1070 // the preconditioner only from A, but we also have the option to include information from B
1071
1072 // Attach the Jacobian computation function. If \p mat is the "eigen" matrix corresponding to B,
1073 // then attach our JacobianB computation routine, else the matrix corresponds to A, and we attach
1074 // the JacobianA computation routine
1075 LibmeshPetscCallA(
1076 eigen_problem.comm().get(),
1077 PetscObjectComposeFunction((PetscObject)mat,
1078 "formJacobian",
1080 : Moose::SlepcSupport::mooseSlepcEigenFormJacobianA));
1081
1082 // Attach the residual computation function. If \p mat is the "eigen" matrix corresponding to B,
1083 // then attach our FunctionB computation routine, else the matrix corresponds to A, and we attach
1084 // the FunctionA computation routine
1085 LibmeshPetscCallA(
1086 eigen_problem.comm().get(),
1087 PetscObjectComposeFunction((PetscObject)mat,
1088 "formFunction",
1090 : Moose::SlepcSupport::mooseSlepcEigenFormFunctionA));
1091
1092 // It's also beneficial to be able to evaluate both A and B residuals at once
1093 LibmeshPetscCallA(eigen_problem.comm().get(),
1094 PetscObjectComposeFunction((PetscObject)mat,
1095 "formFunctionAB",
1097
1098 // Users may choose to provide a custom measure of the norm of B (Bx for a linear system)
1099 if (eigen_problem.bxNormProvided())
1100 LibmeshPetscCallA(eigen_problem.comm().get(),
1101 PetscObjectComposeFunction((PetscObject)mat,
1102 "formNorm",
1104
1105 // Finally we need to attach the "context" object, which is our EigenProblem, to the matrices so
1106 // that eventually when we get callbacks from SLEPc we can call methods on the EigenProblem
1107 PetscContainer container;
1108 LibmeshPetscCallA(eigen_problem.comm().get(),
1109 PetscContainerCreate(eigen_problem.comm().get(), &container));
1110 LibmeshPetscCallA(eigen_problem.comm().get(),
1111 PetscContainerSetPointer(container, &eigen_problem));
1112 LibmeshPetscCallA(
1113 eigen_problem.comm().get(),
1114 PetscObjectCompose((PetscObject)mat, "formJacobianCtx", (PetscObject)container));
1115 LibmeshPetscCallA(
1116 eigen_problem.comm().get(),
1117 PetscObjectCompose((PetscObject)mat, "formFunctionCtx", (PetscObject)container));
1118 if (eigen_problem.bxNormProvided())
1119 LibmeshPetscCallA(eigen_problem.comm().get(),
1120 PetscObjectCompose((PetscObject)mat, "formNormCtx", (PetscObject)container));
1121
1122 LibmeshPetscCallA(eigen_problem.comm().get(), PetscContainerDestroy(&container));
1123}
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 419 of file SlepcSupport.C.

420{
421 Moose::PetscSupport::setSinglePetscOption("-eps_power_update", "1");
424 stringify(params.get<unsigned int>("nl_max_its")));
426 stringify(params.get<Real>("nl_rel_tol")));
427 Moose::PetscSupport::setSinglePetscOption("-eps_tol", stringify(params.get<Real>("eigen_tol")));
428}
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.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

Referenced by EigenProblem::doFreeNonlinearPowerIterations().

◆ getSlepcEigenProblemValidParams()

InputParameters Moose::SlepcSupport::getSlepcEigenProblemValidParams ( )

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

Definition at line 66 of file SlepcSupport.C.

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

38{
39 MooseEnum solve_type("POWER ARNOLDI KRYLOVSCHUR JACOBI_DAVIDSON "
40 "NONLINEAR_POWER NEWTON PJFNK PJFNKMO JFNK",
41 "PJFNK");
42 params.set<MooseEnum>("solve_type") = solve_type;
43
44 params.setDocString("solve_type",
45 "POWER: Power / Inverse / RQI "
46 "ARNOLDI: Arnoldi "
47 "KRYLOVSCHUR: Krylov-Schur "
48 "JACOBI_DAVIDSON: Jacobi-Davidson "
49 "NONLINEAR_POWER: Nonlinear Power "
50 "NEWTON: Newton "
51 "PJFNK: Preconditioned Jacobian-free Newton-Kyrlov"
52 "JFNK: Jacobian-free Newton-Kyrlov"
53 "PJFNKMO: Preconditioned Jacobian-free Newton-Kyrlov with Matrix Only");
54
55 // When the eigenvalue problems is reformed as a coupled nonlinear system,
56 // we use part of Jacobian as the preconditioning matrix.
57 // Because the difference between the Jacobian and the preconditioning matrix is not small,
58 // the linear solver KSP can not reduce the residual much. After several tests,
59 // we find 1e-2 is a reasonable choice.
60 params.set<Real>("l_tol") = 1e-2;
61
62 return params;
63}
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 573 of file SlepcSupport.C.

574{
575 ST st;
576 Mat A, B;
577 PetscBool aisshell, bisshell;
579
580 if (eigen_problem.constantMatrices() && eigen_problem.wereMatricesFormed())
581 PetscFunctionReturn(PETSC_SUCCESS);
582
583 if (eigen_problem.onLinearSolver())
584 // We reach here during linear iteration when solve type is PJFNKMO.
585 // We will use the matrices assembled at the beginning of this Newton
586 // iteration for the following residual evaluation.
587 PetscFunctionReturn(PETSC_SUCCESS);
588
589 NonlinearEigenSystem & eigen_nl = eigen_problem.getCurrentNonlinearEigenSystem();
590 auto & sys = eigen_nl.sys();
591 SNES snes = eigen_nl.getSNES();
592 // Rest ST state so that we can retrieve matrices
593 LibmeshPetscCallQ(EPSGetST(eps, &st));
594 LibmeshPetscCallQ(STResetMatrixState(st));
595 LibmeshPetscCallQ(EPSGetOperators(eps, &A, &B));
596 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)A, MATSHELL, &aisshell));
597 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)B, MATSHELL, &bisshell));
598 if (aisshell || bisshell)
599 {
600 SETERRQ(PetscObjectComm((PetscObject)eps),
601 PETSC_ERR_ARG_INCOMP,
602 "A and B matrices can not be shell matrices when using PJFNKMO \n");
603 }
604 // Form A and B
605 std::vector<Mat> mats = {A, B};
606 std::vector<SparseMatrix<Number> *> libmesh_mats = {&sys.get_matrix_A(), &sys.get_matrix_B()};
608 snes, x, mats, libmesh_mats, ctx, {eigen_nl.nonEigenMatrixTag(), eigen_nl.eigenMatrixTag()});
609 eigen_problem.wereMatricesFormed(true);
610 PetscFunctionReturn(PETSC_SUCCESS);
611}
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.
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
void * ctx
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))

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 1126 of file SlepcSupport.C.

1127{
1129 void * ctx = nullptr;
1130 LibmeshPetscCallQ(MatShellGetContext(mat, &ctx));
1131
1132 if (!ctx)
1133 mooseError("No context is set for shell matrix ");
1134
1135 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
1136 NonlinearEigenSystem & eigen_nl = eigen_problem->getCurrentNonlinearEigenSystem();
1137
1138 evaluateResidual(*eigen_problem, x, r, eigen_nl.eigenVectorTag());
1139
1140 if (eigen_problem->negativeSignEigenKernel())
1141 LibmeshPetscCallQ(VecScale(r, -1.));
1142
1143 PetscFunctionReturn(PETSC_SUCCESS);
1144}
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 1147 of file SlepcSupport.C.

1148{
1150 void * ctx = nullptr;
1151 LibmeshPetscCallQ(MatShellGetContext(mat, &ctx));
1152
1153 if (!ctx)
1154 mooseError("No context is set for shell matrix ");
1155
1156 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
1157 NonlinearEigenSystem & eigen_nl = eigen_problem->getCurrentNonlinearEigenSystem();
1158
1159 evaluateResidual(*eigen_problem, x, r, eigen_nl.nonEigenVectorTag());
1160
1161 PetscFunctionReturn(PETSC_SUCCESS);
1162}
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 904 of file SlepcSupport.C.

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

Referenced by mooseSlepcEigenFormFunctionA(), and mooseSlepcEigenFormFunctionB().

◆ moosePetscSNESFormMatricesTags() [1/2]

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 712 of file SlepcSupport.C.

718{
719 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
720 auto & nl = eigen_problem->getCurrentNonlinearEigenSystem();
721 auto & sys = nl.sys();
722 auto & dof_map = sys.get_dof_map();
723
724#ifndef NDEBUG
725 for (const auto i : index_range(eigen_mats))
726 mooseAssert(!dof_map.n_constrained_dofs() ==
727 (eigen_mats[i] == cast_ptr<PetscMatrix<Number> *>(all_dofs_mats[i])->mat()),
728 "If we do not have constrained dofs, then mat and libmesh_mat should be the same. "
729 "Conversely, if we do have constrained dofs, they must be different");
730#endif
731
732 updateCurrentLocalSolution(sys, x);
733
734 for (auto * const all_dofs_mat : all_dofs_mats)
735 if (!eigen_problem->constJacobian())
736 all_dofs_mat->zero();
737
738 eigen_problem->computeMatricesTags(*sys.current_local_solution.get(), all_dofs_mats, tags);
739
740 if (dof_map.n_constrained_dofs())
741 for (const auto i : index_range(eigen_mats))
742 {
743 PetscMatrix<Number> wrapped_eigen_mat(eigen_mats[i], sys.comm());
744 sys.copy_super_to_sub(*all_dofs_mats[i], wrapped_eigen_mat);
745 }
746}
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
auto index_range(const T &sizable)
if(subdm)
const Number zero
Real Number
Tnew cast_ptr(Told *oldvar)

Referenced by mooseEPSFormMatrices(), and mooseSlepcEigenFormJacobianA().

◆ moosePetscSNESFormMatricesTags() [2/2]

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 712 of file SlepcSupport.C.

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

Referenced by mooseEPSFormMatrices(), and mooseSlepcEigenFormJacobianA().

◆ moosePetscSNESFormMatrixTag() [1/2]

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 681 of file SlepcSupport.C.

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

◆ moosePetscSNESFormMatrixTag() [2/2]

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 681 of file SlepcSupport.C.

683{
684 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
685 auto & nl = eigen_problem->getCurrentNonlinearEigenSystem();
686 auto & sys = nl.sys();
687 auto & dof_map = sys.get_dof_map();
688
689#ifndef NDEBUG
690 auto & petsc_all_dofs_mat = cast_ref<PetscMatrix<Number> &>(all_dofs_mat);
691 mooseAssert(
692 !dof_map.n_constrained_dofs() == (eigen_mat == petsc_all_dofs_mat.mat()),
693 "If we do not have constrained dofs, then eigen_mat and all_dofs_mat should be the same. "
694 "Conversely, if we do have constrained dofs, they must be different");
695#endif
696
697 updateCurrentLocalSolution(sys, x);
698
699 if (!eigen_problem->constJacobian())
700 all_dofs_mat.zero();
701
702 eigen_problem->computeJacobianTag(*sys.current_local_solution.get(), all_dofs_mat, tag);
703
704 if (dof_map.n_constrained_dofs())
705 {
706 PetscMatrix<Number> wrapped_eigen_mat(eigen_mat, sys.comm());
707 sys.copy_super_to_sub(all_dofs_mat, wrapped_eigen_mat);
708 }
709}

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 911 of file SlepcSupport.C.

912{
914
915 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
916 NonlinearEigenSystem & eigen_nl = eigen_problem->getCurrentNonlinearEigenSystem();
917
918 if (eigen_problem->solverParams(eigen_nl.number())._eigen_matrix_vector_mult &&
919 (eigen_problem->onLinearSolver() || eigen_problem->constantMatrices()))
920 {
921 EPS eps = eigen_nl.getEPS();
922 Mat A;
923 ST st;
924
925 LibmeshPetscCallQ(mooseEPSFormMatrices(*eigen_problem, eps, x, ctx));
926
927 // Rest ST state so that we can restrieve matrices
928 LibmeshPetscCallQ(EPSGetST(eps, &st));
929 LibmeshPetscCallQ(STResetMatrixState(st));
930 LibmeshPetscCallQ(EPSGetOperators(eps, &A, NULL));
931
932 LibmeshPetscCallQ(MatMult(A, x, r));
933
934 PetscFunctionReturn(PETSC_SUCCESS);
935 }
936
937 moosePetscSNESFormFunction(snes, x, r, ctx, eigen_nl.nonEigenVectorTag());
938
939 PetscFunctionReturn(PETSC_SUCCESS);
940}
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 985 of file SlepcSupport.C.

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

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

Referenced by attachCallbacksToMat().

◆ mooseSlepcEigenFormFunctionMFFD()

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

Function call for MFFD.

Definition at line 749 of file SlepcSupport.C.

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

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 775 of file SlepcSupport.C.

776{
777 PetscBool jisshell, pisshell;
778 PetscBool jismffd;
779
781
782 EigenProblem * eigen_problem = static_cast<EigenProblem *>(ctx);
783 NonlinearEigenSystem & eigen_nl = eigen_problem->getCurrentNonlinearEigenSystem();
784 auto & sys = eigen_nl.sys();
785
786 // If both jacobian and preconditioning are shell matrices,
787 // and then assemble them and return
788 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)jac, MATSHELL, &jisshell));
789 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)jac, MATMFFD, &jismffd));
790
791 if (jismffd && eigen_problem->solverParams(eigen_nl.number())._eigen_matrix_vector_mult)
792 {
795
796 EPS eps = eigen_nl.getEPS();
797
798 LibmeshPetscCallQ(mooseEPSFormMatrices(*eigen_problem, eps, x, ctx));
799
800 if (pc != jac)
801 {
802 LibmeshPetscCallQ(MatAssemblyBegin(jac, MAT_FINAL_ASSEMBLY));
803 LibmeshPetscCallQ(MatAssemblyEnd(jac, MAT_FINAL_ASSEMBLY));
804 }
805 PetscFunctionReturn(PETSC_SUCCESS);
806 }
807
808 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)pc, MATSHELL, &pisshell));
809 if ((jisshell || jismffd) && pisshell)
810 {
811 // Just assemble matrices and return
812 LibmeshPetscCallQ(MatAssemblyBegin(jac, MAT_FINAL_ASSEMBLY));
813 LibmeshPetscCallQ(MatAssemblyBegin(pc, MAT_FINAL_ASSEMBLY));
814 LibmeshPetscCallQ(MatAssemblyEnd(jac, MAT_FINAL_ASSEMBLY));
815 LibmeshPetscCallQ(MatAssemblyEnd(pc, MAT_FINAL_ASSEMBLY));
816
817 PetscFunctionReturn(PETSC_SUCCESS);
818 }
819
820 // Jacobian and precond matrix are the same
821 if (jac == pc)
822 {
823 if (!pisshell)
825 snes, x, pc, sys.get_matrix_A(), ctx, eigen_nl.precondMatrixTag());
826
827 PetscFunctionReturn(PETSC_SUCCESS);
828 }
829 else
830 {
831 if (!jisshell && !jismffd && !pisshell) // We need to form both Jacobian and precond matrix
832 {
833 std::vector<Mat> mats = {jac, pc};
834 std::vector<SparseMatrix<Number> *> libmesh_mats = {&sys.get_matrix_A(),
835 &sys.get_precond_matrix()};
836 std::set<TagID> tags = {eigen_nl.nonEigenMatrixTag(), eigen_nl.precondMatrixTag()};
837 moosePetscSNESFormMatricesTags(snes, x, mats, libmesh_mats, ctx, tags);
838 PetscFunctionReturn(PETSC_SUCCESS);
839 }
840 if (!pisshell) // We need to form only precond matrix
841 {
843 snes, x, pc, sys.get_precond_matrix(), ctx, eigen_nl.precondMatrixTag());
844 LibmeshPetscCallQ(MatAssemblyBegin(jac, MAT_FINAL_ASSEMBLY));
845 LibmeshPetscCallQ(MatAssemblyEnd(jac, MAT_FINAL_ASSEMBLY));
846 PetscFunctionReturn(PETSC_SUCCESS);
847 }
848 if (!jisshell && !jismffd) // We need to form only Jacobian matrix
849 {
851 snes, x, jac, sys.get_matrix_A(), ctx, eigen_nl.nonEigenMatrixTag());
852 LibmeshPetscCallQ(MatAssemblyBegin(pc, MAT_FINAL_ASSEMBLY));
853 LibmeshPetscCallQ(MatAssemblyEnd(pc, MAT_FINAL_ASSEMBLY));
854 PetscFunctionReturn(PETSC_SUCCESS);
855 }
856 }
857 PetscFunctionReturn(PETSC_SUCCESS);
858}
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 861 of file SlepcSupport.C.

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

Referenced by attachCallbacksToMat().

◆ mooseSlepcEigenFormNorm()

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

Definition at line 1053 of file SlepcSupport.C.

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

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 1311 of file SlepcSupport.C.

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

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 1387 of file SlepcSupport.C.

1395{
1396 ST st;
1397 PetscScalar eigenr, eigeni;
1398
1400 EigenProblem * eigen_problem = static_cast<EigenProblem *>(mctx);
1401 auto & console = eigen_problem->console();
1402
1403 auto inverse = eigen_problem->outputInverseEigenvalue();
1404 LibmeshPetscCallQ(EPSGetST(eps, &st));
1405 eigenr = eigr[0];
1406 eigeni = eigi[0];
1407 // Make the eigenvalue consistent with shift type
1408 LibmeshPetscCallQ(STBackTransform(st, 1, &eigenr, &eigeni));
1409
1410 auto eigenvalue = inverse ? 1.0 / eigenr : eigenr;
1411
1412 // The term "k-eigenvalue" is adopted from the neutronics community.
1413 console << " Iteration " << its << std::setprecision(10) << std::fixed
1414 << (inverse ? " k-eigenvalue = " : " eigenvalue = ") << eigenvalue << std::endl;
1415
1416 PetscFunctionReturn(PETSC_SUCCESS);
1417}
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 1369 of file SlepcSupport.C.

1370{
1371 SNES snes;
1372 KSP ksp;
1373
1375 // Get SNES from EPS
1377 // Get KSP from SNES
1378 LibmeshPetscCallQ(SNESGetKSP(snes, &ksp));
1379
1381
1383 PetscFunctionReturn(PETSC_SUCCESS);
1384}
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 1350 of file SlepcSupport.C.

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

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 1332 of file SlepcSupport.C.

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

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 1283 of file SlepcSupport.C.

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

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

1187{
1189
1190 pc->ops->view = PCView_MoosePC;
1191 pc->ops->destroy = PCDestroy_MoosePC;
1192 pc->ops->setup = PCSetUp_MoosePC;
1193 pc->ops->apply = PCApply_MoosePC;
1194
1195 PetscFunctionReturn(PETSC_SUCCESS);
1196}
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 1199 of file SlepcSupport.C.

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

Referenced by PCCreate_MoosePC().

◆ PCSetUp_MoosePC()

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

Setup preconditioner.

Definition at line 1252 of file SlepcSupport.C.

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

Referenced by PCCreate_MoosePC().

◆ PCView_MoosePC()

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

View preconditioner.

Definition at line 1208 of file SlepcSupport.C.

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

Referenced by PCCreate_MoosePC().

◆ registerPCToPETSc()

PETSC_EXTERN PetscErrorCode Moose::SlepcSupport::registerPCToPETSc ( )

Let PETSc know there is a preconditioner.

Definition at line 1176 of file SlepcSupport.C.

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

Referenced by NonlinearEigenSystem::attachPreconditioner().

◆ setEigenProblemOptions()

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

Definition at line 298 of file SlepcSupport.C.

299{
300 switch (solver_params._eigen_problem_type)
301 {
304 "-eps_hermitian");
305 break;
306
309 "-eps_non_hermitian");
310 break;
311
314 "-eps_gen_hermitian");
315 break;
316
319 "-eps_gen_indefinite");
320 break;
321
324 "-eps_gen_non_hermitian");
325 break;
326
329 "-eps_pos_gen_non_hermitian");
330 break;
331
333 break;
334
335 default:
336 mooseError("Unknown eigen solver type \n");
337 }
338}
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 212 of file SlepcSupport.C.

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

Referenced by EigenProblemSolve::EigenProblemSolve().

◆ setEigenSolverOptions()

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

Definition at line 494 of file SlepcSupport.C.

495{
496 // Avoid unused variable warnings when you have SLEPc but not PETSc-dev.
497 libmesh_ignore(params);
498
499 switch (solver_params._eigen_solve_type)
500 {
501 case Moose::EST_POWER:
502 Moose::PetscSupport::setSinglePetscOption("-eps_type", "power");
503 break;
504
506 Moose::PetscSupport::setSinglePetscOption("-eps_type", "arnoldi");
507 break;
508
510 Moose::PetscSupport::setSinglePetscOption("-eps_type", "krylovschur");
511 break;
512
515 break;
516
518 setNonlinearPowerOptions(solver_params);
519 break;
520
522 setNewtonPetscOptions(solver_params, params);
523 break;
524
525 case Moose::EST_PJFNK:
526 solver_params._eigen_matrix_free = true;
527 solver_params._customized_pc_for_eigen = false;
528 setNewtonPetscOptions(solver_params, params);
529 break;
530
531 case Moose::EST_JFNK:
532 solver_params._eigen_matrix_free = true;
533 solver_params._customized_pc_for_eigen = true;
534 setNewtonPetscOptions(solver_params, params);
535 break;
536
538 solver_params._eigen_matrix_free = true;
539 solver_params._customized_pc_for_eigen = false;
540 solver_params._eigen_matrix_vector_mult = true;
541 setNewtonPetscOptions(solver_params, params);
542 break;
543
544 default:
545 mooseError("Unknown eigen solver type \n");
546 }
547}
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
void libmesh_ignore(const Args &...)

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 404 of file SlepcSupport.C.

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

Referenced by EigenProblem::doFreeNonlinearPowerIterations().

◆ setNewtonPetscOptions()

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

Definition at line 431 of file SlepcSupport.C.

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

Referenced by setEigenSolverOptions().

◆ setNonlinearPowerOptions()

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

Definition at line 474 of file SlepcSupport.C.

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

Referenced by setEigenSolverOptions().

◆ setOperationsForShellMat()

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

Set operations to shell mat.

Definition at line 1165 of file SlepcSupport.C.

1166{
1167 LibmeshPetscCallA(eigen_problem.comm().get(), MatShellSetContext(mat, &eigen_problem));
1168 LibmeshPetscCallA(eigen_problem.comm().get(),
1169 MatShellSetOperation(mat,
1170 MATOP_MULT,
1171 eigen ? (void (*)(void))mooseMatMult_Eigen
1172 : (void (*)(void))mooseMatMult_NonEigen));
1173}
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 128 of file SlepcSupport.C.

131{
132 const auto & dont_add_these_options = eigen_problem.getPetscOptions().dont_add_these_options;
133 const auto prefix_with_dash = '-' + solver_params._prefix;
134
135 mooseAssert(solver_params._solver_sys_num != libMesh::invalid_uint,
136 "The solver system number must be initialized");
137
139 prefix_with_dash + "eps_tol",
140 stringify(params.get<Real>("eigen_tol")));
141
143 dont_add_these_options,
144 prefix_with_dash + "eps_max_it",
145 stringify(params.get<unsigned int>("eigen_max_its")));
146
147 // if it is a nonlinear eigenvalue solver, we need to set tolerances for nonlinear solver and
148 // linear solver
149 if (eigen_problem.isNonlinearEigenvalueSolver(solver_params._solver_sys_num))
150 {
151 // nonlinear solver tolerances
153 dont_add_these_options,
154 prefix_with_dash + "snes_max_it",
155 stringify(params.get<unsigned int>("nl_max_its")));
156
158 dont_add_these_options,
159 prefix_with_dash + "snes_max_funcs",
160 stringify(params.get<unsigned int>("nl_max_funcs")));
161
163 dont_add_these_options,
164 prefix_with_dash + "snes_atol",
165 stringify(params.get<Real>("nl_abs_tol")));
166
168 dont_add_these_options,
169 prefix_with_dash + "snes_rtol",
170 stringify(params.get<Real>("nl_rel_tol")));
171
173 dont_add_these_options,
174 prefix_with_dash + "snes_stol",
175 stringify(params.get<Real>("nl_rel_step_tol")));
176
177 // linear solver
179 dont_add_these_options,
180 prefix_with_dash + "ksp_max_it",
181 stringify(params.get<unsigned int>("l_max_its")));
182
184 prefix_with_dash + "ksp_rtol",
185 stringify(params.get<Real>("l_tol")));
186
188 dont_add_these_options,
189 prefix_with_dash + "ksp_atol",
190 stringify(params.get<Real>("l_abs_tol")));
191 }
192 else
193 { // linear eigenvalue problem
194 // linear solver
196 dont_add_these_options,
197 prefix_with_dash + "st_ksp_max_it",
198 stringify(params.get<unsigned int>("l_max_its")));
199
201 prefix_with_dash + "st_ksp_rtol",
202 stringify(params.get<Real>("l_tol")));
203
205 dont_add_these_options,
206 prefix_with_dash + "st_ksp_atol",
207 stringify(params.get<Real>("l_abs_tol")));
208 }
209}
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 341 of file SlepcSupport.C.

343{
344 switch (solver_params._which_eigen_pairs)
345 {
348 "-eps_largest_magnitude");
349 break;
350
353 "-eps_smallest_magnitude");
354 break;
355
358 "-eps_largest_real");
359 break;
360
363 "-eps_smallest_real");
364 break;
365
368 "-eps_largest_imaginary");
369 break;
370
373 "-eps_smallest_imaginary");
374 break;
375
378 "-eps_target_magnitude");
379 break;
380
383 "-eps_target_real");
384 break;
385
388 "-eps_target_imaginary");
389 break;
390
392 Moose::PetscSupport::setSinglePetscOptionIfAppropriate(dont_add_these_options, "-eps_all");
393 break;
394
396 break;
397
398 default:
399 mooseError("Unknown type of WhichEigenPairs \n");
400 }
401}
@ 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 550 of file SlepcSupport.C.

553{
554 const auto & dont_add_these_options = eigen_problem.getPetscOptions().dont_add_these_options;
555
557 eigen_problem.getPetscOptions(), solver_params, &eigen_problem);
558 // Call "SolverTolerances" first, so some solver specific tolerance such as "eps_max_it"
559 // can be overriden
560 setSlepcEigenSolverTolerances(eigen_problem, solver_params, params);
561 setEigenSolverOptions(solver_params, params);
562 // when Bx norm postprocessor is provided, we switch off the sign normalization
563 if (eigen_problem.bxNormProvided())
565 dont_add_these_options, "-eps_power_sign_normalization", "0", &eigen_problem);
566 setEigenProblemOptions(solver_params, eigen_problem.getPetscOptions().dont_add_these_options);
569}
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 286 of file SlepcSupport.C.

287{
288 if (!(dynamic_cast<EigenProblem *>(&fe_problem)))
289 return;
290
291 if (params.isParamValid("solve_type"))
292 for (const auto i : make_range(fe_problem.numNonlinearSystems()))
293 fe_problem.solverParams(i)._eigen_solve_type =
294 Moose::stringToEnum<Moose::EigenSolveType>(params.get<MooseEnum>("solve_type"));
295}
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 34 of file SlepcSupport.C.

Referenced by setEigenProblemSolverParams().