xref: /petsc/src/ksp/pc/interface/pcset.c (revision 4b9ad92859ccb93b5e851e53cb8c4c04ac10e155)
1*4b9ad928SBarry Smith /*$Id: pcset.c,v 1.118 2001/08/21 21:03:13 bsmith Exp $*/
2*4b9ad928SBarry Smith /*
3*4b9ad928SBarry Smith     Routines to set PC methods and options.
4*4b9ad928SBarry Smith */
5*4b9ad928SBarry Smith 
6*4b9ad928SBarry Smith #include "src/ksp/pc/pcimpl.h"      /*I "petscpc.h" I*/
7*4b9ad928SBarry Smith #include "petscsys.h"
8*4b9ad928SBarry Smith 
9*4b9ad928SBarry Smith PetscTruth PCRegisterAllCalled = PETSC_FALSE;
10*4b9ad928SBarry Smith /*
11*4b9ad928SBarry Smith    Contains the list of registered KSP routines
12*4b9ad928SBarry Smith */
13*4b9ad928SBarry Smith PetscFList PCList = 0;
14*4b9ad928SBarry Smith 
15*4b9ad928SBarry Smith #undef __FUNCT__
16*4b9ad928SBarry Smith #define __FUNCT__ "PCSetType"
17*4b9ad928SBarry Smith /*@C
18*4b9ad928SBarry Smith    PCSetType - Builds PC for a particular preconditioner.
19*4b9ad928SBarry Smith 
20*4b9ad928SBarry Smith    Collective on PC
21*4b9ad928SBarry Smith 
22*4b9ad928SBarry Smith    Input Parameter:
23*4b9ad928SBarry Smith +  pc - the preconditioner context.
24*4b9ad928SBarry Smith -  type - a known method
25*4b9ad928SBarry Smith 
26*4b9ad928SBarry Smith    Options Database Key:
27*4b9ad928SBarry Smith .  -pc_type <type> - Sets PC type
28*4b9ad928SBarry Smith 
29*4b9ad928SBarry Smith    Use -help for a list of available methods (for instance,
30*4b9ad928SBarry Smith    jacobi or bjacobi)
31*4b9ad928SBarry Smith 
32*4b9ad928SBarry Smith   Notes:
33*4b9ad928SBarry Smith   See "petsc/include/petscpc.h" for available methods (for instance,
34*4b9ad928SBarry Smith   PCJACOBI, PCILU, or PCBJACOBI).
35*4b9ad928SBarry Smith 
36*4b9ad928SBarry Smith   Normally, it is best to use the KSPSetFromOptions() command and
37*4b9ad928SBarry Smith   then set the PC type from the options database rather than by using
38*4b9ad928SBarry Smith   this routine.  Using the options database provides the user with
39*4b9ad928SBarry Smith   maximum flexibility in evaluating the many different preconditioners.
40*4b9ad928SBarry Smith   The PCSetType() routine is provided for those situations where it
41*4b9ad928SBarry Smith   is necessary to set the preconditioner independently of the command
42*4b9ad928SBarry Smith   line or options database.  This might be the case, for example, when
43*4b9ad928SBarry Smith   the choice of preconditioner changes during the execution of the
44*4b9ad928SBarry Smith   program, and the user's application is taking responsibility for
45*4b9ad928SBarry Smith   choosing the appropriate preconditioner.  In other words, this
46*4b9ad928SBarry Smith   routine is not for beginners.
47*4b9ad928SBarry Smith 
48*4b9ad928SBarry Smith   Level: intermediate
49*4b9ad928SBarry Smith 
50*4b9ad928SBarry Smith .keywords: PC, set, method, type
51*4b9ad928SBarry Smith 
52*4b9ad928SBarry Smith .seealso: KSPSetType(), PCType
53*4b9ad928SBarry Smith 
54*4b9ad928SBarry Smith @*/
55*4b9ad928SBarry Smith int PCSetType(PC pc,PCType type)
56*4b9ad928SBarry Smith {
57*4b9ad928SBarry Smith   int        ierr,(*r)(PC);
58*4b9ad928SBarry Smith   PetscTruth match;
59*4b9ad928SBarry Smith 
60*4b9ad928SBarry Smith   PetscFunctionBegin;
61*4b9ad928SBarry Smith   PetscValidHeaderSpecific(pc,PC_COOKIE);
62*4b9ad928SBarry Smith   PetscValidCharPointer(type);
63*4b9ad928SBarry Smith 
64*4b9ad928SBarry Smith   ierr = PetscTypeCompare((PetscObject)pc,type,&match);CHKERRQ(ierr);
65*4b9ad928SBarry Smith   if (match) PetscFunctionReturn(0);
66*4b9ad928SBarry Smith 
67*4b9ad928SBarry Smith   if (pc->ops->destroy) {ierr =  (*pc->ops->destroy)(pc);CHKERRQ(ierr);}
68*4b9ad928SBarry Smith   ierr = PetscFListDestroy(&pc->qlist);CHKERRQ(ierr);
69*4b9ad928SBarry Smith   pc->data        = 0;
70*4b9ad928SBarry Smith   pc->setupcalled = 0;
71*4b9ad928SBarry Smith 
72*4b9ad928SBarry Smith   /* Get the function pointers for the method requested */
73*4b9ad928SBarry Smith   if (!PCRegisterAllCalled) {ierr = PCRegisterAll(0);CHKERRQ(ierr);}
74*4b9ad928SBarry Smith 
75*4b9ad928SBarry Smith   /* Determine the PCCreateXXX routine for a particular preconditioner */
76*4b9ad928SBarry Smith   ierr =  PetscFListFind(pc->comm,PCList,type,(void (**)(void)) &r);CHKERRQ(ierr);
77*4b9ad928SBarry Smith   if (!r) SETERRQ1(1,"Unable to find requested PC type %s",type);
78*4b9ad928SBarry Smith   if (pc->data) {ierr = PetscFree(pc->data);CHKERRQ(ierr);}
79*4b9ad928SBarry Smith 
80*4b9ad928SBarry Smith   pc->ops->destroy             = (int (*)(PC)) 0;
81*4b9ad928SBarry Smith   pc->ops->view                = (int (*)(PC,PetscViewer)) 0;
82*4b9ad928SBarry Smith   pc->ops->apply               = (int (*)(PC,Vec,Vec)) 0;
83*4b9ad928SBarry Smith   pc->ops->setup               = (int (*)(PC)) 0;
84*4b9ad928SBarry Smith   pc->ops->applyrichardson     = (int (*)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int)) 0;
85*4b9ad928SBarry Smith   pc->ops->applyBA             = (int (*)(PC,int,Vec,Vec,Vec)) 0;
86*4b9ad928SBarry Smith   pc->ops->setfromoptions      = (int (*)(PC)) 0;
87*4b9ad928SBarry Smith   pc->ops->applytranspose      = (int (*)(PC,Vec,Vec)) 0;
88*4b9ad928SBarry Smith   pc->ops->applyBAtranspose    = (int (*)(PC,int,Vec,Vec,Vec)) 0;
89*4b9ad928SBarry Smith   pc->ops->presolve            = (int (*)(PC,KSP,Vec,Vec)) 0;
90*4b9ad928SBarry Smith   pc->ops->postsolve           = (int (*)(PC,KSP,Vec,Vec)) 0;
91*4b9ad928SBarry Smith   pc->ops->getfactoredmatrix   = (int (*)(PC,Mat*)) 0;
92*4b9ad928SBarry Smith   pc->ops->applysymmetricleft  = (int (*)(PC,Vec,Vec)) 0;
93*4b9ad928SBarry Smith   pc->ops->applysymmetricright = (int (*)(PC,Vec,Vec)) 0;
94*4b9ad928SBarry Smith   pc->ops->setuponblocks       = (int (*)(PC)) 0;
95*4b9ad928SBarry Smith   pc->modifysubmatrices        = (int (*)(PC,int,const IS[],const IS[],Mat[],void*)) 0;
96*4b9ad928SBarry Smith 
97*4b9ad928SBarry Smith   /* Call the PCCreateXXX routine for this particular preconditioner */
98*4b9ad928SBarry Smith   ierr = (*r)(pc);CHKERRQ(ierr);
99*4b9ad928SBarry Smith 
100*4b9ad928SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)pc,type);CHKERRQ(ierr);
101*4b9ad928SBarry Smith   PetscFunctionReturn(0);
102*4b9ad928SBarry Smith }
103*4b9ad928SBarry Smith 
104*4b9ad928SBarry Smith #undef __FUNCT__
105*4b9ad928SBarry Smith #define __FUNCT__ "PCRegisterDestroy"
106*4b9ad928SBarry Smith /*@C
107*4b9ad928SBarry Smith    PCRegisterDestroy - Frees the list of preconditioners that were
108*4b9ad928SBarry Smith    registered by PCRegisterDynamic().
109*4b9ad928SBarry Smith 
110*4b9ad928SBarry Smith    Not Collective
111*4b9ad928SBarry Smith 
112*4b9ad928SBarry Smith    Level: advanced
113*4b9ad928SBarry Smith 
114*4b9ad928SBarry Smith .keywords: PC, register, destroy
115*4b9ad928SBarry Smith 
116*4b9ad928SBarry Smith .seealso: PCRegisterAll(), PCRegisterAll()
117*4b9ad928SBarry Smith 
118*4b9ad928SBarry Smith @*/
119*4b9ad928SBarry Smith int PCRegisterDestroy(void)
120*4b9ad928SBarry Smith {
121*4b9ad928SBarry Smith   int ierr;
122*4b9ad928SBarry Smith 
123*4b9ad928SBarry Smith   PetscFunctionBegin;
124*4b9ad928SBarry Smith   if (PCList) {
125*4b9ad928SBarry Smith     ierr = PetscFListDestroy(&PCList);CHKERRQ(ierr);
126*4b9ad928SBarry Smith     PCList = 0;
127*4b9ad928SBarry Smith   }
128*4b9ad928SBarry Smith   PCRegisterAllCalled = PETSC_FALSE;
129*4b9ad928SBarry Smith   PetscFunctionReturn(0);
130*4b9ad928SBarry Smith }
131*4b9ad928SBarry Smith 
132*4b9ad928SBarry Smith #undef __FUNCT__
133*4b9ad928SBarry Smith #define __FUNCT__ "PCGetType"
134*4b9ad928SBarry Smith /*@C
135*4b9ad928SBarry Smith    PCGetType - Gets the PC method type and name (as a string) from the PC
136*4b9ad928SBarry Smith    context.
137*4b9ad928SBarry Smith 
138*4b9ad928SBarry Smith    Not Collective
139*4b9ad928SBarry Smith 
140*4b9ad928SBarry Smith    Input Parameter:
141*4b9ad928SBarry Smith .  pc - the preconditioner context
142*4b9ad928SBarry Smith 
143*4b9ad928SBarry Smith    Output Parameter:
144*4b9ad928SBarry Smith .  name - name of preconditioner
145*4b9ad928SBarry Smith 
146*4b9ad928SBarry Smith    Level: intermediate
147*4b9ad928SBarry Smith 
148*4b9ad928SBarry Smith .keywords: PC, get, method, name, type
149*4b9ad928SBarry Smith 
150*4b9ad928SBarry Smith .seealso: PCSetType()
151*4b9ad928SBarry Smith 
152*4b9ad928SBarry Smith @*/
153*4b9ad928SBarry Smith int PCGetType(PC pc,PCType *meth)
154*4b9ad928SBarry Smith {
155*4b9ad928SBarry Smith   PetscFunctionBegin;
156*4b9ad928SBarry Smith   *meth = (PCType) pc->type_name;
157*4b9ad928SBarry Smith   PetscFunctionReturn(0);
158*4b9ad928SBarry Smith }
159*4b9ad928SBarry Smith 
160*4b9ad928SBarry Smith #undef __FUNCT__
161*4b9ad928SBarry Smith #define __FUNCT__ "PCSetFromOptions"
162*4b9ad928SBarry Smith /*@
163*4b9ad928SBarry Smith    PCSetFromOptions - Sets PC options from the options database.
164*4b9ad928SBarry Smith    This routine must be called before PCSetUp() if the user is to be
165*4b9ad928SBarry Smith    allowed to set the preconditioner method.
166*4b9ad928SBarry Smith 
167*4b9ad928SBarry Smith    Collective on PC
168*4b9ad928SBarry Smith 
169*4b9ad928SBarry Smith    Input Parameter:
170*4b9ad928SBarry Smith .  pc - the preconditioner context
171*4b9ad928SBarry Smith 
172*4b9ad928SBarry Smith    Level: developer
173*4b9ad928SBarry Smith 
174*4b9ad928SBarry Smith .keywords: PC, set, from, options, database
175*4b9ad928SBarry Smith 
176*4b9ad928SBarry Smith .seealso:
177*4b9ad928SBarry Smith 
178*4b9ad928SBarry Smith @*/
179*4b9ad928SBarry Smith int PCSetFromOptions(PC pc)
180*4b9ad928SBarry Smith {
181*4b9ad928SBarry Smith   int        ierr;
182*4b9ad928SBarry Smith   char       type[256],*def;
183*4b9ad928SBarry Smith   PetscTruth flg;
184*4b9ad928SBarry Smith 
185*4b9ad928SBarry Smith   PetscFunctionBegin;
186*4b9ad928SBarry Smith   PetscValidHeaderSpecific(pc,PC_COOKIE);
187*4b9ad928SBarry Smith 
188*4b9ad928SBarry Smith   if (!PCRegisterAllCalled) {ierr = PCRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
189*4b9ad928SBarry Smith   ierr = PetscOptionsBegin(pc->comm,pc->prefix,"Preconditioner (PC) Options","PC");CHKERRQ(ierr);
190*4b9ad928SBarry Smith     if (!pc->type_name) {
191*4b9ad928SBarry Smith       PetscTruth ismatshell;
192*4b9ad928SBarry Smith       int        size;
193*4b9ad928SBarry Smith 
194*4b9ad928SBarry Smith       /*
195*4b9ad928SBarry Smith         Shell matrix (probably) cannot support Bjacobi and ILU
196*4b9ad928SBarry Smith       */
197*4b9ad928SBarry Smith       ierr = MPI_Comm_size(pc->comm,&size);CHKERRQ(ierr);
198*4b9ad928SBarry Smith       if (pc->pmat) {
199*4b9ad928SBarry Smith         ierr = PetscTypeCompare((PetscObject)pc->pmat,MATSHELL,&ismatshell);CHKERRQ(ierr);
200*4b9ad928SBarry Smith       } else {
201*4b9ad928SBarry Smith         ismatshell = PETSC_FALSE; /* matrix is not yet set, so guess that it will not be MATSHELL */
202*4b9ad928SBarry Smith       }
203*4b9ad928SBarry Smith       /*
204*4b9ad928SBarry Smith          MATMFFD cannot support BJacobia and ILU
205*4b9ad928SBarry Smith       */
206*4b9ad928SBarry Smith       if (!ismatshell) {
207*4b9ad928SBarry Smith         ierr = PetscTypeCompare((PetscObject)pc->pmat,MATMFFD,&ismatshell);CHKERRQ(ierr);
208*4b9ad928SBarry Smith       }
209*4b9ad928SBarry Smith 
210*4b9ad928SBarry Smith       if (ismatshell) {
211*4b9ad928SBarry Smith         def = PCNONE;
212*4b9ad928SBarry Smith         PetscLogInfo(pc,"PCSetOperators:Setting default PC to PCNONE since MATSHELL doesn't support\n\
213*4b9ad928SBarry Smith     preconditioners (unless defined by the user)\n");
214*4b9ad928SBarry Smith       } else if (size == 1) {
215*4b9ad928SBarry Smith         ierr = PetscTypeCompare((PetscObject)pc->pmat,MATSEQSBAIJ,&flg);CHKERRQ(ierr);
216*4b9ad928SBarry Smith         if (flg) {
217*4b9ad928SBarry Smith           def = PCICC;
218*4b9ad928SBarry Smith         } else {
219*4b9ad928SBarry Smith 	  def = PCILU;
220*4b9ad928SBarry Smith         }
221*4b9ad928SBarry Smith       } else {
222*4b9ad928SBarry Smith         def = PCBJACOBI;
223*4b9ad928SBarry Smith       }
224*4b9ad928SBarry Smith     } else {
225*4b9ad928SBarry Smith       def = pc->type_name;
226*4b9ad928SBarry Smith     }
227*4b9ad928SBarry Smith 
228*4b9ad928SBarry Smith     ierr = PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr);
229*4b9ad928SBarry Smith     if (flg) {
230*4b9ad928SBarry Smith       ierr = PCSetType(pc,type);CHKERRQ(ierr);
231*4b9ad928SBarry Smith     }
232*4b9ad928SBarry Smith 
233*4b9ad928SBarry Smith     ierr = PetscOptionsName("-pc_constant_null_space","Add constant null space to preconditioner","PCNullSpaceAttach",&flg);CHKERRQ(ierr);
234*4b9ad928SBarry Smith     if (flg) {
235*4b9ad928SBarry Smith       MatNullSpace nsp;
236*4b9ad928SBarry Smith 
237*4b9ad928SBarry Smith       ierr = MatNullSpaceCreate(pc->comm,1,0,0,&nsp);CHKERRQ(ierr);
238*4b9ad928SBarry Smith       ierr = PCNullSpaceAttach(pc,nsp);CHKERRQ(ierr);
239*4b9ad928SBarry Smith       ierr = MatNullSpaceDestroy(nsp);CHKERRQ(ierr);
240*4b9ad928SBarry Smith     }
241*4b9ad928SBarry Smith 
242*4b9ad928SBarry Smith 
243*4b9ad928SBarry Smith     /* option is actually checked in PCSetUp() */
244*4b9ad928SBarry Smith     if (pc->nullsp) {
245*4b9ad928SBarry Smith       ierr = PetscOptionsName("-pc_test_null_space","Is provided null space correct","None",&flg);CHKERRQ(ierr);
246*4b9ad928SBarry Smith     }
247*4b9ad928SBarry Smith 
248*4b9ad928SBarry Smith     /*
249*4b9ad928SBarry Smith       Set the type if it was never set.
250*4b9ad928SBarry Smith     */
251*4b9ad928SBarry Smith     if (!pc->type_name) {
252*4b9ad928SBarry Smith       ierr = PCSetType(pc,def);CHKERRQ(ierr);
253*4b9ad928SBarry Smith     }
254*4b9ad928SBarry Smith 
255*4b9ad928SBarry Smith 
256*4b9ad928SBarry Smith 
257*4b9ad928SBarry Smith     if (pc->ops->setfromoptions) {
258*4b9ad928SBarry Smith       ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr);
259*4b9ad928SBarry Smith     }
260*4b9ad928SBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
261*4b9ad928SBarry Smith #if defined(__cplusplus) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && defined(PETSC_HAVE_CXX_NAMESPACE)
262*4b9ad928SBarry Smith   ierr = PCESISetFromOptions(pc);CHKERRQ(ierr);
263*4b9ad928SBarry Smith #endif
264*4b9ad928SBarry Smith   PetscFunctionReturn(0);
265*4b9ad928SBarry Smith }
266