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: #undef __FUNCT__
17: /*@C
18: PCSetType - Builds PC for a particular preconditioner.
20: Collective on PC
22: Input Parameter:
23: + pc - the preconditioner context.
24: - type - a known method
26: Options Database Key:
27: . -pc_type <type> - Sets PC type
29: Use -help for a list of available methods (for instance,
30: jacobi or bjacobi)
32: Notes:
33: See "petsc/include/petscpc.h" for available methods (for instance,
34: PCJACOBI, PCILU, or PCBJACOBI).
36: Normally, it is best to use the SLESSetFromOptions() 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.
48: Level: intermediate
50: .keywords: PC, set, method, type
52: .seealso: KSPSetType(), PCType
54: @*/
55: int PCSetType(PC pc,PCType type)
56: {
57: int ierr,(*r)(PC);
58: PetscTruth match;
64: PetscTypeCompare((PetscObject)pc,type,&match);
65: if (match) return(0);
67: if (pc->ops->destroy) { (*pc->ops->destroy)(pc);}
68: PetscFListDestroy(&pc->qlist);
69: pc->data = 0;
70: pc->setupcalled = 0;
72: /* Get the function pointers for the method requested */
73: if (!PCRegisterAllCalled) {PCRegisterAll(0);}
75: /* Determine the PCCreateXXX routine for a particular preconditioner */
76: PetscFListFind(pc->comm,PCList,type,(void (**)(void)) &r);
77: if (!r) SETERRQ1(1,"Unable to find requested PC type %s",type);
78: if (pc->data) {PetscFree(pc->data);}
80: pc->ops->destroy = (int (*)(PC)) 0;
81: pc->ops->view = (int (*)(PC,PetscViewer)) 0;
82: pc->ops->apply = (int (*)(PC,Vec,Vec)) 0;
83: pc->ops->setup = (int (*)(PC)) 0;
84: pc->ops->applyrichardson = (int (*)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int)) 0;
85: pc->ops->applyBA = (int (*)(PC,int,Vec,Vec,Vec)) 0;
86: pc->ops->setfromoptions = (int (*)(PC)) 0;
87: pc->ops->applytranspose = (int (*)(PC,Vec,Vec)) 0;
88: pc->ops->applyBAtranspose = (int (*)(PC,int,Vec,Vec,Vec)) 0;
89: pc->ops->presolve = (int (*)(PC,KSP,Vec,Vec)) 0;
90: pc->ops->postsolve = (int (*)(PC,KSP,Vec,Vec)) 0;
91: pc->ops->getfactoredmatrix = (int (*)(PC,Mat*)) 0;
92: pc->ops->applysymmetricleft = (int (*)(PC,Vec,Vec)) 0;
93: pc->ops->applysymmetricright = (int (*)(PC,Vec,Vec)) 0;
94: pc->ops->setuponblocks = (int (*)(PC)) 0;
95: pc->modifysubmatrices = (int (*)(PC,int,IS*,IS*,Mat*,void*)) 0;
97: /* Call the PCCreateXXX routine for this particular preconditioner */
98: (*r)(pc);
100: PetscObjectChangeTypeName((PetscObject)pc,type);
101: return(0);
102: }
104: #undef __FUNCT__
106: /*@C
107: PCRegisterDestroy - Frees the list of preconditioners that were
108: registered by PCRegisterDynamic().
110: Not Collective
112: Level: advanced
114: .keywords: PC, register, destroy
116: .seealso: PCRegisterAll(), PCRegisterAll()
118: @*/
119: int PCRegisterDestroy(void)
120: {
124: if (PCList) {
125: PetscFListDestroy(&PCList);
126: PCList = 0;
127: }
128: PCRegisterAllCalled = PETSC_FALSE;
129: return(0);
130: }
132: #undef __FUNCT__
134: /*@C
135: PCGetType - Gets the PC method type and name (as a string) from the PC
136: context.
138: Not Collective
140: Input Parameter:
141: . pc - the preconditioner context
143: Output Parameter:
144: . name - name of preconditioner
146: Level: intermediate
148: .keywords: PC, get, method, name, type
150: .seealso: PCSetType()
152: @*/
153: int PCGetType(PC pc,PCType *meth)
154: {
156: *meth = (PCType) pc->type_name;
157: return(0);
158: }
160: #undef __FUNCT__
162: /*@
163: PCSetFromOptions - Sets PC options from the options database.
164: This routine must be called before PCSetUp() if the user is to be
165: allowed to set the preconditioner method.
167: Collective on PC
169: Input Parameter:
170: . pc - the preconditioner context
172: Level: developer
174: .keywords: PC, set, from, options, database
176: .seealso:
178: @*/
179: int PCSetFromOptions(PC pc)
180: {
181: int ierr;
182: char type[256],*def;
183: PetscTruth flg;
188: if (!PCRegisterAllCalled) {PCRegisterAll(PETSC_NULL);}
189: PetscOptionsBegin(pc->comm,pc->prefix,"Preconditioner (PC) Options","PC");
190: if (!pc->type_name) {
191: PetscTruth ismatshell;
192: int size;
194: /*
195: Shell matrix (probably) cannot support Bjacobi and ILU
196: */
197: MPI_Comm_size(pc->comm,&size);
198: if (pc->pmat) {
199: PetscTypeCompare((PetscObject)pc->pmat,MATSHELL,&ismatshell);
200: } else {
201: ismatshell = PETSC_FALSE; /* matrix is not yet set, so guess that it will not be MATSHELL */
202: }
203: /*
204: MATMFFD cannot support BJacobia and ILU
205: */
206: if (!ismatshell) {
207: PetscTypeCompare((PetscObject)pc->pmat,MATMFFD,&ismatshell);
208: }
210: if (ismatshell) {
211: def = PCNONE;
212: PetscLogInfo(pc,"PCSetOperators:Setting default PC to PCNONE since MATSHELL doesn't supportn
213: preconditioners (unless defined by the user)n");
214: } else if (size == 1) {
215: PetscTypeCompare((PetscObject)pc->pmat,MATSEQSBAIJ,&flg);
216: if (flg) {
217: def = PCICC;
218: } else {
219: def = PCILU;
220: }
221: } else {
222: def = PCBJACOBI;
223: }
224: } else {
225: def = pc->type_name;
226: }
228: PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);
229: if (flg) {
230: PCSetType(pc,type);
231: }
232: /* option is actually checked in PCSetUp() */
233: if (pc->nullsp) {
234: PetscOptionsName("-pc_test_null_space","Is provided null space correct","None",&flg);
235: }
237: /*
238: Set the type if it was never set.
239: */
240: if (!pc->type_name) {
241: PCSetType(pc,def);
242: }
244: if (pc->ops->setfromoptions) {
245: (*pc->ops->setfromoptions)(pc);
246: }
247: PetscOptionsEnd();
248: #if defined(__cplusplus) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && defined(PETSC_HAVE_CXX_NAMESPACE)
249: PCESISetFromOptions(pc);
250: #endif
251: return(0);
252: }