xref: /petsc/src/ksp/pc/interface/pcset.c (revision cdbf8f939cdfb1c797c4b7f2cbbd00be19935363)
1 
2 /*
3     Routines to set PC methods and options.
4 */
5 
6 #include <private/pcimpl.h>      /*I "petscpc.h" I*/
7 
8 PetscBool  PCRegisterAllCalled = PETSC_FALSE;
9 /*
10    Contains the list of registered KSP routines
11 */
12 PetscFList PCList = 0;
13 
14 #undef __FUNCT__
15 #define __FUNCT__ "PCSetType"
16 /*@C
17    PCSetType - Builds PC for a particular preconditioner.
18 
19    Collective on PC
20 
21    Input Parameter:
22 +  pc - the preconditioner context.
23 -  type - a known method
24 
25    Options Database Key:
26 .  -pc_type <type> - Sets PC type
27 
28    Use -help for a list of available methods (for instance,
29    jacobi or bjacobi)
30 
31   Notes:
32   See "petsc/include/petscpc.h" for available methods (for instance,
33   PCJACOBI, PCILU, or PCBJACOBI).
34 
35   Normally, it is best to use the KSPSetFromOptions() command and
36   then set the PC type from the options database rather than by using
37   this routine.  Using the options database provides the user with
38   maximum flexibility in evaluating the many different preconditioners.
39   The PCSetType() routine is provided for those situations where it
40   is necessary to set the preconditioner independently of the command
41   line or options database.  This might be the case, for example, when
42   the choice of preconditioner changes during the execution of the
43   program, and the user's application is taking responsibility for
44   choosing the appropriate preconditioner.  In other words, this
45   routine is not for beginners.
46 
47   Level: intermediate
48 
49 .keywords: PC, set, method, type
50 
51 .seealso: KSPSetType(), PCType
52 
53 @*/
54 PetscErrorCode  PCSetType(PC pc,const PCType type)
55 {
56   PetscErrorCode ierr,(*r)(PC);
57   PetscBool      match;
58 
59   PetscFunctionBegin;
60   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
61   PetscValidCharPointer(type,2);
62 
63   ierr = PetscTypeCompare((PetscObject)pc,type,&match);CHKERRQ(ierr);
64   if (match) PetscFunctionReturn(0);
65 
66   ierr =  PetscFListFind(PCList,((PetscObject)pc)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
67   if (!r) SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PC type %s",type);
68   /* Destroy the previous private PC context */
69   if (pc->ops->destroy) { ierr =  (*pc->ops->destroy)(pc);CHKERRQ(ierr); pc->data = 0;}
70   ierr = PetscFListDestroy(&((PetscObject)pc)->qlist);CHKERRQ(ierr);
71   /* Reinitialize function pointers in PCOps structure */
72   ierr = PetscMemzero(pc->ops,sizeof(struct _PCOps));CHKERRQ(ierr);
73   /* XXX Is this OK?? */
74   pc->modifysubmatrices        = 0;
75   pc->modifysubmatricesP       = 0;
76   /* Call the PCCreate_XXX routine for this particular preconditioner */
77   pc->setupcalled = 0;
78   ierr = PetscObjectChangeTypeName((PetscObject)pc,type);CHKERRQ(ierr);
79   ierr = (*r)(pc);CHKERRQ(ierr);
80 #if defined(PETSC_HAVE_AMS)
81   if (PetscAMSPublishAll) {
82     ierr = PetscObjectAMSPublish((PetscObject)pc);CHKERRQ(ierr);
83   }
84 #endif
85   PetscFunctionReturn(0);
86 }
87 
88 #undef __FUNCT__
89 #define __FUNCT__ "PCRegisterDestroy"
90 /*@
91    PCRegisterDestroy - Frees the list of preconditioners that were
92    registered by PCRegisterDynamic().
93 
94    Not Collective
95 
96    Level: advanced
97 
98 .keywords: PC, register, destroy
99 
100 .seealso: PCRegisterAll(), PCRegisterAll()
101 
102 @*/
103 PetscErrorCode  PCRegisterDestroy(void)
104 {
105   PetscErrorCode ierr;
106 
107   PetscFunctionBegin;
108   ierr = PetscFListDestroy(&PCList);CHKERRQ(ierr);
109   PCRegisterAllCalled = PETSC_FALSE;
110   PetscFunctionReturn(0);
111 }
112 
113 #undef __FUNCT__
114 #define __FUNCT__ "PCGetType"
115 /*@C
116    PCGetType - Gets the PC method type and name (as a string) from the PC
117    context.
118 
119    Not Collective
120 
121    Input Parameter:
122 .  pc - the preconditioner context
123 
124    Output Parameter:
125 .  type - name of preconditioner method
126 
127    Level: intermediate
128 
129 .keywords: PC, get, method, name, type
130 
131 .seealso: PCSetType()
132 
133 @*/
134 PetscErrorCode  PCGetType(PC pc,const PCType *type)
135 {
136   PetscFunctionBegin;
137   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
138   PetscValidPointer(type,2);
139   *type = ((PetscObject)pc)->type_name;
140   PetscFunctionReturn(0);
141 }
142 
143 extern PetscErrorCode PCGetDefaultType_Private(PC,const char*[]);
144 
145 #undef __FUNCT__
146 #define __FUNCT__ "PCSetFromOptions"
147 /*@
148    PCSetFromOptions - Sets PC options from the options database.
149    This routine must be called before PCSetUp() if the user is to be
150    allowed to set the preconditioner method.
151 
152    Collective on PC
153 
154    Input Parameter:
155 .  pc - the preconditioner context
156 
157    Level: developer
158 
159 .keywords: PC, set, from, options, database
160 
161 .seealso:
162 
163 @*/
164 PetscErrorCode  PCSetFromOptions(PC pc)
165 {
166   PetscErrorCode ierr;
167   char           type[256];
168   const char     *def;
169   PetscBool      flg;
170 
171   PetscFunctionBegin;
172   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
173 
174   if (!PCRegisterAllCalled) {ierr = PCRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
175 ierr = PetscObjectOptionsBegin((PetscObject)pc);CHKERRQ(ierr);
176   if (!((PetscObject)pc)->type_name) {
177     ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr);
178   } else {
179     def = ((PetscObject)pc)->type_name;
180   }
181 
182   ierr = PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr);
183   if (flg) {
184     ierr = PCSetType(pc,type);CHKERRQ(ierr);
185   } else if (!((PetscObject)pc)->type_name){
186     ierr = PCSetType(pc,def);CHKERRQ(ierr);
187   }
188 
189   ierr = PetscOptionsGetInt(((PetscObject)pc)->prefix,"-pc_reuse",&pc->reuse,PETSC_NULL);CHKERRQ(ierr);
190 
191   if (pc->ops->setfromoptions) {
192     ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr);
193   }
194 
195   /* process any options handlers added with PetscObjectAddOptionsHandler() */
196   ierr = PetscObjectProcessOptionsHandlers((PetscObject)pc);CHKERRQ(ierr);
197   ierr = PetscOptionsEnd();CHKERRQ(ierr);
198   pc->setfromoptionscalled++;
199   PetscFunctionReturn(0);
200 }
201 
202 #undef __FUNCT__
203 #define __FUNCT__ "PCSetDM"
204 /*@
205    PCSetDM - Sets the DM that may be used by some preconditioners
206 
207    Logically Collective on PC
208 
209    Input Parameters:
210 +  pc - the preconditioner context
211 -  dm - the dm
212 
213    Level: intermediate
214 
215 
216 .seealso: PCGetDM(), KSPSetDM(), KSPGetDM()
217 @*/
218 PetscErrorCode  PCSetDM(PC pc,DM dm)
219 {
220   PetscErrorCode ierr;
221 
222   PetscFunctionBegin;
223   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
224   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
225   ierr = DMDestroy(&pc->dm);CHKERRQ(ierr);
226   pc->dm = dm;
227   PetscFunctionReturn(0);
228 }
229 
230 #undef __FUNCT__
231 #define __FUNCT__ "PCGetDM"
232 /*@
233    PCGetDM - Gets the DM that may be used by some preconditioners
234 
235    Not Collective
236 
237    Input Parameter:
238 . pc - the preconditioner context
239 
240    Output Parameter:
241 .  dm - the dm
242 
243    Level: intermediate
244 
245 
246 .seealso: PCSetDM(), KSPSetDM(), KSPGetDM()
247 @*/
248 PetscErrorCode  PCGetDM(PC pc,DM *dm)
249 {
250   PetscFunctionBegin;
251   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
252   *dm = pc->dm;
253   PetscFunctionReturn(0);
254 }
255 
256 #undef __FUNCT__
257 #define __FUNCT__ "PCSetApplicationContext"
258 /*@
259    PCSetApplicationContext - Sets the optional user-defined context for the linear solver.
260 
261    Logically Collective on PC
262 
263    Input Parameters:
264 +  pc - the PC context
265 -  usrP - optional user context
266 
267    Level: intermediate
268 
269 .keywords: PC, set, application, context
270 
271 .seealso: PCGetApplicationContext()
272 @*/
273 PetscErrorCode  PCSetApplicationContext(PC pc,void *usrP)
274 {
275   PetscFunctionBegin;
276   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
277   pc->user = usrP;
278   PetscFunctionReturn(0);
279 }
280 
281 #undef __FUNCT__
282 #define __FUNCT__ "PCGetApplicationContext"
283 /*@
284    PCGetApplicationContext - Gets the user-defined context for the linear solver.
285 
286    Not Collective
287 
288    Input Parameter:
289 .  pc - PC context
290 
291    Output Parameter:
292 .  usrP - user context
293 
294    Level: intermediate
295 
296 .keywords: PC, get, application, context
297 
298 .seealso: PCSetApplicationContext()
299 @*/
300 PetscErrorCode  PCGetApplicationContext(PC pc,void *usrP)
301 {
302   PetscFunctionBegin;
303   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
304   *(void**)usrP = pc->user;
305   PetscFunctionReturn(0);
306 }
307 
308