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