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