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