Actual source code: pcset.c
1: /*$Id: pcset.c,v 1.118 2001/08/21 21:03:13 bsmith Exp $*/
2: /*
3: Routines to set PC methods and options.
4: */
6: #include src/sles/pc/pcimpl.h
7: #include petscsys.h
9: PetscTruth PCRegisterAllCalled = PETSC_FALSE;
10: /*
11: Contains the list of registered KSP routines
12: */
13: PetscFList PCList = 0;
15: /*@C
16: PCSetType - Builds PC for a particular preconditioner.
18: Collective on PC
20: Input Parameter:
21: + pc - the preconditioner context.
22: - type - a known method
24: Options Database Key:
25: . -pc_type <type> - Sets PC type
27: Use -help for a list of available methods (for instance,
28: jacobi or bjacobi)
30: Notes:
31: See "petsc/include/petscpc.h" for available methods (for instance,
32: PCJACOBI, PCILU, or PCBJACOBI).
34: Normally, it is best to use the SLESSetFromOptions() command and
35: then set the PC type from the options database rather than by using
36: this routine. Using the options database provides the user with
37: maximum flexibility in evaluating the many different preconditioners.
38: The PCSetType() routine is provided for those situations where it
39: is necessary to set the preconditioner independently of the command
40: line or options database. This might be the case, for example, when
41: the choice of preconditioner changes during the execution of the
42: program, and the user's application is taking responsibility for
43: choosing the appropriate preconditioner. In other words, this
44: routine is not for beginners.
46: Level: intermediate
48: .keywords: PC, set, method, type
50: .seealso: KSPSetType(), PCType
52: @*/
53: int PCSetType(PC pc,PCType type)
54: {
55: int ierr,(*r)(PC);
56: PetscTruth match;
62: PetscTypeCompare((PetscObject)pc,type,&match);
63: if (match) return(0);
65: if (pc->ops->destroy) { (*pc->ops->destroy)(pc);}
66: PetscFListDestroy(&pc->qlist);
67: pc->data = 0;
68: pc->setupcalled = 0;
70: /* Get the function pointers for the method requested */
71: if (!PCRegisterAllCalled) {PCRegisterAll(0);}
73: /* Determine the PCCreateXXX routine for a particular preconditioner */
74: PetscFListFind(pc->comm,PCList,type,(void (**)(void)) &r);
75: if (!r) SETERRQ1(1,"Unable to find requested PC type %s",type);
76: if (pc->data) {PetscFree(pc->data);}
78: pc->ops->destroy = (int (*)(PC)) 0;
79: pc->ops->view = (int (*)(PC,PetscViewer)) 0;
80: pc->ops->apply = (int (*)(PC,Vec,Vec)) 0;
81: pc->ops->setup = (int (*)(PC)) 0;
82: pc->ops->applyrichardson = (int (*)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int)) 0;
83: pc->ops->applyBA = (int (*)(PC,int,Vec,Vec,Vec)) 0;
84: pc->ops->setfromoptions = (int (*)(PC)) 0;
85: pc->ops->applytranspose = (int (*)(PC,Vec,Vec)) 0;
86: pc->ops->applyBAtranspose = (int (*)(PC,int,Vec,Vec,Vec)) 0;
87: pc->ops->presolve = (int (*)(PC,KSP,Vec,Vec)) 0;
88: pc->ops->postsolve = (int (*)(PC,KSP,Vec,Vec)) 0;
89: pc->ops->getfactoredmatrix = (int (*)(PC,Mat*)) 0;
90: pc->ops->applysymmetricleft = (int (*)(PC,Vec,Vec)) 0;
91: pc->ops->applysymmetricright = (int (*)(PC,Vec,Vec)) 0;
92: pc->ops->setuponblocks = (int (*)(PC)) 0;
93: pc->modifysubmatrices = (int (*)(PC,int,IS*,IS*,Mat*,void*)) 0;
95: /* Call the PCCreateXXX routine for this particular preconditioner */
96: (*r)(pc);
98: PetscObjectChangeTypeName((PetscObject)pc,type);
99: return(0);
100: }
102: /*@C
103: PCRegisterDestroy - Frees the list of preconditioners that were
104: registered by PCRegisterDynamic().
106: Not Collective
108: Level: advanced
110: .keywords: PC, register, destroy
112: .seealso: PCRegisterAll(), PCRegisterAll()
114: @*/
115: int PCRegisterDestroy(void)
116: {
120: if (PCList) {
121: PetscFListDestroy(&PCList);
122: PCList = 0;
123: }
124: PCRegisterAllCalled = PETSC_FALSE;
125: return(0);
126: }
128: /*@C
129: PCGetType - Gets the PC method type and name (as a string) from the PC
130: context.
132: Not Collective
134: Input Parameter:
135: . pc - the preconditioner context
137: Output Parameter:
138: . name - name of preconditioner
140: Level: intermediate
142: .keywords: PC, get, method, name, type
144: .seealso: PCSetType()
146: @*/
147: int PCGetType(PC pc,PCType *meth)
148: {
150: *meth = (PCType) pc->type_name;
151: return(0);
152: }
154: /*@
155: PCSetFromOptions - Sets PC options from the options database.
156: This routine must be called before PCSetUp() if the user is to be
157: allowed to set the preconditioner method.
159: Collective on PC
161: Input Parameter:
162: . pc - the preconditioner context
164: Level: developer
166: .keywords: PC, set, from, options, database
168: .seealso:
170: @*/
171: int PCSetFromOptions(PC pc)
172: {
173: int ierr;
174: char type[256],*def;
175: PetscTruth flg;
180: if (!PCRegisterAllCalled) {PCRegisterAll(PETSC_NULL);}
181: PetscOptionsBegin(pc->comm,pc->prefix,"Preconditioner (PC) Options","PC");
182: if (!pc->type_name) {
183: PetscTruth ismatshell;
184: int size;
186: /*
187: Shell matrix (probably) cannot support Bjacobi and ILU
188: */
189: MPI_Comm_size(pc->comm,&size);
190: if (pc->pmat) {
191: PetscTypeCompare((PetscObject)pc->pmat,MATSHELL,&ismatshell);
192: } else {
193: ismatshell = PETSC_FALSE; /* matrix is not yet set, so guess that it will not be MATSHELL */
194: }
195: /*
196: MATMFFD cannot support BJacobia and ILU
197: */
198: if (!ismatshell) {
199: PetscTypeCompare((PetscObject)pc->pmat,MATMFFD,&ismatshell);
200: }
202: if (ismatshell) {
203: def = PCNONE;
204: PetscLogInfo(pc,"PCSetOperators:Setting default PC to PCNONE since MATSHELL doesn't supportn
205: preconditioners (unless defined by the user)n");
206: } else if (size == 1) {
207: def = PCILU;
208: } else {
209: def = PCBJACOBI;
210: }
211: } else {
212: def = pc->type_name;
213: }
215: PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);
216: if (flg) {
217: PCSetType(pc,type);
218: }
219: /* option is actually checked in PCSetUp() */
220: if (pc->nullsp) {
221: PetscOptionsName("-pc_test_null_space","Is provided null space correct","None",&flg);
222: }
224: /*
225: Set the type if it was never set.
226: */
227: if (!pc->type_name) {
228: PCSetType(pc,def);
229: }
231: if (pc->ops->setfromoptions) {
232: (*pc->ops->setfromoptions)(pc);
233: }
234: PetscOptionsEnd();
235: #if defined(__cplusplus) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_MATSINGLE) && defined(PETSC_HAVE_CXX_NAMESPACE)
236: PCESISetFromOptions(pc);
237: #endif
238: return(0);
239: }