xref: /petsc/src/ksp/pc/interface/pcset.c (revision 92ff6ae828fe67abd231a335eb38900b8f8c5b4a)
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   ierr =  PetscFListFind(pc->comm,PCList,type,(void (**)(void)) &r);CHKERRQ(ierr);
68   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PC type %s",type);
69   /* Destroy the previous private PC context */
70   if (pc->ops->destroy) { ierr =  (*pc->ops->destroy)(pc);CHKERRQ(ierr); }
71   ierr = PetscFListDestroy(pc->qlist);CHKERRQ(ierr);
72   /* Reinitialize function pointers in PCOps structure */
73   ierr = PetscMemzero(pc->ops,sizeof(struct _PCOps));CHKERRQ(ierr);
74   /* XXX Is this OK?? */
75   pc->modifysubmatrices        = 0;
76   pc->modifysubmatricesP       = 0;
77   /* Call the PCCreate_XXX routine for this particular preconditioner */
78   pc->setupcalled = 0;
79   ierr = (*r)(pc);CHKERRQ(ierr);
80   ierr = PetscObjectChangeTypeName((PetscObject)pc,type);CHKERRQ(ierr);
81   PetscFunctionReturn(0);
82 }
83 
84 #undef __FUNCT__
85 #define __FUNCT__ "PCRegisterDestroy"
86 /*@
87    PCRegisterDestroy - Frees the list of preconditioners that were
88    registered by PCRegisterDynamic().
89 
90    Not Collective
91 
92    Level: advanced
93 
94 .keywords: PC, register, destroy
95 
96 .seealso: PCRegisterAll(), PCRegisterAll()
97 
98 @*/
99 PetscErrorCode PETSCKSP_DLLEXPORT PCRegisterDestroy(void)
100 {
101   PetscErrorCode ierr;
102 
103   PetscFunctionBegin;
104   if (PCList) {
105     ierr = PetscFListDestroy(PCList);CHKERRQ(ierr);
106     PCList = 0;
107   }
108   PCRegisterAllCalled = PETSC_FALSE;
109   PetscFunctionReturn(0);
110 }
111 
112 #undef __FUNCT__
113 #define __FUNCT__ "PCGetType"
114 /*@C
115    PCGetType - Gets the PC method type and name (as a string) from the PC
116    context.
117 
118    Not Collective
119 
120    Input Parameter:
121 .  pc - the preconditioner context
122 
123    Output Parameter:
124 .  name - name of preconditioner
125 
126    Level: intermediate
127 
128 .keywords: PC, get, method, name, type
129 
130 .seealso: PCSetType()
131 
132 @*/
133 PetscErrorCode PETSCKSP_DLLEXPORT PCGetType(PC pc,PCType *meth)
134 {
135   PetscFunctionBegin;
136   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
137   PetscValidPointer(meth,2);
138   *meth = (PCType) pc->type_name;
139   PetscFunctionReturn(0);
140 }
141 
142 EXTERN PetscErrorCode PCGetDefaultType_Private(PC,const char*[]);
143 
144 #undef __FUNCT__
145 #define __FUNCT__ "PCSetFromOptions"
146 /*@
147    PCSetFromOptions - Sets PC options from the options database.
148    This routine must be called before PCSetUp() if the user is to be
149    allowed to set the preconditioner method.
150 
151    Collective on PC
152 
153    Input Parameter:
154 .  pc - the preconditioner context
155 
156    Level: developer
157 
158 .keywords: PC, set, from, options, database
159 
160 .seealso:
161 
162 @*/
163 PetscErrorCode PETSCKSP_DLLEXPORT PCSetFromOptions(PC pc)
164 {
165   PetscErrorCode ierr;
166   char           type[256];
167   const char     *def;
168   PetscTruth     flg;
169 
170   PetscFunctionBegin;
171   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
172 
173   if (!PCRegisterAllCalled) {ierr = PCRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
174   ierr = PetscOptionsBegin(pc->comm,pc->prefix,"Preconditioner (PC) Options","PC");CHKERRQ(ierr);
175     if (!pc->type_name) {
176       ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr);
177     } else {
178       def = pc->type_name;
179     }
180 
181     ierr = PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr);
182     if (flg) {
183       ierr = PCSetType(pc,type);CHKERRQ(ierr);
184     } else if (!pc->type_name){
185       ierr = PCSetType(pc,def);CHKERRQ(ierr);
186     }
187 
188     if (pc->ops->setfromoptions) {
189       ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr);
190     }
191   ierr = PetscOptionsEnd();CHKERRQ(ierr);
192   pc->setfromoptionscalled++;
193   PetscFunctionReturn(0);
194 }
195