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