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