xref: /petsc/src/ksp/pc/interface/pcset.c (revision 6849ba73f22fecb8f92ef896a42e4e8bd4cd6965)
1 /*
2     Routines to set PC methods and options.
3 */
4 
5 #include "src/ksp/pc/pcimpl.h"      /*I "petscpc.h" I*/
6 #include "petscsys.h"
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 PCSetType(PC pc,const PCType type)
55 {
56   PetscErrorCode ierr,(*r)(PC);
57   PetscTruth match;
58 
59   PetscFunctionBegin;
60   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
61   PetscValidCharPointer(type,2);
62 
63   ierr = PetscTypeCompare((PetscObject)pc,type,&match);CHKERRQ(ierr);
64   if (match) PetscFunctionReturn(0);
65 
66   if (pc->ops->destroy) {ierr =  (*pc->ops->destroy)(pc);CHKERRQ(ierr);}
67   ierr = PetscFListDestroy(&pc->qlist);CHKERRQ(ierr);
68   pc->data        = 0;
69   pc->setupcalled = 0;
70 
71   /* Get the function pointers for the method requested */
72   if (!PCRegisterAllCalled) {ierr = PCRegisterAll(0);CHKERRQ(ierr);}
73 
74   /* Determine the PCCreateXXX routine for a particular preconditioner */
75   ierr =  PetscFListFind(pc->comm,PCList,type,(void (**)(void)) &r);CHKERRQ(ierr);
76   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PC type %s",type);
77   if (pc->data) {ierr = PetscFree(pc->data);CHKERRQ(ierr);}
78 
79   pc->ops->destroy             = (PetscErrorCode (*)(PC)) 0;
80   pc->ops->view                = (PetscErrorCode (*)(PC,PetscViewer)) 0;
81   pc->ops->apply               = (PetscErrorCode (*)(PC,Vec,Vec)) 0;
82   pc->ops->setup               = (PetscErrorCode (*)(PC)) 0;
83   pc->ops->applyrichardson     = (PetscErrorCode (*)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int)) 0;
84   pc->ops->applyBA             = (PetscErrorCode (*)(PC,int,Vec,Vec,Vec)) 0;
85   pc->ops->setfromoptions      = (PetscErrorCode (*)(PC)) 0;
86   pc->ops->applytranspose      = (PetscErrorCode (*)(PC,Vec,Vec)) 0;
87   pc->ops->applyBAtranspose    = (PetscErrorCode (*)(PC,int,Vec,Vec,Vec)) 0;
88   pc->ops->presolve            = (PetscErrorCode (*)(PC,KSP,Vec,Vec)) 0;
89   pc->ops->postsolve           = (PetscErrorCode (*)(PC,KSP,Vec,Vec)) 0;
90   pc->ops->getfactoredmatrix   = (PetscErrorCode (*)(PC,Mat*)) 0;
91   pc->ops->applysymmetricleft  = (PetscErrorCode (*)(PC,Vec,Vec)) 0;
92   pc->ops->applysymmetricright = (PetscErrorCode (*)(PC,Vec,Vec)) 0;
93   pc->ops->setuponblocks       = (PetscErrorCode (*)(PC)) 0;
94   pc->modifysubmatrices        = (PetscErrorCode (*)(PC,int,const IS[],const IS[],Mat[],void*)) 0;
95 
96   /* Call the PCCreateXXX routine for this particular preconditioner */
97   ierr = (*r)(pc);CHKERRQ(ierr);
98 
99   ierr = PetscObjectChangeTypeName((PetscObject)pc,type);CHKERRQ(ierr);
100   PetscFunctionReturn(0);
101 }
102 
103 #undef __FUNCT__
104 #define __FUNCT__ "PCRegisterDestroy"
105 /*@C
106    PCRegisterDestroy - Frees the list of preconditioners that were
107    registered by PCRegisterDynamic().
108 
109    Not Collective
110 
111    Level: advanced
112 
113 .keywords: PC, register, destroy
114 
115 .seealso: PCRegisterAll(), PCRegisterAll()
116 
117 @*/
118 PetscErrorCode PCRegisterDestroy(void)
119 {
120   PetscErrorCode ierr;
121 
122   PetscFunctionBegin;
123   if (PCList) {
124     ierr = PetscFListDestroy(&PCList);CHKERRQ(ierr);
125     PCList = 0;
126   }
127   PCRegisterAllCalled = PETSC_FALSE;
128   PetscFunctionReturn(0);
129 }
130 
131 #undef __FUNCT__
132 #define __FUNCT__ "PCGetType"
133 /*@C
134    PCGetType - Gets the PC method type and name (as a string) from the PC
135    context.
136 
137    Not Collective
138 
139    Input Parameter:
140 .  pc - the preconditioner context
141 
142    Output Parameter:
143 .  name - name of preconditioner
144 
145    Level: intermediate
146 
147 .keywords: PC, get, method, name, type
148 
149 .seealso: PCSetType()
150 
151 @*/
152 PetscErrorCode PCGetType(PC pc,PCType *meth)
153 {
154   PetscFunctionBegin;
155   *meth = (PCType) pc->type_name;
156   PetscFunctionReturn(0);
157 }
158 
159 EXTERN PetscErrorCode PCGetDefaultType_Private(PC,const char*[]);
160 
161 #undef __FUNCT__
162 #define __FUNCT__ "PCSetFromOptions"
163 /*@
164    PCSetFromOptions - Sets PC options from the options database.
165    This routine must be called before PCSetUp() if the user is to be
166    allowed to set the preconditioner method.
167 
168    Collective on PC
169 
170    Input Parameter:
171 .  pc - the preconditioner context
172 
173    Level: developer
174 
175 .keywords: PC, set, from, options, database
176 
177 .seealso:
178 
179 @*/
180 PetscErrorCode PCSetFromOptions(PC pc)
181 {
182   PetscErrorCode ierr;
183   char       type[256];
184   const char *def;
185   PetscTruth flg;
186 
187   PetscFunctionBegin;
188   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
189 
190   if (!PCRegisterAllCalled) {ierr = PCRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
191   ierr = PetscOptionsBegin(pc->comm,pc->prefix,"Preconditioner (PC) Options","PC");CHKERRQ(ierr);
192     if (!pc->type_name) {
193       ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr);
194     } else {
195       def = pc->type_name;
196     }
197 
198     ierr = PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr);
199     if (flg) {
200       ierr = PCSetType(pc,type);CHKERRQ(ierr);
201     } else if (!pc->type_name){
202       ierr = PCSetType(pc,def);CHKERRQ(ierr);
203     }
204 
205     if (pc->ops->setfromoptions) {
206       ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr);
207     }
208   ierr = PetscOptionsEnd();CHKERRQ(ierr);
209 #if defined(__cplusplus) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && defined(PETSC_HAVE_CXX_NAMESPACE)
210   ierr = PCESISetFromOptions(pc);CHKERRQ(ierr);
211 #endif
212   PetscFunctionReturn(0);
213 }
214