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: /*@C
15: PCESISetPreconditioner - Takes a PETSc PC sets it to type ESI and
16: provides the ESI preconditioner that it wraps to look like a PETSc PC.
18: Input Parameter:
19: . xin - The Petsc PC
21: Output Parameter:
22: . v - The ESI preconditioner
24: Level: advanced
26: .keywords: PC, ESI
27: @*/
28: int PCESISetPreconditioner(PC xin,esi::Preconditioner<double,int> *v)
29: {
30: PC_ESI *x = (PC_ESI*)xin->data;
31: PetscTruth tesi;
32: int ierr;
35: PetscTypeCompare((PetscObject)xin,0,&tesi);
36: if (tesi) {
37: PCSetType(xin,PCESI);
38: }
39: PetscTypeCompare((PetscObject)xin,PCESI,&tesi);
40: if (tesi) {
41: x->epc = v;
42: v->addReference();
43: }
44: return(0);
45: }
47: #include esi/petsc/matrix.h
49: static int PCSetUp_ESI(PC pc)
50: {
51: PC_ESI *jac = (PC_ESI*)pc->data;
52: int ierr;
53: ::esi::Operator<double,int> *em;
56: MatESIWrap(pc->mat,&em);
57: jac->epc->setOperator(*em);
58: jac->epc->setup();
59: return(0);
60: }
62: static int PCApply_ESI(PC pc,Vec x,Vec y)
63: {
64: PC_ESI *jac = (PC_ESI*)pc->data;
65: esi::Vector<double,int> *xx,*yy;
66: int ierr;
69: VecESIWrap(x,&xx);
70: VecESIWrap(y,&yy);
71: jac->epc->solve(*xx,*yy);
72: return(0);
73: }
75: static int PCApplySymmetricLeft_ESI(PC pc,Vec x,Vec y)
76: {
77: int ierr;
78: PC_ESI *jac = (PC_ESI*)pc->data;
79: esi::Vector<double,int> *xx,*yy;
82: VecESIWrap(x,&xx);
83: VecESIWrap(y,&yy);
84: jac->epc->solveLeft(*xx,*yy);
85: return(0);
86: }
88: static int PCApplySymmetricRight_ESI(PC pc,Vec x,Vec y)
89: {
90: int ierr;
91: PC_ESI *jac = (PC_ESI*)pc->data;
92: esi::Vector<double,int> *xx,*yy;
95: VecESIWrap(x,&xx);
96: VecESIWrap(y,&yy);
97: jac->epc->solveRight(*xx,*yy);
98: return(0);
99: }
101: static int PCDestroy_ESI(PC pc)
102: {
103: PC_ESI *jac = (PC_ESI*)pc->data;
104: int ierr;
107: jac->epc->deleteReference();
108: /*
109: Free the private data structure that was hanging off the PC
110: */
111: PetscFree(jac);
112: return(0);
113: }
115: static int PCSetFromOptions_ESI(PC pc)
116: {
117: /*PC_ESI *jac = (PC_ESI*)pc->data;*/
118: int ierr;
121: PetscOptionsHead("ESI options");
122: PetscOptionsTail();
123: return(0);
124: }
126: extern PetscFList CCAList;
128: /*@C
129: PCESISetType - Given a PETSc matrix of type ESI loads the ESI constructor
130: by name and wraps the ESI operator to look like a PETSc matrix.
132: Collective on PC
134: Input Parameters:
135: + V - preconditioner object
136: - name - name of the ESI constructor
138: Level: intermediate
140: @*/
141: int PCESISetType(PC V,char *name)
142: {
143: int ierr;
144: ::esi::Preconditioner<double,int> *ve;
145: ::esi::Preconditioner<double,int>::Factory *f,*(*r)(void);
148: PetscFListFind(V->comm,CCAList,name,(void(**)(void))&r);
149: if (!r) SETERRQ1(1,"Unable to load esi::PreconditionerFactory constructor %s",name);
150: f = (*r)();
152: f->create("MPI",(void*)&V->comm,ve);
153: delete f;
154: PCESISetPreconditioner(V,ve);
155: ve->deleteReference();
156: return(0);
157: }
159: int PCESISetFromOptions(PC V)
160: {
161: char string[1024];
162: PetscTruth flg;
163: int ierr;
164:
166: PetscTypeCompare((PetscObject)V,PCESI,&flg);
167: if (flg) {
168: PetscOptionsGetString(V->prefix,"-pc_esi_type",string,1024,&flg);
169: if (flg) {
170: PCESISetType(V,string);
171: }
172: }
173: return(0);
174: }
176: EXTERN_C_BEGIN
177: int PCCreate_ESI(PC pc)
178: {
179: PC_ESI *jac;
180: int ierr;
184: /*
185: Creates the private data structure for this preconditioner and
186: attach it to the PC object.
187: */
188: ierr = PetscNew(PC_ESI,&jac);
189: pc->data = (void*)jac;
191: /*
192: Logs the memory usage; this is not needed but allows PETSc to
193: monitor how much memory is being used for various purposes.
194: */
195: PetscLogObjectMemory(pc,sizeof(PC_ESI));
197: /*
198: Set the pointers for the functions that are provided above.
199: Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
200: are called, they will automatically call these functions. Note we
201: choose not to provide a couple of these functions since they are
202: not needed.
203: */
204: pc->ops->apply = PCApply_ESI;
205: pc->ops->applytranspose = 0;
206: pc->ops->setup = PCSetUp_ESI;
207: pc->ops->destroy = PCDestroy_ESI;
208: pc->ops->setfromoptions = PCSetFromOptions_ESI;
209: pc->ops->view = 0;
210: pc->ops->applyrichardson = 0;
211: pc->ops->applysymmetricleft = PCApplySymmetricLeft_ESI;
212: pc->ops->applysymmetricright = PCApplySymmetricRight_ESI;
213: return(0);
214: }
215: EXTERN_C_END
217: EXTERN_C_BEGIN
218: int PCCreate_PetscESI(PC V)
219: {
220: int ierr;
221: PC v;
222: esi::petsc::Preconditioner<double,int> *ve;
225: V->ops->destroy = 0; /* since this is called from PCSetType() we have to make sure it doesn't get destroyed twice */
226: PCSetType(V,PCESI);
227: PCCreate(V->comm,&v);
228: PetscObjectSetOptionsPrefix((PetscObject)v,"esi_");
229: PCSetFromOptions(v);
230: ve = new esi::petsc::Preconditioner<double,int>(v);
231: PCESISetPreconditioner(V,ve);
232: ve->deleteReference();
233: PetscObjectDereference((PetscObject)v);
234: return(0);
235: }
236: EXTERN_C_END