xref: /petsc/src/ksp/pc/interface/pcset.c (revision 030f984af8d8bb4c203755d35bded3c05b3d83ce)
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 Parameter:
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   PetscErrorCode ierr,(*r)(PC);
57   PetscBool      match;
58 
59   PetscFunctionBegin;
60   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
61   PetscValidCharPointer(type,2);
62 
63   ierr = PetscObjectTypeCompare((PetscObject)pc,type,&match);CHKERRQ(ierr);
64   if (match) PetscFunctionReturn(0);
65 
66   ierr =  PetscFunctionListFind(PCList,type,&r);CHKERRQ(ierr);
67   if (!r) SETERRQ1(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     ierr             = (*pc->ops->destroy)(pc);CHKERRQ(ierr);
71     pc->ops->destroy = NULL;
72     pc->data         = NULL;
73   }
74   ierr = PetscFunctionListDestroy(&((PetscObject)pc)->qlist);CHKERRQ(ierr);
75   /* Reinitialize function pointers in PCOps structure */
76   ierr = PetscMemzero(pc->ops,sizeof(struct _PCOps));CHKERRQ(ierr);
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   ierr = PetscObjectChangeTypeName((PetscObject)pc,type);CHKERRQ(ierr);
84   ierr = (*r)(pc);CHKERRQ(ierr);
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   ierr = PCRegisterAll();CHKERRQ(ierr);
145   ierr = PetscObjectOptionsBegin((PetscObject)pc);CHKERRQ(ierr);
146   if (!((PetscObject)pc)->type_name) {
147     ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr);
148   } else {
149     def = ((PetscObject)pc)->type_name;
150   }
151 
152   ierr = PetscOptionsFList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr);
153   if (flg) {
154     ierr = PCSetType(pc,type);CHKERRQ(ierr);
155   } else if (!((PetscObject)pc)->type_name) {
156     ierr = PCSetType(pc,def);CHKERRQ(ierr);
157   }
158 
159   ierr = PetscObjectTypeCompare((PetscObject)pc,PCNONE,&flg);CHKERRQ(ierr);
160   if (flg) goto skipoptions;
161 
162   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);
163 
164   if (pc->ops->setfromoptions) {
165     ierr = (*pc->ops->setfromoptions)(PetscOptionsObject,pc);CHKERRQ(ierr);
166   }
167 
168   skipoptions:
169   /* process any options handlers added with PetscObjectAddOptionsHandler() */
170   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pc);CHKERRQ(ierr);
171   ierr = PetscOptionsEnd();CHKERRQ(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   PetscErrorCode ierr;
196 
197   PetscFunctionBegin;
198   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
199   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
200   ierr   = DMDestroy(&pc->dm);CHKERRQ(ierr);
201   pc->dm = dm;
202   PetscFunctionReturn(0);
203 }
204 
205 /*@
206    PCGetDM - Gets the DM that may be used by some preconditioners
207 
208    Not Collective
209 
210    Input Parameter:
211 . pc - the preconditioner context
212 
213    Output Parameter:
214 .  dm - the dm
215 
216    Level: intermediate
217 
218 .seealso: PCSetDM(), KSPSetDM(), KSPGetDM()
219 @*/
220 PetscErrorCode  PCGetDM(PC pc,DM *dm)
221 {
222   PetscFunctionBegin;
223   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
224   *dm = pc->dm;
225   PetscFunctionReturn(0);
226 }
227 
228 /*@
229    PCSetApplicationContext - Sets the optional user-defined context for the linear solver.
230 
231    Logically Collective on PC
232 
233    Input Parameters:
234 +  pc - the PC context
235 -  usrP - optional user context
236 
237    Level: intermediate
238 
239 .seealso: PCGetApplicationContext()
240 @*/
241 PetscErrorCode  PCSetApplicationContext(PC pc,void *usrP)
242 {
243   PetscFunctionBegin;
244   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
245   pc->user = usrP;
246   PetscFunctionReturn(0);
247 }
248 
249 /*@
250    PCGetApplicationContext - Gets the user-defined context for the linear solver.
251 
252    Not Collective
253 
254    Input Parameter:
255 .  pc - PC context
256 
257    Output Parameter:
258 .  usrP - user context
259 
260    Level: intermediate
261 
262 .seealso: PCSetApplicationContext()
263 @*/
264 PetscErrorCode  PCGetApplicationContext(PC pc,void *usrP)
265 {
266   PetscFunctionBegin;
267   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
268   *(void**)usrP = pc->user;
269   PetscFunctionReturn(0);
270 }
271