From 97349f9041b99c35a75a46509af20a9f3cf9c014 Mon Sep 17 00:00:00 2001 From: Fande Kong Date: Tue, 19 Nov 2019 17:02:54 -0700 Subject: [PATCH] Eigenvalue Solver: Support shell matrices Closes #7398 --- framework/include/base/SolverParams.h | 2 +- framework/include/problems/EigenProblem.h | 5 -- framework/include/utils/MooseTypes.h | 14 +++-- framework/src/base/SolverParams.C | 3 +- framework/src/executioners/Eigenvalue.C | 2 - framework/src/problems/EigenProblem.C | 6 +-- framework/src/utils/Conversion.C | 4 +- framework/src/utils/SlepcSupport.C | 53 +++++-------------- test/tests/problems/eigen_problem/ane.i | 3 +- test/tests/problems/eigen_problem/ne.i | 3 +- .../tests/problems/eigen_problem/ne_coupled.i | 3 +- .../eigen_problem/ne_coupled_picard.i | 3 +- .../ne_coupled_picard_subT_sub.i | 3 +- .../problems/eigen_problem/ne_deficient_b.i | 3 +- test/tests/problems/eigen_problem/tests | 4 +- 15 files changed, 40 insertions(+), 71 deletions(-) diff --git a/framework/include/base/SolverParams.h b/framework/include/base/SolverParams.h index 1f3d2cb89920..4741abf1fb7b 100644 --- a/framework/include/base/SolverParams.h +++ b/framework/include/base/SolverParams.h @@ -24,5 +24,5 @@ class SolverParams Moose::EigenSolveType _eigen_solve_type; Moose::EigenProblemType _eigen_problem_type; Moose::WhichEigenPairs _which_eigen_pairs; + bool _eigen_matrix_free; }; - diff --git a/framework/include/problems/EigenProblem.h b/framework/include/problems/EigenProblem.h index 5fdf5b5a42b9..fb946299b78b 100644 --- a/framework/include/problems/EigenProblem.h +++ b/framework/include/problems/EigenProblem.h @@ -57,10 +57,6 @@ class EigenProblem : public FEProblemBase */ bool negativeSignEigenKernel() { return _negative_sign_eigen_kernel; } - bool matrixFree() { return _matrix_free; } - - void matrixFree(bool matrix_free) { _matrix_free = matrix_free; } - #if LIBMESH_HAVE_SLEPC void setEigenproblemType(Moose::EigenProblemType eigen_problem_type); @@ -109,7 +105,6 @@ class EigenProblem : public FEProblemBase std::shared_ptr _nl_eigen; bool _negative_sign_eigen_kernel; - bool _matrix_free; unsigned int _active_eigen_index; /// Timers diff --git a/framework/include/utils/MooseTypes.h b/framework/include/utils/MooseTypes.h index bc41f1049187..e6068f7fc339 100644 --- a/framework/include/utils/MooseTypes.h +++ b/framework/include/utils/MooseTypes.h @@ -735,14 +735,12 @@ enum SolveType */ enum EigenSolveType { - EST_POWER, ///< Power / Inverse / RQI - EST_ARNOLDI, ///< Arnoldi - EST_KRYLOVSCHUR, ///< Krylov-Schur - EST_JACOBI_DAVIDSON, ///< Jacobi-Davidson - EST_NONLINEAR_POWER, ///< Nonlinear inverse power - EST_MF_NONLINEAR_POWER, ///< Matrix-free nonlinear inverse power - EST_MONOLITH_NEWTON, ///< Newton-based eigen solver - EST_MF_MONOLITH_NEWTON, ///< Matrix-free Newton-based eigen solver + EST_POWER, ///< Power / Inverse / RQI + EST_ARNOLDI, ///< Arnoldi + EST_KRYLOVSCHUR, ///< Krylov-Schur + EST_JACOBI_DAVIDSON, ///< Jacobi-Davidson + EST_NONLINEAR_POWER, ///< Nonlinear inverse power + EST_NEWTON, ///< Newton-based eigen solver }; /** diff --git a/framework/src/base/SolverParams.C b/framework/src/base/SolverParams.C index a394fcfd9d53..3d27d1ec6098 100644 --- a/framework/src/base/SolverParams.C +++ b/framework/src/base/SolverParams.C @@ -15,6 +15,7 @@ SolverParams::SolverParams() _mffd_type(Moose::MFFD_INVALID), _eigen_solve_type(Moose::EST_KRYLOVSCHUR), _eigen_problem_type(Moose::EPT_SLEPC_DEFAULT), - _which_eigen_pairs(Moose::WEP_SLEPC_DEFAULT) + _which_eigen_pairs(Moose::WEP_SLEPC_DEFAULT), + _eigen_matrix_free(false) { } diff --git a/framework/src/executioners/Eigenvalue.C b/framework/src/executioners/Eigenvalue.C index c1101d3905c1..5efc4ea37c1b 100644 --- a/framework/src/executioners/Eigenvalue.C +++ b/framework/src/executioners/Eigenvalue.C @@ -62,8 +62,6 @@ Eigenvalue::Eigenvalue(const InputParameters & parameters) Moose::SlepcSupport::storeSlepcEigenProblemOptions(_eigen_problem, parameters); _eigen_problem.setEigenproblemType(_eigen_problem.solverParams()._eigen_problem_type); - - _eigen_problem.matrixFree(getParam("matrix_free")); #endif if (!parameters.isParamValid("normalization") && parameters.isParamSetByUser("normal_factor")) diff --git a/framework/src/problems/EigenProblem.C b/framework/src/problems/EigenProblem.C index e92f9ee30d17..141834dbf0cd 100644 --- a/framework/src/problems/EigenProblem.C +++ b/framework/src/problems/EigenProblem.C @@ -304,7 +304,7 @@ void EigenProblem::init() { // If matrix_free=true, this set Libmesh to use shell matrices - _nl_eigen->sys().use_shell_matrices(_matrix_free); + _nl_eigen->sys().use_shell_matrices(solverParams()._eigen_matrix_free); FEProblemBase::init(); @@ -322,7 +322,5 @@ bool EigenProblem::isNonlinearEigenvalueSolver() { return solverParams()._eigen_solve_type == Moose::EST_NONLINEAR_POWER || - solverParams()._eigen_solve_type == Moose::EST_MF_NONLINEAR_POWER || - solverParams()._eigen_solve_type == Moose::EST_MONOLITH_NEWTON || - solverParams()._eigen_solve_type == Moose::EST_MF_MONOLITH_NEWTON; + solverParams()._eigen_solve_type == Moose::EST_NEWTON; } diff --git a/framework/src/utils/Conversion.C b/framework/src/utils/Conversion.C index d997213c5f73..054d855bb598 100644 --- a/framework/src/utils/Conversion.C +++ b/framework/src/utils/Conversion.C @@ -82,9 +82,7 @@ initEigenSolveType() eigen_solve_type_to_enum["KRYLOVSCHUR"] = EST_KRYLOVSCHUR; eigen_solve_type_to_enum["JACOBI_DAVIDSON"] = EST_JACOBI_DAVIDSON; eigen_solve_type_to_enum["NONLINEAR_POWER"] = EST_NONLINEAR_POWER; - eigen_solve_type_to_enum["MF_NONLINEAR_POWER"] = EST_MF_NONLINEAR_POWER; - eigen_solve_type_to_enum["MONOLITH_NEWTON"] = EST_MONOLITH_NEWTON; - eigen_solve_type_to_enum["MF_MONOLITH_NEWTON"] = EST_MF_MONOLITH_NEWTON; + eigen_solve_type_to_enum["NEWTON"] = EST_NEWTON; } } diff --git a/framework/src/utils/SlepcSupport.C b/framework/src/utils/SlepcSupport.C index a03859fcd1e5..1c1d46ec1935 100644 --- a/framework/src/utils/SlepcSupport.C +++ b/framework/src/utils/SlepcSupport.C @@ -35,8 +35,7 @@ InputParameters getSlepcValidParams(InputParameters & params) { MooseEnum solve_type("POWER ARNOLDI KRYLOVSCHUR JACOBI_DAVIDSON " - "NONLINEAR_POWER MF_NONLINEAR_POWER " - "MONOLITH_NEWTON MF_MONOLITH_NEWTON"); + "NONLINEAR_POWER NEWTON"); params.set("solve_type") = solve_type; params.setDocString("solve_type", @@ -45,9 +44,7 @@ getSlepcValidParams(InputParameters & params) "KRYLOVSCHUR: Krylov-Schur " "JACOBI_DAVIDSON: Jacobi-Davidson " "NONLINEAR_POWER: Nonlinear Power " - "MF_NONLINEAR_POWER: Matrix-free Nonlinear Power " - "MONOLITH_NEWTON: Newton " - "MF_MONOLITH_NEWTON: Matrix-free Newton "); + "NEWTON: Newton "); // When the eigenvalue problems is reformed as a coupled nonlinear system, // we use part of Jacobian as the preconditioning matrix. @@ -197,6 +194,8 @@ storeSlepcEigenProblemOptions(EigenProblem & eigen_problem, const InputParameter } eigen_problem.es().parameters.set("basis vectors") = n_basis_vectors; + + eigen_problem.solverParams()._eigen_matrix_free = params.get("matrix_free"); } void @@ -257,13 +256,11 @@ setSlepcOutputOptions(EigenProblem & eigen_problem) switch (eigen_problem.solverParams()._eigen_solve_type) { case Moose::EST_NONLINEAR_POWER: - case Moose::EST_MF_NONLINEAR_POWER: Moose::PetscSupport::setSinglePetscOption("-eps_power_snes_monitor"); Moose::PetscSupport::setSinglePetscOption("-eps_power_ksp_monitor"); break; - case Moose::EST_MONOLITH_NEWTON: - case Moose::EST_MF_MONOLITH_NEWTON: + case Moose::EST_NEWTON: Moose::PetscSupport::setSinglePetscOption("-init_eps_monitor_conv"); Moose::PetscSupport::setSinglePetscOption("-init_eps_monitor"); Moose::PetscSupport::setSinglePetscOption("-eps_power_snes_monitor"); @@ -367,23 +364,14 @@ setEigenSolverOptions(SolverParams & solver_params, const InputParameters & para Moose::PetscSupport::setSinglePetscOption("-eps_type", "power"); Moose::PetscSupport::setSinglePetscOption("-eps_power_nonlinear", "1"); Moose::PetscSupport::setSinglePetscOption("-eps_target_magnitude", ""); + if (solver_params._eigen_matrix_free) + Moose::PetscSupport::setSinglePetscOption("-eps_power_snes_mf_operator", "1"); #else mooseError("Nonlinear Inverse Power requires SLEPc 3.7.3 or higher"); #endif - break; - case Moose::EST_MF_NONLINEAR_POWER: -#if !SLEPC_VERSION_LESS_THAN(3, 8, 0) || !PETSC_VERSION_RELEASE - Moose::PetscSupport::setSinglePetscOption("-eps_type", "power"); - Moose::PetscSupport::setSinglePetscOption("-eps_power_nonlinear", "1"); - Moose::PetscSupport::setSinglePetscOption("-eps_power_snes_mf_operator", "1"); - Moose::PetscSupport::setSinglePetscOption("-eps_target_magnitude", ""); -#else - mooseError("Matrix-free nonlinear Inverse Power requires SLEPc 3.7.3 or higher"); -#endif - break; - case Moose::EST_MONOLITH_NEWTON: + case Moose::EST_NEWTON: #if !SLEPC_VERSION_LESS_THAN(3, 8, 0) || !PETSC_VERSION_RELEASE Moose::PetscSupport::setSinglePetscOption("-eps_type", "power"); Moose::PetscSupport::setSinglePetscOption("-eps_power_nonlinear", "1"); @@ -393,28 +381,15 @@ setEigenSolverOptions(SolverParams & solver_params, const InputParameters & para Moose::PetscSupport::setSinglePetscOption( "-init_eps_max_it", stringify(params.get("free_power_iterations"))); Moose::PetscSupport::setSinglePetscOption("-eps_target_magnitude", ""); + if (solver_params._eigen_matrix_free) + { + Moose::PetscSupport::setSinglePetscOption("-eps_power_snes_mf_operator", "1"); + Moose::PetscSupport::setSinglePetscOption("-init_eps_power_snes_mf_operator", "1"); + } #else - mooseError("Newton-based eigenvalue solver requires SLEPc 3.7.3 or higher"); + mooseError("Newton-based eigenvalue solver requires SLEPc 3.7.3 or higher"); #endif break; - - case Moose::EST_MF_MONOLITH_NEWTON: -#if !SLEPC_VERSION_LESS_THAN(3, 8, 0) || !PETSC_VERSION_RELEASE - Moose::PetscSupport::setSinglePetscOption("-eps_type", "power"); - Moose::PetscSupport::setSinglePetscOption("-eps_power_nonlinear", "1"); - Moose::PetscSupport::setSinglePetscOption("-eps_power_update", "1"); - Moose::PetscSupport::setSinglePetscOption("-eps_power_snes_mf_operator", "1"); - Moose::PetscSupport::setSinglePetscOption("-init_eps_power_snes_mf_operator", "1"); - Moose::PetscSupport::setSinglePetscOption("-init_eps_power_snes_max_it", "1"); - Moose::PetscSupport::setSinglePetscOption("-init_eps_power_ksp_rtol", "1e-2"); - Moose::PetscSupport::setSinglePetscOption( - "-init_eps_max_it", stringify(params.get("free_power_iterations"))); - Moose::PetscSupport::setSinglePetscOption("-eps_target_magnitude", ""); -#else - mooseError("Matrix-free Newton-based eigenvalue solver requires SLEPc 3.7.3 or higher"); -#endif - break; - default: mooseError("Unknown eigen solver type \n"); } diff --git a/test/tests/problems/eigen_problem/ane.i b/test/tests/problems/eigen_problem/ane.i index 00a7b3a184f4..2d5e8c8814da 100644 --- a/test/tests/problems/eigen_problem/ane.i +++ b/test/tests/problems/eigen_problem/ane.i @@ -53,7 +53,8 @@ [Executioner] type = Eigenvalue - solve_type = MF_MONOLITH_NEWTON + matrix_free = false + solve_type = NEWTON eigen_problem_type = GEN_NON_HERMITIAN [] diff --git a/test/tests/problems/eigen_problem/ne.i b/test/tests/problems/eigen_problem/ne.i index 44651401fdf1..bdc3b03c999e 100644 --- a/test/tests/problems/eigen_problem/ne.i +++ b/test/tests/problems/eigen_problem/ne.i @@ -50,7 +50,8 @@ [Executioner] type = Eigenvalue - solve_type = MF_MONOLITH_NEWTON + matrix_free = true + solve_type = NEWTON eigen_problem_type = GEN_NON_HERMITIAN [] diff --git a/test/tests/problems/eigen_problem/ne_coupled.i b/test/tests/problems/eigen_problem/ne_coupled.i index b24901555aad..f2fdc0910d8f 100644 --- a/test/tests/problems/eigen_problem/ne_coupled.i +++ b/test/tests/problems/eigen_problem/ne_coupled.i @@ -107,7 +107,8 @@ [Executioner] type = Eigenvalue - solve_type = MF_MONOLITH_NEWTON + matrix_free = true + solve_type = NEWTON eigen_problem_type = GEN_NON_HERMITIAN [] diff --git a/test/tests/problems/eigen_problem/ne_coupled_picard.i b/test/tests/problems/eigen_problem/ne_coupled_picard.i index bcf3992d5ba3..ea66d8de4922 100644 --- a/test/tests/problems/eigen_problem/ne_coupled_picard.i +++ b/test/tests/problems/eigen_problem/ne_coupled_picard.i @@ -86,7 +86,8 @@ [Executioner] type = Eigenvalue - solve_type = MF_MONOLITH_NEWTON + matrix_free = true + solve_type = NEWTON eigen_problem_type = GEN_NON_HERMITIAN picard_max_its = 10 picard_rel_tol = 1e-6 diff --git a/test/tests/problems/eigen_problem/ne_coupled_picard_subT_sub.i b/test/tests/problems/eigen_problem/ne_coupled_picard_subT_sub.i index 3573511e0505..9310ea0e3b3c 100644 --- a/test/tests/problems/eigen_problem/ne_coupled_picard_subT_sub.i +++ b/test/tests/problems/eigen_problem/ne_coupled_picard_subT_sub.i @@ -81,7 +81,8 @@ [Executioner] type = Eigenvalue - solve_type = MF_MONOLITH_NEWTON + matrix_free = true + solve_type = NEWTON eigen_problem_type = GEN_NON_HERMITIAN [] diff --git a/test/tests/problems/eigen_problem/ne_deficient_b.i b/test/tests/problems/eigen_problem/ne_deficient_b.i index 84b5880ce229..5b3946dcc1ec 100644 --- a/test/tests/problems/eigen_problem/ne_deficient_b.i +++ b/test/tests/problems/eigen_problem/ne_deficient_b.i @@ -79,7 +79,8 @@ [Executioner] type = Eigenvalue - solve_type = MF_MONOLITH_NEWTON + matrix_free = true + solve_type = NEWTON eigen_problem_type = GEN_NON_HERMITIAN [] diff --git a/test/tests/problems/eigen_problem/tests b/test/tests/problems/eigen_problem/tests index a94d5dae042f..bc4b6d7ff18f 100644 --- a/test/tests/problems/eigen_problem/tests +++ b/test/tests/problems/eigen_problem/tests @@ -56,7 +56,7 @@ [./nonlinear_power] type = 'CSVDiff' input = 'ne.i' - cli_args = 'Executioner/solve_type=MF_NONLINEAR_POWER Outputs/file_base=nonlinear_power' + cli_args = 'Executioner/solve_type=NONLINEAR_POWER Executioner/matrix_free=true Outputs/file_base=nonlinear_power' csvdiff = 'nonlinear_power_eigenvalues_0001.csv' slepc_version = '>=3.8.0' requirement = "Eigenvalue system should be able to solve a nonlinear eigenvalue problem" @@ -65,7 +65,7 @@ [./monolith_newton] type = 'CSVDiff' input = 'ne.i' - cli_args = 'Executioner/solve_type=MF_MONOLITH_NEWTON Outputs/file_base=monolith_newton' + cli_args = 'Executioner/solve_type=NEWTON Executioner/matrix_free=true Outputs/file_base=monolith_newton' csvdiff = 'monolith_newton_eigenvalues_0001.csv' slepc_version = '>=3.8.0' requirement = "Eigenvalue system should be able to solve a nonlinear eigenvalue problem using Newton"