diff --git a/framework/include/outputs/OutputWarehouse.h b/framework/include/outputs/OutputWarehouse.h index 53d372ab7eaa..3da09087a99f 100644 --- a/framework/include/outputs/OutputWarehouse.h +++ b/framework/include/outputs/OutputWarehouse.h @@ -194,6 +194,12 @@ class OutputWarehouse /// Reset the output system void reset(); + /** + * Calls the timestepSetup function for each of the output objects + * @see FEProblemBase::solve() + */ + void solveSetup(); + private: /** * Calls the outputStep method for each output object @@ -247,12 +253,6 @@ class OutputWarehouse */ void timestepSetup(); - /** - * Calls the timestepSetup function for each of the output objects - * @see FEProblemBase::solve() - */ - void solveSetup(); - /** * Calls the jacobianSetup function for each of the output objects * @see FEProblemBase::computeJacobian diff --git a/framework/include/problems/EigenProblem.h b/framework/include/problems/EigenProblem.h index dd32be458990..33cb5e998e90 100644 --- a/framework/include/problems/EigenProblem.h +++ b/framework/include/problems/EigenProblem.h @@ -138,6 +138,11 @@ class EigenProblem : public FEProblemBase * Which eigenvalue is active */ unsigned int activeEigenvalueIndex() { return _active_eigen_index; } + + const ConsoleStream & console() { return _console; } + + virtual void initPetscOutput() override; + #endif protected: diff --git a/framework/include/problems/FEProblemBase.h b/framework/include/problems/FEProblemBase.h index fcd5ffe82cb2..6f3b0b318b07 100644 --- a/framework/include/problems/FEProblemBase.h +++ b/framework/include/problems/FEProblemBase.h @@ -526,7 +526,7 @@ class FEProblemBase : public SubProblem, public Restartable /** * Reinitialize petsc output for proper linear/nonlinear iteration display */ - void initPetscOutput(); + virtual void initPetscOutput(); #ifdef LIBMESH_HAVE_PETSC /** diff --git a/framework/include/systems/DumpObjectsNonlinearSystem.h b/framework/include/systems/DumpObjectsNonlinearSystem.h index e52a6278188a..7c5c277df239 100644 --- a/framework/include/systems/DumpObjectsNonlinearSystem.h +++ b/framework/include/systems/DumpObjectsNonlinearSystem.h @@ -31,6 +31,7 @@ class DumpObjectsNonlinearSystem : public NonlinearSystemBase virtual void stopSolve() override {} virtual bool converged() override { return true; } virtual NumericVector & RHS() override { return *_dummy; } + virtual SNES getSNES() override { return nullptr; } virtual unsigned int getCurrentNonlinearIterationNumber() override { return 0; } virtual void setupFiniteDifferencedPreconditioner() override {} diff --git a/framework/include/systems/NonlinearEigenSystem.h b/framework/include/systems/NonlinearEigenSystem.h index e1a996b1ec00..db6b82660a11 100644 --- a/framework/include/systems/NonlinearEigenSystem.h +++ b/framework/include/systems/NonlinearEigenSystem.h @@ -93,6 +93,8 @@ class NonlinearEigenSystem : public NonlinearSystemBase virtual NonlinearSolver * nonlinearSolver() override; + virtual SNES getSNES() override; + virtual TransientEigenSystem & sys() { return _transient_sys; } /** diff --git a/framework/include/systems/NonlinearSystem.h b/framework/include/systems/NonlinearSystem.h index 7bbef32231cc..d1db9e2b7d53 100644 --- a/framework/include/systems/NonlinearSystem.h +++ b/framework/include/systems/NonlinearSystem.h @@ -64,6 +64,8 @@ class NonlinearSystem : public NonlinearSystemBase return _transient_sys.nonlinear_solver.get(); } + virtual SNES getSNES() override; + virtual TransientNonlinearImplicitSystem & sys() { return _transient_sys; } virtual void attachPreconditioner(Preconditioner * preconditioner) override; diff --git a/framework/include/systems/NonlinearSystemBase.h b/framework/include/systems/NonlinearSystemBase.h index 0b14ef5f4adf..f9a9feffeab2 100644 --- a/framework/include/systems/NonlinearSystemBase.h +++ b/framework/include/systems/NonlinearSystemBase.h @@ -85,6 +85,8 @@ class NonlinearSystemBase : public SystemBase, public PerfGraphInterface virtual NonlinearSolver * nonlinearSolver() = 0; + virtual SNES getSNES() = 0; + virtual unsigned int getCurrentNonlinearIterationNumber() = 0; /** diff --git a/framework/include/utils/SlepcSupport.h b/framework/include/utils/SlepcSupport.h index d71cda86d2c4..afda24e6292f 100644 --- a/framework/include/utils/SlepcSupport.h +++ b/framework/include/utils/SlepcSupport.h @@ -21,7 +21,7 @@ /* We need this in order to implement moose PC */ #include #include -#include +#include /* In order to use libMesh preconditioner */ #include "libmesh/linear_solver.h" #include "libmesh/preconditioner.h" @@ -45,7 +45,7 @@ void storeSlepcOptions(FEProblemBase & fe_problem, const InputParameters & param void storeSlepcEigenProblemOptions(EigenProblem & eigen_problem, const InputParameters & params); void slepcSetOptions(EigenProblem & eigen_problem, const InputParameters & params); void setSlepcEigenSolverTolerances(EigenProblem & eigen_problem, const InputParameters & params); -void setSlepcOutputOptions(EigenProblem & eigen_problem); +void setSlepcOutputOptions(); void setFreeNonlinearPowerIterations(unsigned int free_power_iterations); void clearFreeNonlinearPowerIterations(const InputParameters & params); void moosePetscSNESFormMatrixTag(SNES snes, Vec x, Mat mat, void * ctx, TagID tag); @@ -57,6 +57,15 @@ PetscErrorCode mooseSlepcEigenFormFunctionA(SNES snes, Vec x, Vec r, void * ctx) PetscErrorCode mooseSlepcEigenFormFunctionB(SNES snes, Vec x, Vec r, void * ctx); PetscErrorCode mooseSlepcEigenFormFunctionAB(SNES snes, Vec x, Vec Ax, Vec Bx, void * ctx); PetscErrorCode mooseSlepcStoppingTest(EPS eps,PetscInt its,PetscInt max_it,PetscInt nconv,PetscInt nev,EPSConvergedReason *reason,void *ctx); +PetscErrorCode epsGetSNES(EPS eps, SNES * snes); +PetscErrorCode mooseSlepcEPSMonitor(EPS eps, + int its, + int nconv, + PetscScalar * eigr, + PetscScalar * eigi, + PetscReal * errest, + int nest, + void * mctx); void attachCallbacksToMat(EigenProblem & eigen_problem, Mat mat, bool eigen); diff --git a/framework/src/executioners/Eigenvalue.C b/framework/src/executioners/Eigenvalue.C index 8cfebeac5418..facb08b7d8ed 100644 --- a/framework/src/executioners/Eigenvalue.C +++ b/framework/src/executioners/Eigenvalue.C @@ -52,13 +52,12 @@ Eigenvalue::validParams() "normal_factor", 1.0, "Normalize eigenvector to make a defined norm equal to this factor"); params.addParam("auto_initialization", - false, + true, "If true, we will set an initial eigen vector in moose, otherwise EPS " "solver will initial eigen vector"); - params.addParam("newton_inverse_power", - true, - "If Newton and Inverse Power is combined in SLEPc side"); + params.addParam( + "newton_inverse_power", false, "If Newton and Inverse Power is combined in SLEPc side"); // Add slepc options and eigen problems #ifdef LIBMESH_HAVE_SLEPC @@ -122,6 +121,8 @@ Eigenvalue::init() if (_eigen_problem.needInitializeEigenVector()) _eigen_problem.initEigenvector(1.0); + _console << " Free power iteration starts" << std::endl; + // Call solver _eigen_problem.solve(); // Clear free power iterations @@ -144,6 +145,9 @@ Eigenvalue::execute() _eigen_problem.doInitialFreePowerIteration(true); // Set free power iterations setFreeNonlinearPowerIterations(extra_power_iterations); + + _console << " Extra Free power iteration starts" << std::endl; + // Call solver _eigen_problem.solve(); // Clear free power iterations @@ -152,6 +156,11 @@ Eigenvalue::execute() _eigen_problem.doInitialFreePowerIteration(false); } + if (_eigen_problem.solverParams()._eigen_solve_type != Moose::EST_NONLINEAR_POWER) + _console << " Nonlinear Newton iteration starts" << std::endl; + else + _console << " Nonlinear power iteration starts" << std::endl; + Steady::execute(); } diff --git a/framework/src/outputs/PetscOutput.C b/framework/src/outputs/PetscOutput.C index 4f750500274e..c9dd6d3bacbb 100644 --- a/framework/src/outputs/PetscOutput.C +++ b/framework/src/outputs/PetscOutput.C @@ -134,9 +134,7 @@ PetscOutput::solveSetup() // Extract the non-linear and linear solvers from PETSc NonlinearSystemBase & nl = _problem_ptr->getNonlinearSystemBase(); - PetscNonlinearSolver * petsc_solver = - dynamic_cast *>(nl.nonlinearSolver()); - SNES snes = petsc_solver->snes(); + SNES snes = nl.getSNES(); KSP ksp; SNESGetKSP(snes, &ksp); diff --git a/framework/src/problems/EigenProblem.C b/framework/src/problems/EigenProblem.C index 51836e562619..9848f375617d 100644 --- a/framework/src/problems/EigenProblem.C +++ b/framework/src/problems/EigenProblem.C @@ -411,3 +411,9 @@ EigenProblem::needInitializeEigenVector() { return _auto_initilize_eigen_vector && isNonlinearEigenvalueSolver(); } + +void +EigenProblem::initPetscOutput() +{ + _app.getOutputWarehouse().solveSetup(); +} diff --git a/framework/src/systems/NonlinearEigenSystem.C b/framework/src/systems/NonlinearEigenSystem.C index f140f717b97c..ca577b7e22a1 100644 --- a/framework/src/systems/NonlinearEigenSystem.C +++ b/framework/src/systems/NonlinearEigenSystem.C @@ -397,6 +397,26 @@ NonlinearEigenSystem::nonlinearSolver() return NULL; } +SNES +NonlinearEigenSystem::getSNES() +{ + SlepcEigenSolver * solver = + libmesh_cast_ptr *>(&(*_transient_sys.eigen_solver)); + + if (!solver) + mooseError("There is no a eigen solver"); + + if (_eigen_problem.isNonlinearEigenvalueSolver()) + { + EPS eps = solver->eps(); + SNES snes = nullptr; + Moose::SlepcSupport::epsGetSNES(eps, &snes); + return snes; + } + else + mooseError("There is no SNES in linear eigen solver"); +} + void NonlinearEigenSystem::checkIntegrity() { diff --git a/framework/src/systems/NonlinearSystem.C b/framework/src/systems/NonlinearSystem.C index e56a74ecf23a..33bbc5087914 100644 --- a/framework/src/systems/NonlinearSystem.C +++ b/framework/src/systems/NonlinearSystem.C @@ -446,3 +446,15 @@ NonlinearSystem::computeScalingResidual() { _fe_problem.computeResidualSys(_transient_sys, *_current_solution, RHS()); } + +SNES +NonlinearSystem::getSNES() +{ + PetscNonlinearSolver * petsc_solver = + dynamic_cast *>(nonlinearSolver()); + + if (petsc_solver) + return petsc_solver->snes(); + else + mooseError("It is not a petsc nonlinear solver"); +} diff --git a/framework/src/utils/SlepcEigenSolverConfiguration.C b/framework/src/utils/SlepcEigenSolverConfiguration.C index 013d729b2e33..b65b61fbd42b 100644 --- a/framework/src/utils/SlepcEigenSolverConfiguration.C +++ b/framework/src/utils/SlepcEigenSolverConfiguration.C @@ -26,10 +26,20 @@ SlepcEigenSolverConfiguration::SlepcEigenSolverConfiguration(EigenProblem & eige void SlepcEigenSolverConfiguration::configure_solver() { - PetscErrorCode ierr; - - std::cout<<" configure_solver "<nconv = 1; } + return 0; +} + +PetscErrorCode +epsGetSNES(EPS eps, SNES * snes) +{ + PetscErrorCode ierr; + PetscBool same, nonlinear; + + ierr = PetscObjectTypeCompare((PetscObject)eps, EPSPOWER, &same); + LIBMESH_CHKERR(ierr); + + if (!same) + mooseError("It is not eps power, and there is no snes"); + + ierr = EPSPowerGetNonlinear(eps, &nonlinear); + LIBMESH_CHKERR(ierr); + + if (!nonlinear) + mooseError("It is not a nonlinear eigen solver"); + + ierr = EPSPowerGetSNES(eps, snes); + LIBMESH_CHKERR(ierr); + + return 0; +} + +PetscErrorCode +mooseSlepcEPSMonitor(EPS /*eps*/, + int its, + int /*nconv*/, + PetscScalar * eigr, + PetscScalar * /*eigi*/, + PetscReal * /*errest*/, + int /*nest*/, + void * mctx) +{ + EigenProblem * eigen_problem = static_cast(mctx); + auto & console = eigen_problem->console(); - std::cout<<"its "<