xref: /petsc/src/ksp/pc/interface/pcset.c (revision 3923b477fd0dced8a2d147b4fb4519fe3af97d3f)
1 
2 /*
3     Routines to set PC methods and options.
4 */
5 
6 #include <petsc-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,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 = PetscObjectTypeCompare((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) {
70     ierr =  (*pc->ops->destroy)(pc);CHKERRQ(ierr);
71     pc->ops->destroy = PETSC_NULL;
72     pc->data = 0;
73   }
74   ierr = PetscFListDestroy(&((PetscObject)pc)->qlist);CHKERRQ(ierr);
75   /* Reinitialize function pointers in PCOps structure */
76   ierr = PetscMemzero(pc->ops,sizeof(struct _PCOps));CHKERRQ(ierr);
77   /* XXX Is this OK?? */
78   pc->modifysubmatrices        = 0;
79   pc->modifysubmatricesP       = 0;
80   /* Call the PCCreate_XXX routine for this particular preconditioner */
81   pc->setupcalled = 0;
82   ierr = PetscObjectChangeTypeName((PetscObject)pc,type);CHKERRQ(ierr);
83   ierr = (*r)(pc);CHKERRQ(ierr);
84 #if defined(PETSC_HAVE_AMS)
85   if (PetscAMSPublishAll) {
86     ierr = PetscObjectAMSPublish((PetscObject)pc);CHKERRQ(ierr);
87   }
88 #endif
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 = PetscFListDestroy(&PCList);CHKERRQ(ierr);
113   PCRegisterAllCalled = PETSC_FALSE;
114   PetscFunctionReturn(0);
115 }
116 
117 #undef __FUNCT__
118 #define __FUNCT__ "PCGetType"
119 /*@C
120    PCGetType - Gets the PC method type and name (as a string) from the PC
121    context.
122 
123    Not Collective
124 
125    Input Parameter:
126 .  pc - the preconditioner context
127 
128    Output Parameter:
129 .  type - name of preconditioner method
130 
131    Level: intermediate
132 
133 .keywords: PC, get, method, name, type
134 
135 .seealso: PCSetType()
136 
137 @*/
138 PetscErrorCode  PCGetType(PC pc,PCType *type)
139 {
140   PetscFunctionBegin;
141   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
142   PetscValidPointer(type,2);
143   *type = ((PetscObject)pc)->type_name;
144   PetscFunctionReturn(0);
145 }
146 
147 extern PetscErrorCode PCGetDefaultType_Private(PC,const char*[]);
148 
149 #undef __FUNCT__
150 #define __FUNCT__ "PCSetFromOptions"
151 /*@
152    PCSetFromOptions - Sets PC options from the options database.
153    This routine must be called before PCSetUp() if the user is to be
154    allowed to set the preconditioner method.
155 
156    Collective on PC
157 
158    Input Parameter:
159 .  pc - the preconditioner context
160 
161    Level: developer
162 
163 .keywords: PC, set, from, options, database
164 
165 .seealso:
166 
167 @*/
168 PetscErrorCode  PCSetFromOptions(PC pc)
169 {
170   PetscErrorCode ierr;
171   char           type[256];
172   const char     *def;
173   PetscBool      flg;
174 
175   PetscFunctionBegin;
176   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
177 
178   if (!PCRegisterAllCalled) {ierr = PCRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
179   ierr = PetscObjectOptionsBegin((PetscObject)pc);CHKERRQ(ierr);
180   if (!((PetscObject)pc)->type_name) {
181     ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr);
182   } else {
183     def = ((PetscObject)pc)->type_name;
184   }
185 
186   ierr = PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr);
187   if (flg) {
188     ierr = PCSetType(pc,type);CHKERRQ(ierr);
189   } else if (!((PetscObject)pc)->type_name){
190     ierr = PCSetType(pc,def);CHKERRQ(ierr);
191   }
192 
193   ierr = PetscOptionsGetInt(((PetscObject)pc)->prefix,"-pc_reuse",&pc->reuse,PETSC_NULL);CHKERRQ(ierr);
194 
195   if (pc->ops->setfromoptions) {
196     ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr);
197   }
198 
199   /* process any options handlers added with PetscObjectAddOptionsHandler() */
200   ierr = PetscObjectProcessOptionsHandlers((PetscObject)pc);CHKERRQ(ierr);
201   ierr = PetscOptionsEnd();CHKERRQ(ierr);
202   pc->setfromoptionscalled++;
203   PetscFunctionReturn(0);
204 }
205 
206 #undef __FUNCT__
207 #define __FUNCT__ "PCSetDM"
208 /*@
209    PCSetDM - Sets the DM that may be used by some preconditioners
210 
211    Logically Collective on PC
212 
213    Input Parameters:
214 +  pc - the preconditioner context
215 -  dm - the dm
216 
217    Level: intermediate
218 
219 
220 .seealso: PCGetDM(), KSPSetDM(), KSPGetDM()
221 @*/
222 PetscErrorCode  PCSetDM(PC pc,DM dm)
223 {
224   PetscErrorCode ierr;
225 
226   PetscFunctionBegin;
227   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
228   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
229   ierr = DMDestroy(&pc->dm);CHKERRQ(ierr);
230   pc->dm = dm;
231   PetscFunctionReturn(0);
232 }
233 
234 #undef __FUNCT__
235 #define __FUNCT__ "PCGetDM"
236 /*@
237    PCGetDM - Gets the DM that may be used by some preconditioners
238 
239    Not Collective
240 
241    Input Parameter:
242 . pc - the preconditioner context
243 
244    Output Parameter:
245 .  dm - the dm
246 
247    Level: intermediate
248 
249 
250 .seealso: PCSetDM(), KSPSetDM(), KSPGetDM()
251 @*/
252 PetscErrorCode  PCGetDM(PC pc,DM *dm)
253 {
254   PetscFunctionBegin;
255   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
256   *dm = pc->dm;
257   PetscFunctionReturn(0);
258 }
259 
260 #undef __FUNCT__
261 #define __FUNCT__ "PCSetApplicationContext"
262 /*@
263    PCSetApplicationContext - Sets the optional user-defined context for the linear solver.
264 
265    Logically Collective on PC
266 
267    Input Parameters:
268 +  pc - the PC context
269 -  usrP - optional user context
270 
271    Level: intermediate
272 
273 .keywords: PC, set, application, context
274 
275 .seealso: PCGetApplicationContext()
276 @*/
277 PetscErrorCode  PCSetApplicationContext(PC pc,void *usrP)
278 {
279   PetscFunctionBegin;
280   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
281   pc->user = usrP;
282   PetscFunctionReturn(0);
283 }
284 
285 #undef __FUNCT__
286 #define __FUNCT__ "PCGetApplicationContext"
287 /*@
288    PCGetApplicationContext - Gets the user-defined context for the linear solver.
289 
290    Not Collective
291 
292    Input Parameter:
293 .  pc - PC context
294 
295    Output Parameter:
296 .  usrP - user context
297 
298    Level: intermediate
299 
300 .keywords: PC, get, application, context
301 
302 .seealso: PCSetApplicationContext()
303 @*/
304 PetscErrorCode  PCGetApplicationContext(PC pc,void *usrP)
305 {
306   PetscFunctionBegin;
307   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
308   *(void**)usrP = pc->user;
309   PetscFunctionReturn(0);
310 }
311 
312