xref: /petsc/src/ksp/pc/interface/pcset.c (revision fd705b320d8d44969be9ca25a36dbdd35fbe8e12)
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(PCList,((PetscObject)pc)->comm,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(&((PetscObject)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   ierr = PetscFListDestroy(&PCList);CHKERRQ(ierr);
105   PCRegisterAllCalled = PETSC_FALSE;
106   PetscFunctionReturn(0);
107 }
108 
109 #undef __FUNCT__
110 #define __FUNCT__ "PCGetType"
111 /*@C
112    PCGetType - Gets the PC method type and name (as a string) from the PC
113    context.
114 
115    Not Collective
116 
117    Input Parameter:
118 .  pc - the preconditioner context
119 
120    Output Parameter:
121 .  name - name of preconditioner
122 
123    Level: intermediate
124 
125 .keywords: PC, get, method, name, type
126 
127 .seealso: PCSetType()
128 
129 @*/
130 PetscErrorCode PETSCKSP_DLLEXPORT PCGetType(PC pc,PCType *meth)
131 {
132   PetscFunctionBegin;
133   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
134   PetscValidPointer(meth,2);
135   *meth = (PCType) ((PetscObject)pc)->type_name;
136   PetscFunctionReturn(0);
137 }
138 
139 EXTERN PetscErrorCode PCGetDefaultType_Private(PC,const char*[]);
140 
141 #undef __FUNCT__
142 #define __FUNCT__ "PCSetFromOptions"
143 /*@
144    PCSetFromOptions - Sets PC options from the options database.
145    This routine must be called before PCSetUp() if the user is to be
146    allowed to set the preconditioner method.
147 
148    Collective on PC
149 
150    Input Parameter:
151 .  pc - the preconditioner context
152 
153    Level: developer
154 
155 .keywords: PC, set, from, options, database
156 
157 .seealso:
158 
159 @*/
160 PetscErrorCode PETSCKSP_DLLEXPORT PCSetFromOptions(PC pc)
161 {
162   PetscErrorCode ierr;
163   char           type[256];
164   const char     *def;
165   PetscTruth     flg;
166 
167   PetscFunctionBegin;
168   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
169 
170   if (!PCRegisterAllCalled) {ierr = PCRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
171   ierr = PetscOptionsBegin(((PetscObject)pc)->comm,((PetscObject)pc)->prefix,"Preconditioner (PC) Options","PC");CHKERRQ(ierr);
172     if (!((PetscObject)pc)->type_name) {
173       ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr);
174     } else {
175       def = ((PetscObject)pc)->type_name;
176     }
177 
178     ierr = PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr);
179     if (flg) {
180       ierr = PCSetType(pc,type);CHKERRQ(ierr);
181     } else if (!((PetscObject)pc)->type_name){
182       ierr = PCSetType(pc,def);CHKERRQ(ierr);
183     }
184 
185     if (pc->ops->setfromoptions) {
186       ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr);
187     }
188   ierr = PetscOptionsEnd();CHKERRQ(ierr);
189   pc->setfromoptionscalled++;
190   PetscFunctionReturn(0);
191 }
192