1
1
#include "libmesh/shell_matrix.h"
2
2
#include "libmesh/enum_solver_type.h"
3
3
#include "libmesh/sparse_shell_matrix.h"
4
+ #include "libmesh/solver_configuration.h"
4
5
#ifdef LIBMESH_HAVE_PETSC
5
6
#include "libmesh/petsc_linear_solver.h"
6
7
#include "libmesh/petsc_vector.h"
@@ -37,10 +38,8 @@ public:
37
38
// Depending on the config: Use different vector-types here!
38
39
PetscLinearSolver < Number > linear_solver (* _comm );
39
40
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 );
44
43
KSPSetInitialGuessNonzero (linear_solver .ksp (), PETSC_TRUE );
45
44
46
45
unsigned int maxits = 20 ;
@@ -68,10 +67,8 @@ public:
68
67
// Depending on the config: Use different vector-types here!
69
68
PetscLinearSolver < Number > linear_solver (* _comm );
70
69
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 );
75
72
KSPSetInitialGuessNonzero (linear_solver .ksp (), PETSC_TRUE );
76
73
77
74
PetscMatrix < Number > petsc_mat (* _comm );
@@ -99,11 +96,13 @@ public:
99
96
// a) set an irrelevant element to '0':
100
97
solution -> set (7 ,2. );
101
98
petsc_mat .set (2 ,2 ,0. );
99
+ petsc_mat .close ();
102
100
auto rval = linear_solver .solve (mat , * solution , rhs , tol , maxits );
103
101
// In this case, we can solve the equation.
104
102
CPPUNIT_ASSERT_EQUAL (rval .second , 0.00 );
105
103
// b) set the relevant element to '0':
106
104
petsc_mat .set (5 ,5 ,0. );
105
+ petsc_mat .close ();
107
106
rval = linear_solver .solve (mat , * solution , rhs , tol , maxits );
108
107
// In this case, we can not solve the equation.
109
108
// The best solution is the 0-vector and we have an error of 2.0
@@ -120,6 +119,33 @@ private:
120
119
M .set (n ,n ,1. );
121
120
}
122
121
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
+
123
149
class UnityShellMat : public libMesh ::ShellMatrix < libMesh ::Number >
124
150
{
125
151
public :
0 commit comments