xref: /petsc/src/ksp/pc/interface/pcset.c (revision f3fe499b4cc4d64bf04aa4f5e4963dcc4eb56541)
1 #define PETSCKSP_DLL
2 /*
3     Routines to set PC methods and options.
4 */
5 
6 #include "private/pcimpl.h"      /*I "petscpc.h" I*/
7 
8 PetscTruth PCRegisterAllCalled = PETSC_FALSE;
9 /*
10    Contains the list of registered KSP routines
11 */
12 PetscFList PCList = 0;
13 
14 #undef __FUNCT__
15 #define __FUNCT__ "PCSetType"
16 /*@C
17    PCSetType - Builds PC for a particular preconditioner.
18 
19    Collective on PC
20 
21    Input Parameter:
22 +  pc - the preconditioner context.
23 -  type - a known method
24 
25    Options Database Key:
26 .  -pc_type <type> - Sets PC type
27 
28    Use -help for a list of available methods (for instance,
29    jacobi or bjacobi)
30 
31   Notes:
32   See "petsc/include/petscpc.h" for available methods (for instance,
33   PCJACOBI, PCILU, or PCBJACOBI).
34 
35   Normally, it is best to use the KSPSetFromOptions() command and
36   then set the PC type from the options database rather than by using
37   this routine.  Using the options database provides the user with
38   maximum flexibility in evaluating the many different preconditioners.
39   The PCSetType() routine is provided for those situations where it
40   is necessary to set the preconditioner independently of the command
41   line or options database.  This might be the case, for example, when
42   the choice of preconditioner changes during the execution of the
43   program, and the user's application is taking responsibility for
44   choosing the appropriate preconditioner.  In other words, this
45   routine is not for beginners.
46 
47   Level: intermediate
48 
49 .keywords: PC, set, method, type
50 
51 .seealso: KSPSetType(), PCType
52 
53 @*/
54 PetscErrorCode PETSCKSP_DLLEXPORT PCSetType(PC pc,const PCType type)
55 {
56   PetscErrorCode ierr,(*r)(PC);
57   PetscTruth     match;
58 
59   PetscFunctionBegin;
60   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
61   PetscValidCharPointer(type,2);
62 
63   ierr = PetscTypeCompare((PetscObject)pc,type,&match);CHKERRQ(ierr);
64   if (match) PetscFunctionReturn(0);
65 
66   ierr =  PetscFListFind(PCList,((PetscObject)pc)->comm,type,(void (**)(void)) &r);CHKERRQ(ierr);
67   if (!r) SETERRQ1(((PetscObject)pc)->comm,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) { ierr =  (*pc->ops->destroy)(pc);CHKERRQ(ierr); pc->data = 0;}
70   ierr = PetscFListDestroy(&((PetscObject)pc)->qlist);CHKERRQ(ierr);
71   /* Reinitialize function pointers in PCOps structure */
72   ierr = PetscMemzero(pc->ops,sizeof(struct _PCOps));CHKERRQ(ierr);
73   /* XXX Is this OK?? */
74   pc->modifysubmatrices        = 0;
75   pc->modifysubmatricesP       = 0;
76   /* Call the PCCreate_XXX routine for this particular preconditioner */
77   pc->setupcalled = 0;
78   ierr = (*r)(pc);CHKERRQ(ierr);
79   ierr = PetscObjectChangeTypeName((PetscObject)pc,type);CHKERRQ(ierr);
80   PetscFunctionReturn(0);
81 }
82 
83 #undef __FUNCT__
84 #define __FUNCT__ "PCRegisterDestroy"
85 /*@
86    PCRegisterDestroy - Frees the list of preconditioners that were
87    registered by PCRegisterDynamic().
88 
89    Not Collective
90 
91    Level: advanced
92 
93 .keywords: PC, register, destroy
94 
95 .seealso: PCRegisterAll(), PCRegisterAll()
96 
97 @*/
98 PetscErrorCode PETSCKSP_DLLEXPORT PCRegisterDestroy(void)
99 {
100   PetscErrorCode ierr;
101 
102   PetscFunctionBegin;
103   ierr = PetscFListDestroy(&PCList);CHKERRQ(ierr);
104   PCRegisterAllCalled = PETSC_FALSE;
105   PetscFunctionReturn(0);
106 }
107 
108 #undef __FUNCT__
109 #define __FUNCT__ "PCGetType"
110 /*@C
111    PCGetType - Gets the PC method type and name (as a string) from the PC
112    context.
113 
114    Not Collective
115 
116    Input Parameter:
117 .  pc - the preconditioner context
118 
119    Output Parameter:
120 .  type - name of preconditioner method
121 
122    Level: intermediate
123 
124 .keywords: PC, get, method, name, type
125 
126 .seealso: PCSetType()
127 
128 @*/
129 PetscErrorCode PETSCKSP_DLLEXPORT PCGetType(PC pc,const PCType *type)
130 {
131   PetscFunctionBegin;
132   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
133   PetscValidPointer(type,2);
134   *type = ((PetscObject)pc)->type_name;
135   PetscFunctionReturn(0);
136 }
137 
138 EXTERN PetscErrorCode PCGetDefaultType_Private(PC,const char*[]);
139 
140 #undef __FUNCT__
141 #define __FUNCT__ "PCSetFromOptions"
142 /*@
143    PCSetFromOptions - Sets PC options from the options database.
144    This routine must be called before PCSetUp() if the user is to be
145    allowed to set the preconditioner method.
146 
147    Collective on PC
148 
149    Input Parameter:
150 .  pc - the preconditioner context
151 
152    Level: developer
153 
154 .keywords: PC, set, from, options, database
155 
156 .seealso:
157 
158 @*/
159 PetscErrorCode PETSCKSP_DLLEXPORT PCSetFromOptions(PC pc)
160 {
161   PetscErrorCode ierr;
162   char           type[256];
163   const char     *def;
164   PetscTruth     flg;
165 
166   PetscFunctionBegin;
167   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
168 
169   if (!PCRegisterAllCalled) {ierr = PCRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
170   ierr = PetscOptionsBegin(((PetscObject)pc)->comm,((PetscObject)pc)->prefix,"Preconditioner (PC) Options","PC");CHKERRQ(ierr);
171     if (!((PetscObject)pc)->type_name) {
172       ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr);
173     } else {
174       def = ((PetscObject)pc)->type_name;
175     }
176 
177     ierr = PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr);
178     if (flg) {
179       ierr = PCSetType(pc,type);CHKERRQ(ierr);
180     } else if (!((PetscObject)pc)->type_name){
181       ierr = PCSetType(pc,def);CHKERRQ(ierr);
182     }
183 
184     if (pc->ops->setfromoptions) {
185       ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr);
186     }
187 
188     /* process any options handlers added with PetscObjectAddOptionsHandler() */
189     ierr = PetscObjectProcessOptionsHandlers((PetscObject)pc);CHKERRQ(ierr);
190   ierr = PetscOptionsEnd();CHKERRQ(ierr);
191   pc->setfromoptionscalled++;
192   PetscFunctionReturn(0);
193 }
194 
195 #undef __FUNCT__
196 #define __FUNCT__ "PCSetDM"
197 /*@
198    PCSetDM - Sets the DM that may be used by some preconditioners
199 
200    Logically Collective on PC
201 
202    Input Parameters:
203 +  pc - the preconditioner context
204 -  dm - the dm
205 
206    Level: intermediate
207 
208 
209 .seealso: PCGetDM(), KSPSetDM(), KSPGetDM()
210 @*/
211 PetscErrorCode PETSCKSP_DLLEXPORT PCSetDM(PC pc,DM dm)
212 {
213   PetscErrorCode ierr;
214 
215   PetscFunctionBegin;
216   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
217   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
218   if (pc->dm) {ierr = DMDestroy(pc->dm);CHKERRQ(ierr);}
219   pc->dm = dm;
220   PetscFunctionReturn(0);
221 }
222 
223 #undef __FUNCT__
224 #define __FUNCT__ "PCGetDM"
225 /*@
226    PCGetDM - Gets the DM that may be used by some preconditioners
227 
228    Not Collective
229 
230    Input Parameter:
231 . pc - the preconditioner context
232 
233    Output Parameter:
234 .  dm - the dm
235 
236    Level: intermediate
237 
238 
239 .seealso: PCSetDM(), KSPSetDM(), KSPGetDM()
240 @*/
241 PetscErrorCode PETSCKSP_DLLEXPORT PCGetDM(PC pc,DM *dm)
242 {
243   PetscFunctionBegin;
244   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
245   *dm = pc->dm;
246   PetscFunctionReturn(0);
247 }
248 
249