xref: /petsc/src/ksp/pc/interface/pcset.c (revision 0e33f6dd3f48849e1634e838cc80c84f3a650220)
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],*def;
183   PetscTruth flg;
184 
185   PetscFunctionBegin;
186   PetscValidHeaderSpecific(pc,PC_COOKIE);
187 
188   if (!PCRegisterAllCalled) {ierr = PCRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
189   ierr = PetscOptionsBegin(pc->comm,pc->prefix,"Preconditioner (PC) Options","PC");CHKERRQ(ierr);
190     if (!pc->type_name) {
191       PetscTruth ismatshell;
192       int        size;
193 
194       /*
195         Shell matrix (probably) cannot support Bjacobi and ILU
196       */
197       ierr = MPI_Comm_size(pc->comm,&size);CHKERRQ(ierr);
198       if (pc->pmat) {
199         ierr = PetscTypeCompare((PetscObject)pc->pmat,MATSHELL,&ismatshell);CHKERRQ(ierr);
200       } else {
201         ismatshell = PETSC_FALSE; /* matrix is not yet set, so guess that it will not be MATSHELL */
202       }
203       /*
204          MATMFFD cannot support BJacobia and ILU
205       */
206       if (!ismatshell) {
207         ierr = PetscTypeCompare((PetscObject)pc->pmat,MATMFFD,&ismatshell);CHKERRQ(ierr);
208       }
209 
210       if (ismatshell) {
211         def = PCNONE;
212         PetscLogInfo(pc,"PCSetOperators:Setting default PC to PCNONE since MATSHELL doesn't support\n\
213     preconditioners (unless defined by the user)\n");
214       } else if (size == 1) {
215         ierr = PetscTypeCompare((PetscObject)pc->pmat,MATSEQSBAIJ,&flg);CHKERRQ(ierr);
216         if (flg) {
217           def = PCICC;
218         } else {
219 	  def = PCILU;
220         }
221       } else {
222         def = PCBJACOBI;
223       }
224     } else {
225       def = pc->type_name;
226     }
227 
228     ierr = PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr);
229     if (flg) {
230       ierr = PCSetType(pc,type);CHKERRQ(ierr);
231     }
232 
233     ierr = PetscOptionsName("-pc_constant_null_space","Add constant null space to preconditioner","PCNullSpaceAttach",&flg);CHKERRQ(ierr);
234     if (flg) {
235       MatNullSpace nsp;
236 
237       ierr = MatNullSpaceCreate(pc->comm,1,0,0,&nsp);CHKERRQ(ierr);
238       ierr = PCNullSpaceAttach(pc,nsp);CHKERRQ(ierr);
239       ierr = MatNullSpaceDestroy(nsp);CHKERRQ(ierr);
240     }
241 
242 
243     /* option is actually checked in PCSetUp() */
244     if (pc->nullsp) {
245       ierr = PetscOptionsName("-pc_test_null_space","Is provided null space correct","None",&flg);CHKERRQ(ierr);
246     }
247 
248     /*
249       Set the type if it was never set.
250     */
251     if (!pc->type_name) {
252       ierr = PCSetType(pc,def);CHKERRQ(ierr);
253     }
254 
255 
256 
257     if (pc->ops->setfromoptions) {
258       ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr);
259     }
260   ierr = PetscOptionsEnd();CHKERRQ(ierr);
261 #if defined(__cplusplus) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && defined(PETSC_HAVE_CXX_NAMESPACE)
262   ierr = PCESISetFromOptions(pc);CHKERRQ(ierr);
263 #endif
264   PetscFunctionReturn(0);
265 }
266