xref: /petsc/src/ksp/pc/interface/pcset.c (revision 365a8a9ed7995f723d0d1fa67cbec4692bf1ff54)
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   PetscFunctionReturn(0);
87 }
88 
89 #undef __FUNCT__
90 #define __FUNCT__ "PCRegisterDestroy"
91 /*@
92    PCRegisterDestroy - Frees the list of preconditioners that were
93    registered by PCRegisterDynamic().
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(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   ierr = PetscOptionsGetBool(((PetscObject)pc)->prefix,"-pc_use_amat",&pc->useAmat,NULL);CHKERRQ(ierr);
196 
197   if (pc->ops->setfromoptions) {
198     ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr);
199   }
200 
201   /* process any options handlers added with PetscObjectAddOptionsHandler() */
202   ierr = PetscObjectProcessOptionsHandlers((PetscObject)pc);CHKERRQ(ierr);
203   ierr = PetscOptionsEnd();CHKERRQ(ierr);
204   pc->setfromoptionscalled++;
205   PetscFunctionReturn(0);
206 }
207 
208 #undef __FUNCT__
209 #define __FUNCT__ "PCSetDM"
210 /*@
211    PCSetDM - Sets the DM that may be used by some preconditioners
212 
213    Logically Collective on PC
214 
215    Input Parameters:
216 +  pc - the preconditioner context
217 -  dm - the dm
218 
219    Level: intermediate
220 
221 
222 .seealso: PCGetDM(), KSPSetDM(), KSPGetDM()
223 @*/
224 PetscErrorCode  PCSetDM(PC pc,DM dm)
225 {
226   PetscErrorCode ierr;
227 
228   PetscFunctionBegin;
229   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
230   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
231   ierr   = DMDestroy(&pc->dm);CHKERRQ(ierr);
232   pc->dm = dm;
233   PetscFunctionReturn(0);
234 }
235 
236 #undef __FUNCT__
237 #define __FUNCT__ "PCGetDM"
238 /*@
239    PCGetDM - Gets the DM that may be used by some preconditioners
240 
241    Not Collective
242 
243    Input Parameter:
244 . pc - the preconditioner context
245 
246    Output Parameter:
247 .  dm - the dm
248 
249    Level: intermediate
250 
251 
252 .seealso: PCSetDM(), KSPSetDM(), KSPGetDM()
253 @*/
254 PetscErrorCode  PCGetDM(PC pc,DM *dm)
255 {
256   PetscFunctionBegin;
257   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
258   *dm = pc->dm;
259   PetscFunctionReturn(0);
260 }
261 
262 #undef __FUNCT__
263 #define __FUNCT__ "PCSetApplicationContext"
264 /*@
265    PCSetApplicationContext - Sets the optional user-defined context for the linear solver.
266 
267    Logically Collective on PC
268 
269    Input Parameters:
270 +  pc - the PC context
271 -  usrP - optional user context
272 
273    Level: intermediate
274 
275 .keywords: PC, set, application, context
276 
277 .seealso: PCGetApplicationContext()
278 @*/
279 PetscErrorCode  PCSetApplicationContext(PC pc,void *usrP)
280 {
281   PetscFunctionBegin;
282   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
283   pc->user = usrP;
284   PetscFunctionReturn(0);
285 }
286 
287 #undef __FUNCT__
288 #define __FUNCT__ "PCGetApplicationContext"
289 /*@
290    PCGetApplicationContext - Gets the user-defined context for the linear solver.
291 
292    Not Collective
293 
294    Input Parameter:
295 .  pc - PC context
296 
297    Output Parameter:
298 .  usrP - user context
299 
300    Level: intermediate
301 
302 .keywords: PC, get, application, context
303 
304 .seealso: PCSetApplicationContext()
305 @*/
306 PetscErrorCode  PCGetApplicationContext(PC pc,void *usrP)
307 {
308   PetscFunctionBegin;
309   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
310   *(void**)usrP = pc->user;
311   PetscFunctionReturn(0);
312 }
313 
314