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: static int PCSetUp_ESI(PC pc)
48: {
49: PC_ESI *jac = (PC_ESI*)pc->data;
50: int ierr;
53: jac->epc->setup();
54: return(0);
55: }
57: static int PCApply_ESI(PC pc,Vec x,Vec y)
58: {
59: PC_ESI *jac = (PC_ESI*)pc->data;
60: esi::Vector<double,int> *xx,*yy;
61: int ierr;
64: VecESIWrap(x,&xx);
65: VecESIWrap(y,&yy);
66: jac->epc->solve(*xx,*yy);
67: return(0);
68: }
70: static int PCApplySymmetricLeft_ESI(PC pc,Vec x,Vec y)
71: {
72: int ierr;
73: PC_ESI *jac = (PC_ESI*)pc->data;
74: esi::Vector<double,int> *xx,*yy;
77: VecESIWrap(x,&xx);
78: VecESIWrap(y,&yy);
79: jac->epc->solveLeft(*xx,*yy);
80: return(0);
81: }
83: static int PCApplySymmetricRight_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->solveRight(*xx,*yy);
93: return(0);
94: }
96: static int PCDestroy_ESI(PC pc)
97: {
98: PC_ESI *jac = (PC_ESI*)pc->data;
99: int ierr;
102: jac->epc->deleteReference();
103: /*
104: Free the private data structure that was hanging off the PC
105: */
106: PetscFree(jac);
107: return(0);
108: }
110: static int PCSetFromOptions_ESI(PC pc)
111: {
112: /*PC_ESI *jac = (PC_ESI*)pc->data;*/
113: int ierr;
116: PetscOptionsHead("ESI options");
117: PetscOptionsTail();
118: return(0);
119: }
121: EXTERN_C_BEGIN
122: int PCCreate_ESI(PC pc)
123: {
124: PC_ESI *jac;
125: int ierr;
129: /*
130: Creates the private data structure for this preconditioner and
131: attach it to the PC object.
132: */
133: ierr = PetscNew(PC_ESI,&jac);
134: pc->data = (void*)jac;
136: /*
137: Logs the memory usage; this is not needed but allows PETSc to
138: monitor how much memory is being used for various purposes.
139: */
140: PetscLogObjectMemory(pc,sizeof(PC_ESI));
142: /*
143: Set the pointers for the functions that are provided above.
144: Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
145: are called, they will automatically call these functions. Note we
146: choose not to provide a couple of these functions since they are
147: not needed.
148: */
149: pc->ops->apply = PCApply_ESI;
150: pc->ops->applytranspose = 0;
151: pc->ops->setup = PCSetUp_ESI;
152: pc->ops->destroy = PCDestroy_ESI;
153: pc->ops->setfromoptions = PCSetFromOptions_ESI;
154: pc->ops->view = 0;
155: pc->ops->applyrichardson = 0;
156: pc->ops->applysymmetricleft = PCApplySymmetricLeft_ESI;
157: pc->ops->applysymmetricright = PCApplySymmetricRight_ESI;
158: return(0);
159: }
160: EXTERN_C_END
162: EXTERN_C_BEGIN
163: int PCCreate_PetscESI(PC V)
164: {
165: int ierr;
166: PC v;
167: esi::petsc::Preconditioner<double,int> *ve;
170: V->ops->destroy = 0; /* since this is called from MatSetType() we have to make sure it doesn't get destroyed twice */
171: PCSetType(V,PCESI);
172: PCCreate(V->comm,&v);
173: PCSetType(v,PCNONE);
174: ve = new esi::petsc::Preconditioner<double,int>(v);
175: PCESISetPreconditioner(V,ve);
176: ve->deleteReference();
177: PetscObjectDereference((PetscObject)v);
178: return(0);
179: }
180: EXTERN_C_END