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