Actual source code: pesi.c
1: /*$Id: jacobi.c,v 1.75 2001/08/07 03:03:32 balay Exp $*/
4: #include src/sles/pc/pcimpl.h
5: #include esi/petsc/preconditioner.h
7: /*
8: Private context (data structure) for the ESI
9: */
10: typedef struct {
11: esi::Preconditioner<double,int> *epc;
12: } PC_ESI;
14: #undef __FUNCT__
16: /*@C
17: PCESISetPreconditioner - Takes a PETSc PC sets it to type ESI and
18: provides the ESI preconditioner that it wraps to look like a PETSc PC.
20: Input Parameter:
21: . xin - The Petsc PC
23: Output Parameter:
24: . v - The ESI preconditioner
26: Level: advanced
28: .keywords: PC, ESI
29: @*/
30: int PCESISetPreconditioner(PC xin,esi::Preconditioner<double,int> *v)
31: {
32: PC_ESI *x = (PC_ESI*)xin->data;
33: PetscTruth tesi;
34: int ierr;
37: PetscTypeCompare((PetscObject)xin,0,&tesi);
38: if (tesi) {
39: PCSetType(xin,PCESI);
40: }
41: PetscTypeCompare((PetscObject)xin,PCESI,&tesi);
42: if (tesi) {
43: x->epc = v;
44: v->addReference();
45: }
46: return(0);
47: }
49: #include esi/petsc/matrix.h
51: #undef __FUNCT__
53: static int PCSetUp_ESI(PC pc)
54: {
55: PC_ESI *jac = (PC_ESI*)pc->data;
56: int ierr;
57: ::esi::Operator<double,int> *em;
60: MatESIWrap(pc->mat,&em);
61: jac->epc->setOperator(*em);
62: jac->epc->setup();
63: return(0);
64: }
66: #undef __FUNCT__
68: static int PCApply_ESI(PC pc,Vec x,Vec y)
69: {
70: PC_ESI *jac = (PC_ESI*)pc->data;
71: esi::Vector<double,int> *xx,*yy;
72: int ierr;
75: VecESIWrap(x,&xx);
76: VecESIWrap(y,&yy);
77: jac->epc->solve(*xx,*yy);
78: return(0);
79: }
81: #undef __FUNCT__
83: static int PCApplySymmetricLeft_ESI(PC pc,Vec x,Vec y)
84: {
85: int ierr;
86: PC_ESI *jac = (PC_ESI*)pc->data;
87: esi::Vector<double,int> *xx,*yy;
90: VecESIWrap(x,&xx);
91: VecESIWrap(y,&yy);
92: jac->epc->solveLeft(*xx,*yy);
93: return(0);
94: }
96: #undef __FUNCT__
98: static int PCApplySymmetricRight_ESI(PC pc,Vec x,Vec y)
99: {
100: int ierr;
101: PC_ESI *jac = (PC_ESI*)pc->data;
102: esi::Vector<double,int> *xx,*yy;
105: VecESIWrap(x,&xx);
106: VecESIWrap(y,&yy);
107: jac->epc->solveRight(*xx,*yy);
108: return(0);
109: }
111: #undef __FUNCT__
113: static int PCDestroy_ESI(PC pc)
114: {
115: PC_ESI *jac = (PC_ESI*)pc->data;
116: int ierr;
119: jac->epc->deleteReference();
120: /*
121: Free the private data structure that was hanging off the PC
122: */
123: PetscFree(jac);
124: return(0);
125: }
127: #undef __FUNCT__
129: static int PCSetFromOptions_ESI(PC pc)
130: {
131: /*PC_ESI *jac = (PC_ESI*)pc->data;*/
132: int ierr;
135: PetscOptionsHead("ESI options");
136: PetscOptionsTail();
137: return(0);
138: }
140: extern PetscFList CCAList;
142: #undef __FUNCT__
144: /*@C
145: PCESISetType - Given a PETSc matrix of type ESI loads the ESI constructor
146: by name and wraps the ESI operator to look like a PETSc matrix.
148: Collective on PC
150: Input Parameters:
151: + V - preconditioner object
152: - name - name of the ESI constructor
154: Level: intermediate
156: @*/
157: int PCESISetType(PC V,char *name)
158: {
159: int ierr;
160: ::esi::Preconditioner<double,int> *ve;
161: ::esi::Preconditioner<double,int>::Factory *f,*(*r)(void);
164: PetscFListFind(V->comm,CCAList,name,(void(**)(void))&r);
165: if (!r) SETERRQ1(1,"Unable to load esi::PreconditionerFactory constructor %s",name);
166: f = (*r)();
168: f->create("MPI",(void*)&V->comm,ve);
169: delete f;
170: PCESISetPreconditioner(V,ve);
171: ve->deleteReference();
172: return(0);
173: }
175: #undef __FUNCT__
177: int PCESISetFromOptions(PC V)
178: {
179: char string[PETSC_MAX_PATH_LEN];
180: PetscTruth flg;
181: int ierr;
182:
184: PetscTypeCompare((PetscObject)V,PCESI,&flg);
185: if (flg) {
186: PetscOptionsGetString(V->prefix,"-pc_esi_type",string,1024,&flg);
187: if (flg) {
188: PCESISetType(V,string);
189: }
190: }
191: return(0);
192: }
194: EXTERN_C_BEGIN
195: #undef __FUNCT__
197: int PCCreate_ESI(PC pc)
198: {
199: PC_ESI *jac;
200: int ierr;
204: /*
205: Creates the private data structure for this preconditioner and
206: attach it to the PC object.
207: */
208: ierr = PetscNew(PC_ESI,&jac);
209: pc->data = (void*)jac;
211: /*
212: Logs the memory usage; this is not needed but allows PETSc to
213: monitor how much memory is being used for various purposes.
214: */
215: PetscLogObjectMemory(pc,sizeof(PC_ESI));
217: /*
218: Set the pointers for the functions that are provided above.
219: Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
220: are called, they will automatically call these functions. Note we
221: choose not to provide a couple of these functions since they are
222: not needed.
223: */
224: pc->ops->apply = PCApply_ESI;
225: pc->ops->applytranspose = 0;
226: pc->ops->setup = PCSetUp_ESI;
227: pc->ops->destroy = PCDestroy_ESI;
228: pc->ops->setfromoptions = PCSetFromOptions_ESI;
229: pc->ops->view = 0;
230: pc->ops->applyrichardson = 0;
231: pc->ops->applysymmetricleft = PCApplySymmetricLeft_ESI;
232: pc->ops->applysymmetricright = PCApplySymmetricRight_ESI;
233: return(0);
234: }
235: EXTERN_C_END
237: EXTERN_C_BEGIN
238: #undef __FUNCT__
240: int PCCreate_PetscESI(PC V)
241: {
242: int ierr;
243: PC v;
244: esi::petsc::Preconditioner<double,int> *ve;
247: V->ops->destroy = 0; /* since this is called from PCSetType() we have to make sure it doesn't get destroyed twice */
248: PCSetType(V,PCESI);
249: PCCreate(V->comm,&v);
250: PetscObjectSetOptionsPrefix((PetscObject)v,"esi_");
251: PCSetFromOptions(v);
252: ve = new esi::petsc::Preconditioner<double,int>(v);
253: PCESISetPreconditioner(V,ve);
254: ve->deleteReference();
255: PetscObjectDereference((PetscObject)v);
256: return(0);
257: }
258: EXTERN_C_END