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