11#include "libmesh/shell_matrix.h"
22#include "libmesh/enum_solver_type.h"
33#include "libmesh/sparse_shell_matrix.h"
4+ #include "libmesh/solver_configuration.h"
45#ifdef LIBMESH_HAVE_PETSC
56#include "libmesh/petsc_linear_solver.h"
67#include "libmesh/petsc_vector.h"
@@ -37,10 +38,8 @@ public:
3738 // Depending on the config: Use different vector-types here!
3839 PetscLinearSolver < Number > linear_solver (* _comm );
3940 linear_solver .init ();
40- auto ierr = KSPSetType (linear_solver .ksp (), const_cast < KSPType > (KSPGMRES ));
41- CHKERRABORT (linear_solver .comm ().get (), ierr );
42- ierr = PCSetType (linear_solver .pc (), const_cast < PCType > (PCNONE ));
43- CHKERRABORT (linear_solver .comm ().get (), ierr );
41+ NoPcSolverConfiguration solver_conf (linear_solver );
42+ linear_solver .set_solver_configuration (solver_conf );
4443 KSPSetInitialGuessNonzero (linear_solver .ksp (), PETSC_TRUE );
4544
4645 unsigned int maxits = 20 ;
@@ -68,10 +67,8 @@ public:
6867 // Depending on the config: Use different vector-types here!
6968 PetscLinearSolver < Number > linear_solver (* _comm );
7069 linear_solver .init ();
71- auto ierr = KSPSetType (linear_solver .ksp (), const_cast < KSPType > (KSPGMRES ));
72- CHKERRABORT (linear_solver .comm ().get (), ierr );
73- ierr = PCSetType (linear_solver .pc (), const_cast < PCType > (PCNONE ));
74- CHKERRABORT (linear_solver .comm ().get (), ierr );
70+ NoPcSolverConfiguration solver_conf (linear_solver );
71+ linear_solver .set_solver_configuration (solver_conf );
7572 KSPSetInitialGuessNonzero (linear_solver .ksp (), PETSC_TRUE );
7673
7774 PetscMatrix < Number > petsc_mat (* _comm );
@@ -99,11 +96,13 @@ public:
9996 // a) set an irrelevant element to '0':
10097 solution -> set (7 ,2. );
10198 petsc_mat .set (2 ,2 ,0. );
99+ petsc_mat .close ();
102100 auto rval = linear_solver .solve (mat , * solution , rhs , tol , maxits );
103101 // In this case, we can solve the equation.
104102 CPPUNIT_ASSERT_EQUAL (rval .second , 0.00 );
105103 // b) set the relevant element to '0':
106104 petsc_mat .set (5 ,5 ,0. );
105+ petsc_mat .close ();
107106 rval = linear_solver .solve (mat , * solution , rhs , tol , maxits );
108107 // In this case, we can not solve the equation.
109108 // The best solution is the 0-vector and we have an error of 2.0
@@ -120,6 +119,33 @@ private:
120119 M .set (n ,n ,1. );
121120 }
122121
122+
123+ class NoPcSolverConfiguration : public libMesh ::SolverConfiguration
124+ {
125+ public :
126+
127+ NoPcSolverConfiguration (libMesh ::PetscLinearSolver < libMesh ::Number > & petsc_linear_solver ) :
128+ _petsc_linear_solver (petsc_linear_solver )
129+ {
130+ }
131+
132+ // Shell-matrices are implemented only for few solvers/preconditioners.
133+ // The SolverConfiguration overrides input-arguments, so here we force GMRES without precond.
134+ virtual void configure_solver ()
135+ {
136+ PetscErrorCode ierr = 0 ;
137+ ierr = KSPSetType (_petsc_linear_solver .ksp (), const_cast < KSPType > (KSPGMRES ));
138+ CHKERRABORT (_petsc_linear_solver .comm ().get (), ierr );
139+ ierr = PCSetType (_petsc_linear_solver .pc (), const_cast < PCType > (PCNONE ));
140+ CHKERRABORT (_petsc_linear_solver .comm ().get (), ierr );
141+ }
142+
143+ // The linear solver object that we are configuring
144+ libMesh ::PetscLinearSolver < libMesh ::Number > & _petsc_linear_solver ;
145+
146+ };
147+
148+
123149 class UnityShellMat : public libMesh ::ShellMatrix < libMesh ::Number >
124150 {
125151 public :
0 commit comments