xref: /petsc/src/ksp/pc/interface/pcset.c (revision 6a5217c03994f2d95bb2e6dbd8bed42381aeb015) !
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   PetscErrorCode ierr;
137   char           type[256];
138   const char     *def;
139   PetscBool      flg;
140 
141   PetscFunctionBegin;
142   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
143 
144   PetscCall(PCRegisterAll());
145   ierr = PetscObjectOptionsBegin((PetscObject)pc);PetscCall(ierr);
146   if (!((PetscObject)pc)->type_name) {
147     PetscCall(PCGetDefaultType_Private(pc,&def));
148   } else {
149     def = ((PetscObject)pc)->type_name;
150   }
151 
152   PetscCall(PetscOptionsFList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg));
153   if (flg) {
154     PetscCall(PCSetType(pc,type));
155   } else if (!((PetscObject)pc)->type_name) {
156     PetscCall(PCSetType(pc,def));
157   }
158 
159   PetscCall(PetscObjectTypeCompare((PetscObject)pc,PCNONE,&flg));
160   if (flg) goto skipoptions;
161 
162   PetscCall(PetscOptionsBool("-pc_use_amat","use Amat (instead of Pmat) to define preconditioner in nested inner solves","PCSetUseAmat",pc->useAmat,&pc->useAmat,NULL));
163 
164   if (pc->ops->setfromoptions) {
165     PetscCall((*pc->ops->setfromoptions)(PetscOptionsObject,pc));
166   }
167 
168   skipoptions:
169   /* process any options handlers added with PetscObjectAddOptionsHandler() */
170   PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pc));
171   ierr = PetscOptionsEnd();PetscCall(ierr);
172   pc->setfromoptionscalled++;
173   PetscFunctionReturn(0);
174 }
175 
176 /*@
177    PCSetDM - Sets the DM that may be used by some preconditioners
178 
179    Logically Collective on PC
180 
181    Input Parameters:
182 +  pc - the preconditioner context
183 -  dm - the dm, can be NULL
184 
185    Level: intermediate
186 
187    Developer Notes:
188     The routines KSP/SNES/TSSetDM() require the dm to be non-NULL, but this one can be NULL since all it does is
189     replace the current DM
190 
191 .seealso: PCGetDM(), KSPSetDM(), KSPGetDM()
192 @*/
193 PetscErrorCode  PCSetDM(PC pc,DM dm)
194 {
195   PetscFunctionBegin;
196   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
197   if (dm) PetscCall(PetscObjectReference((PetscObject)dm));
198   PetscCall(DMDestroy(&pc->dm));
199   pc->dm = dm;
200   PetscFunctionReturn(0);
201 }
202 
203 /*@
204    PCGetDM - Gets the DM that may be used by some preconditioners
205 
206    Not Collective
207 
208    Input Parameter:
209 . pc - the preconditioner context
210 
211    Output Parameter:
212 .  dm - the dm
213 
214    Level: intermediate
215 
216 .seealso: PCSetDM(), KSPSetDM(), KSPGetDM()
217 @*/
218 PetscErrorCode  PCGetDM(PC pc,DM *dm)
219 {
220   PetscFunctionBegin;
221   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
222   *dm = pc->dm;
223   PetscFunctionReturn(0);
224 }
225 
226 /*@
227    PCSetApplicationContext - Sets the optional user-defined context for the linear solver.
228 
229    Logically Collective on PC
230 
231    Input Parameters:
232 +  pc - the PC context
233 -  usrP - optional user context
234 
235    Level: intermediate
236 
237 .seealso: PCGetApplicationContext()
238 @*/
239 PetscErrorCode  PCSetApplicationContext(PC pc,void *usrP)
240 {
241   PetscFunctionBegin;
242   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
243   pc->user = usrP;
244   PetscFunctionReturn(0);
245 }
246 
247 /*@
248    PCGetApplicationContext - Gets the user-defined context for the linear solver.
249 
250    Not Collective
251 
252    Input Parameter:
253 .  pc - PC context
254 
255    Output Parameter:
256 .  usrP - user context
257 
258    Level: intermediate
259 
260 .seealso: PCSetApplicationContext()
261 @*/
262 PetscErrorCode  PCGetApplicationContext(PC pc,void *usrP)
263 {
264   PetscFunctionBegin;
265   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
266   *(void**)usrP = pc->user;
267   PetscFunctionReturn(0);
268 }
269