xref: /petsc/src/ksp/pc/interface/pcset.c (revision bcd3bd92eda2d5998e2f14c4bbfb33bd936bdc3e)
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 PC routines
12 */
13 PetscFunctionList PCList = NULL;
14 
15 /*@C
16   PCSetType - Builds PC for a particular preconditioner type
17 
18   Collective
19 
20   Input Parameters:
21 + pc   - the preconditioner context.
22 - type - a known method
23 
24   Options Database Key:
25 . -pc_type <type> - Sets PC type
26 
27    Use -help for a list of available methods (for instance,
28    jacobi or bjacobi)
29 
30   Notes:
31   See "petsc/include/petscpc.h" for available methods (for instance,
32   PCJACOBI, PCILU, or PCBJACOBI).
33 
34   Normally, it is best to use the KSPSetFromOptions() command and
35   then set the PC type from the options database rather than by using
36   this routine.  Using the options database provides the user with
37   maximum flexibility in evaluating the many different preconditioners.
38   The PCSetType() routine is provided for those situations where it
39   is necessary to set the preconditioner independently of the command
40   line or options database.  This might be the case, for example, when
41   the choice of preconditioner changes during the execution of the
42   program, and the user's application is taking responsibility for
43   choosing the appropriate preconditioner.  In other words, this
44   routine is not for beginners.
45 
46   Level: intermediate
47 
48   Developer Notes: PCRegister() is used to add preconditioner types to PCList from which they
49   are accessed by PCSetType().
50 
51 .seealso: `KSPSetType()`, `PCType`, `PCRegister()`, `PCCreate()`, `KSPGetPC()`
52 
53 @*/
54 PetscErrorCode PCSetType(PC pc, PCType type)
55 {
56   PetscBool match;
57   PetscErrorCode (*r)(PC);
58 
59   PetscFunctionBegin;
60   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
61   PetscAssertPointer(type, 2);
62 
63   PetscCall(PetscObjectTypeCompare((PetscObject)pc, type, &match));
64   if (match) PetscFunctionReturn(PETSC_SUCCESS);
65 
66   PetscCall(PetscFunctionListFind(PCList, type, &r));
67   PetscCheck(r, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested PC type %s", type);
68   /* Destroy the previous private PC context */
69   PetscTryTypeMethod(pc, destroy);
70   pc->ops->destroy = NULL;
71   pc->data         = NULL;
72 
73   PetscCall(PetscFunctionListDestroy(&((PetscObject)pc)->qlist));
74   /* Reinitialize function pointers in PCOps structure */
75   PetscCall(PetscMemzero(pc->ops, sizeof(struct _PCOps)));
76   /* XXX Is this OK?? */
77   pc->modifysubmatrices  = NULL;
78   pc->modifysubmatricesP = NULL;
79   /* Call the PCCreate_XXX routine for this particular preconditioner */
80   pc->setupcalled = 0;
81 
82   PetscCall(PetscObjectChangeTypeName((PetscObject)pc, type));
83   PetscCall((*r)(pc));
84   PetscFunctionReturn(PETSC_SUCCESS);
85 }
86 
87 /*@C
88   PCGetType - Gets the PC method type and name (as a string) from the PC
89   context.
90 
91   Not Collective
92 
93   Input Parameter:
94 . pc - the preconditioner context
95 
96   Output Parameter:
97 . type - name of preconditioner method
98 
99   Level: intermediate
100 
101 .seealso: `PCSetType()`
102 
103 @*/
104 PetscErrorCode PCGetType(PC pc, PCType *type)
105 {
106   PetscFunctionBegin;
107   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
108   PetscAssertPointer(type, 2);
109   *type = ((PetscObject)pc)->type_name;
110   PetscFunctionReturn(PETSC_SUCCESS);
111 }
112 
113 extern PetscErrorCode PCGetDefaultType_Private(PC, const char *[]);
114 
115 /*@
116   PCSetFromOptions - Sets PC options from the options database.
117   This routine must be called before PCSetUp() if the user is to be
118   allowed to set the preconditioner method.
119 
120   Collective
121 
122   Input Parameter:
123 . pc - the preconditioner context
124 
125   Options Database Key:
126 . -pc_use_amat true,false - see PCSetUseAmat()
127 
128   Level: developer
129 
130 .seealso: `PCSetUseAmat()`
131 
132 @*/
133 PetscErrorCode PCSetFromOptions(PC pc)
134 {
135   char        type[256];
136   const char *def;
137   PetscBool   flg;
138 
139   PetscFunctionBegin;
140   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
141 
142   PetscCall(PCRegisterAll());
143   PetscObjectOptionsBegin((PetscObject)pc);
144   if (!((PetscObject)pc)->type_name) {
145     PetscCall(PCGetDefaultType_Private(pc, &def));
146   } else {
147     def = ((PetscObject)pc)->type_name;
148   }
149 
150   PetscCall(PetscOptionsFList("-pc_type", "Preconditioner", "PCSetType", PCList, def, type, 256, &flg));
151   if (flg) {
152     PetscCall(PCSetType(pc, type));
153   } else if (!((PetscObject)pc)->type_name) {
154     PetscCall(PCSetType(pc, def));
155   }
156 
157   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &flg));
158   if (flg) goto skipoptions;
159 
160   PetscCall(PetscOptionsBool("-pc_use_amat", "use Amat (instead of Pmat) to define preconditioner in nested inner solves", "PCSetUseAmat", pc->useAmat, &pc->useAmat, NULL));
161 
162   PetscTryTypeMethod(pc, setfromoptions, PetscOptionsObject);
163 
164 skipoptions:
165   /* process any options handlers added with PetscObjectAddOptionsHandler() */
166   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)pc, PetscOptionsObject));
167   PetscOptionsEnd();
168   pc->setfromoptionscalled++;
169   PetscFunctionReturn(PETSC_SUCCESS);
170 }
171 
172 /*@
173   PCSetDM - Sets the DM that may be used by some preconditioners
174 
175   Logically Collective
176 
177   Input Parameters:
178 + pc - the preconditioner context
179 - dm - the dm, can be NULL
180 
181   Level: intermediate
182 
183   Developer Notes:
184   The routines KSP/SNES/TSSetDM() require the dm to be non-NULL, but this one can be NULL since all it does is
185   replace the current DM
186 
187 .seealso: `PCGetDM()`, `KSPSetDM()`, `KSPGetDM()`
188 @*/
189 PetscErrorCode PCSetDM(PC pc, DM dm)
190 {
191   PetscFunctionBegin;
192   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
193   if (dm) PetscCall(PetscObjectReference((PetscObject)dm));
194   PetscCall(DMDestroy(&pc->dm));
195   pc->dm = dm;
196   PetscFunctionReturn(PETSC_SUCCESS);
197 }
198 
199 /*@
200   PCGetDM - Gets the DM that may be used by some preconditioners
201 
202   Not Collective
203 
204   Input Parameter:
205 . pc - the preconditioner context
206 
207   Output Parameter:
208 . dm - the dm
209 
210   Level: intermediate
211 
212 .seealso: `PCSetDM()`, `KSPSetDM()`, `KSPGetDM()`
213 @*/
214 PetscErrorCode PCGetDM(PC pc, DM *dm)
215 {
216   PetscFunctionBegin;
217   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
218   *dm = pc->dm;
219   PetscFunctionReturn(PETSC_SUCCESS);
220 }
221 
222 /*@
223   PCSetApplicationContext - Sets the optional user-defined context for the linear solver.
224 
225   Logically Collective
226 
227   Input Parameters:
228 + pc   - the PC context
229 - usrP - optional user context
230 
231   Level: intermediate
232 
233 .seealso: `PCGetApplicationContext()`
234 @*/
235 PetscErrorCode PCSetApplicationContext(PC pc, void *usrP)
236 {
237   PetscFunctionBegin;
238   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
239   pc->user = usrP;
240   PetscFunctionReturn(PETSC_SUCCESS);
241 }
242 
243 /*@
244   PCGetApplicationContext - Gets the user-defined context for the linear solver.
245 
246   Not Collective
247 
248   Input Parameter:
249 . pc - PC context
250 
251   Output Parameter:
252 . usrP - user context
253 
254   Level: intermediate
255 
256 .seealso: `PCSetApplicationContext()`
257 @*/
258 PetscErrorCode PCGetApplicationContext(PC pc, void *usrP)
259 {
260   PetscFunctionBegin;
261   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
262   *(void **)usrP = pc->user;
263   PetscFunctionReturn(PETSC_SUCCESS);
264 }
265