xref: /petsc/src/ksp/pc/interface/pcset.c (revision ec7429eab6e231810adac0f010b269bd5bae4496)
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(PetscObjectComm((PetscObject)pc),PCList,type,PETSC_TRUE,(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   if (PetscAMSPublishAll) {
87     ierr = PetscObjectAMSPublish((PetscObject)pc);CHKERRQ(ierr);
88   }
89   PetscFunctionReturn(0);
90 }
91 
92 #undef __FUNCT__
93 #define __FUNCT__ "PCRegisterDestroy"
94 /*@
95    PCRegisterDestroy - Frees the list of preconditioners that were
96    registered by PCRegisterDynamic().
97 
98    Not Collective
99 
100    Level: advanced
101 
102 .keywords: PC, register, destroy
103 
104 .seealso: PCRegisterAll(), PCRegisterAll()
105 
106 @*/
107 PetscErrorCode  PCRegisterDestroy(void)
108 {
109   PetscErrorCode ierr;
110 
111   PetscFunctionBegin;
112   ierr = PetscFunctionListDestroy(&PCList);CHKERRQ(ierr);
113 
114   PCRegisterAllCalled = PETSC_FALSE;
115   PetscFunctionReturn(0);
116 }
117 
118 #undef __FUNCT__
119 #define __FUNCT__ "PCGetType"
120 /*@C
121    PCGetType - Gets the PC method type and name (as a string) from the PC
122    context.
123 
124    Not Collective
125 
126    Input Parameter:
127 .  pc - the preconditioner context
128 
129    Output Parameter:
130 .  type - name of preconditioner method
131 
132    Level: intermediate
133 
134 .keywords: PC, get, method, name, type
135 
136 .seealso: PCSetType()
137 
138 @*/
139 PetscErrorCode  PCGetType(PC pc,PCType *type)
140 {
141   PetscFunctionBegin;
142   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
143   PetscValidPointer(type,2);
144   *type = ((PetscObject)pc)->type_name;
145   PetscFunctionReturn(0);
146 }
147 
148 extern PetscErrorCode PCGetDefaultType_Private(PC,const char*[]);
149 
150 #undef __FUNCT__
151 #define __FUNCT__ "PCSetFromOptions"
152 /*@
153    PCSetFromOptions - Sets PC options from the options database.
154    This routine must be called before PCSetUp() if the user is to be
155    allowed to set the preconditioner method.
156 
157    Collective on PC
158 
159    Input Parameter:
160 .  pc - the preconditioner context
161 
162    Level: developer
163 
164 .keywords: PC, set, from, options, database
165 
166 .seealso:
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(NULL);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 = PetscOptionsGetInt(((PetscObject)pc)->prefix,"-pc_reuse",&pc->reuse,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