xref: /petsc/src/ksp/pc/interface/pcset.c (revision 8a1af44da4882b8d0246f6cd95069f95e8fe7aba)
1 
2 /*
3     Routines to set PC methods and options.
4 */
5 
6 #include <petsc-private/pcimpl.h>      /*I "petscpc.h" I*/
7 #include <petscdm.h>
8 
9 PetscBool PCRegisterAllCalled = PETSC_FALSE;
10 /*
11    Contains the list of registered KSP routines
12 */
13 PetscFunctionList 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 PetscErrorCode  PCSetType(PC pc,PCType type)
56 {
57   PetscErrorCode ierr,(*r)(PC);
58   PetscBool      match;
59 
60   PetscFunctionBegin;
61   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
62   PetscValidCharPointer(type,2);
63 
64   ierr = PetscObjectTypeCompare((PetscObject)pc,type,&match);CHKERRQ(ierr);
65   if (match) PetscFunctionReturn(0);
66 
67   ierr =  PetscFunctionListFind(PCList,type,(void (**)(void)) &r);CHKERRQ(ierr);
68   if (!r) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PC type %s",type);
69   /* Destroy the previous private PC context */
70   if (pc->ops->destroy) {
71     ierr             =  (*pc->ops->destroy)(pc);CHKERRQ(ierr);
72     pc->ops->destroy = NULL;
73     pc->data         = 0;
74   }
75   ierr = PetscFunctionListDestroy(&((PetscObject)pc)->qlist);CHKERRQ(ierr);
76   /* Reinitialize function pointers in PCOps structure */
77   ierr = PetscMemzero(pc->ops,sizeof(struct _PCOps));CHKERRQ(ierr);
78   /* XXX Is this OK?? */
79   pc->modifysubmatrices  = 0;
80   pc->modifysubmatricesP = 0;
81   /* Call the PCCreate_XXX routine for this particular preconditioner */
82   pc->setupcalled = 0;
83 
84   ierr = PetscObjectChangeTypeName((PetscObject)pc,type);CHKERRQ(ierr);
85   ierr = (*r)(pc);CHKERRQ(ierr);
86   PetscFunctionReturn(0);
87 }
88 
89 #undef __FUNCT__
90 #define __FUNCT__ "PCRegisterDestroy"
91 /*@
92    PCRegisterDestroy - Frees the list of preconditioners that were
93    registered by PCRegister().
94 
95    Not Collective
96 
97    Level: advanced
98 
99 .keywords: PC, register, destroy
100 
101 .seealso: PCRegisterAll(), PCRegisterAll()
102 
103 @*/
104 PetscErrorCode  PCRegisterDestroy(void)
105 {
106   PetscErrorCode ierr;
107 
108   PetscFunctionBegin;
109   ierr = PetscFunctionListDestroy(&PCList);CHKERRQ(ierr);
110 
111   PCRegisterAllCalled = PETSC_FALSE;
112   PetscFunctionReturn(0);
113 }
114 
115 #undef __FUNCT__
116 #define __FUNCT__ "PCGetType"
117 /*@C
118    PCGetType - Gets the PC method type and name (as a string) from the PC
119    context.
120 
121    Not Collective
122 
123    Input Parameter:
124 .  pc - the preconditioner context
125 
126    Output Parameter:
127 .  type - name of preconditioner method
128 
129    Level: intermediate
130 
131 .keywords: PC, get, method, name, type
132 
133 .seealso: PCSetType()
134 
135 @*/
136 PetscErrorCode  PCGetType(PC pc,PCType *type)
137 {
138   PetscFunctionBegin;
139   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
140   PetscValidPointer(type,2);
141   *type = ((PetscObject)pc)->type_name;
142   PetscFunctionReturn(0);
143 }
144 
145 extern PetscErrorCode PCGetDefaultType_Private(PC,const char*[]);
146 
147 #undef __FUNCT__
148 #define __FUNCT__ "PCSetFromOptions"
149 /*@
150    PCSetFromOptions - Sets PC options from the options database.
151    This routine must be called before PCSetUp() if the user is to be
152    allowed to set the preconditioner method.
153 
154    Collective on PC
155 
156    Input Parameter:
157 .  pc - the preconditioner context
158 
159    Options Database:
160 .   -pc_use_amat true,false see PCSetUseAmat()
161 
162    Level: developer
163 
164 .keywords: PC, set, from, options, database
165 
166 .seealso: PCSetUseAmat()
167 
168 @*/
169 PetscErrorCode  PCSetFromOptions(PC pc)
170 {
171   PetscErrorCode ierr;
172   char           type[256];
173   const char     *def;
174   PetscBool      flg;
175 
176   PetscFunctionBegin;
177   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
178 
179   if (!PCRegisterAllCalled) {ierr = PCRegisterAll();CHKERRQ(ierr);}
180   ierr = PetscObjectOptionsBegin((PetscObject)pc);CHKERRQ(ierr);
181   if (!((PetscObject)pc)->type_name) {
182     ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr);
183   } else {
184     def = ((PetscObject)pc)->type_name;
185   }
186 
187   ierr = PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr);
188   if (flg) {
189     ierr = PCSetType(pc,type);CHKERRQ(ierr);
190   } else if (!((PetscObject)pc)->type_name) {
191     ierr = PCSetType(pc,def);CHKERRQ(ierr);
192   }
193 
194   ierr = PetscOptionsBool("-pc_use_amat","use Amat (instead of Pmat) to define preconditioner in nested inner solves","PCSetUseAmat",pc->useAmat,&pc->useAmat,NULL);CHKERRQ(ierr);
195 
196   if (pc->ops->setfromoptions) {
197     ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr);
198   }
199 
200   /* process any options handlers added with PetscObjectAddOptionsHandler() */
201   ierr = PetscObjectProcessOptionsHandlers((PetscObject)pc);CHKERRQ(ierr);
202   ierr = PetscOptionsEnd();CHKERRQ(ierr);
203   pc->setfromoptionscalled++;
204   PetscFunctionReturn(0);
205 }
206 
207 #undef __FUNCT__
208 #define __FUNCT__ "PCSetDM"
209 /*@
210    PCSetDM - Sets the DM that may be used by some preconditioners
211 
212    Logically Collective on PC
213 
214    Input Parameters:
215 +  pc - the preconditioner context
216 -  dm - the dm
217 
218    Level: intermediate
219 
220 
221 .seealso: PCGetDM(), KSPSetDM(), KSPGetDM()
222 @*/
223 PetscErrorCode  PCSetDM(PC pc,DM dm)
224 {
225   PetscErrorCode ierr;
226 
227   PetscFunctionBegin;
228   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
229   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
230   ierr   = DMDestroy(&pc->dm);CHKERRQ(ierr);
231   pc->dm = dm;
232   PetscFunctionReturn(0);
233 }
234 
235 #undef __FUNCT__
236 #define __FUNCT__ "PCGetDM"
237 /*@
238    PCGetDM - Gets the DM that may be used by some preconditioners
239 
240    Not Collective
241 
242    Input Parameter:
243 . pc - the preconditioner context
244 
245    Output Parameter:
246 .  dm - the dm
247 
248    Level: intermediate
249 
250 
251 .seealso: PCSetDM(), KSPSetDM(), KSPGetDM()
252 @*/
253 PetscErrorCode  PCGetDM(PC pc,DM *dm)
254 {
255   PetscFunctionBegin;
256   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
257   *dm = pc->dm;
258   PetscFunctionReturn(0);
259 }
260 
261 #undef __FUNCT__
262 #define __FUNCT__ "PCSetApplicationContext"
263 /*@
264    PCSetApplicationContext - Sets the optional user-defined context for the linear solver.
265 
266    Logically Collective on PC
267 
268    Input Parameters:
269 +  pc - the PC context
270 -  usrP - optional user context
271 
272    Level: intermediate
273 
274 .keywords: PC, set, application, context
275 
276 .seealso: PCGetApplicationContext()
277 @*/
278 PetscErrorCode  PCSetApplicationContext(PC pc,void *usrP)
279 {
280   PetscFunctionBegin;
281   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
282   pc->user = usrP;
283   PetscFunctionReturn(0);
284 }
285 
286 #undef __FUNCT__
287 #define __FUNCT__ "PCGetApplicationContext"
288 /*@
289    PCGetApplicationContext - Gets the user-defined context for the linear solver.
290 
291    Not Collective
292 
293    Input Parameter:
294 .  pc - PC context
295 
296    Output Parameter:
297 .  usrP - user context
298 
299    Level: intermediate
300 
301 .keywords: PC, get, application, context
302 
303 .seealso: PCSetApplicationContext()
304 @*/
305 PetscErrorCode  PCGetApplicationContext(PC pc,void *usrP)
306 {
307   PetscFunctionBegin;
308   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
309   *(void**)usrP = pc->user;
310   PetscFunctionReturn(0);
311 }
312 
313