Actual source code: ebvec1.c



  4: /*$Id: ebvec1.c,v 1.9 2001/09/26 17:10:29 balay Exp $*/


 7:  #include src/vec/vecimpl.h
 8:  #include src/vec/impls/dvecimpl.h
 9:  #include esi/petsc/vector.h

 11: typedef struct {
 12:   ::esi::Vector<double,int> *evec;
 13: } Vec_ESI;

 15: /*
 16:     Wraps a PETSc vector to look like an ESI vector and stashes the wrapper inside the
 17:   PETSc vector. If PETSc vector already had wrapper uses that instead.
 18: */
 19: int VecESIWrap(Vec xin,::esi::Vector<double,int> **v)
 20: {
 21:   esi::petsc::Vector<double,int> *t;
 22:   int                             ierr;

 25:   if (!xin->esivec) {
 26:     t = new esi::petsc::Vector<double,int>(xin);
 27:     t->getInterface("esi::Vector",xin->esivec);
 28:   }
 29:   *v = reinterpret_cast<esi::Vector<double,int>* >(xin->esivec);
 30:   return(0);
 31: }

 33: /*@C
 34:   VecESISetVector - Takes a PETSc vector sets it to type ESI and 
 35:   provides the ESI vector that it wraps to look like a PETSc vector.

 37:   Level: intermediate

 39: @*/
 40:  int VecESISetVector(Vec xin,::esi::Vector<double,int> *v)
 41: {
 42:   Vec_ESI    *x;
 43:   PetscTruth tesi;
 44:   int        ierr;

 47:   PetscTypeCompare((PetscObject)xin,0,&tesi);
 48:   if (tesi) {
 49:     VecSetType(xin,VECESI);
 50:   }
 51:   PetscTypeCompare((PetscObject)xin,VECESI,&tesi);
 52:   if (tesi) {
 53:     int                      n,N;
 54:     ::esi::IndexSpace<int>   *map;

 56:     v->getGlobalSize(N);
 57:     if (xin->N == -1) xin->N = N;
 58:     else if (xin->N != N) SETERRQ2(1,"Global size of Vec %d not equal size of esi::Vector %d",xin->N,N);

 60:     v->getIndexSpace(map);
 61:     map->getLocalSize(n);
 62:     if (xin->n == -1) xin->n = n;
 63:     else if (xin->n != n) SETERRQ2(1,"Local size of Vec %d not equal size of esi::Vector %d",xin->n,n);

 65:     x       = (Vec_ESI*)xin->data;
 66:     x->evec = v;
 67:     v->addReference();
 68:     if (!xin->map){
 69:       PetscMapCreateMPI(xin->comm,n,N,&xin->map);
 70:     }
 71:     VecStashCreate_Private(xin->comm,1,&xin->stash);
 72:     VecStashCreate_Private(xin->comm,xin->bs,&xin->bstash);
 73:     (v)->getInterface("esi::Vector",xin->esivec);
 74:   }
 75:   return(0);
 76: }

 78: /* ---------------------------------------------------------------------------------*/

 80: int VecPlaceArray_ESI(Vec vin,const PetscScalar *a)
 81: {
 82:   Vec_ESI                                *v = (Vec_ESI *)vin->data;
 83:   ::esi::VectorReplaceAccess<double,int> *vr;
 84:   int                                    ierr;

 87:   v->evec->getInterface("esi::VectorReplaceAccess",reinterpret_cast<void *&>(vr));
 88:   vr->setArrayPointer((PetscScalar*)a,vin->n);
 89:   return(0);
 90: }

 92: int VecSet_ESI(const PetscScalar *alpha,Vec xin)
 93: {
 94:   Vec_ESI *x = (Vec_ESI*)xin->data;
 95:   int     ierr;

 98:   x->evec->put(*alpha);
 99:   return(0);
100: }

102: int VecDuplicate_ESI(Vec xin,Vec *xout)
103: {
104:   Vec_ESI                   *x = (Vec_ESI*)xin->data;
105:   int                       ierr;
106:   ::esi::Vector<double,int> *nevec;

109:   VecCreate(xin->comm,xout);
110:   VecSetSizes(*xout,xin->n,xin->N);
111:   x->evec->clone(nevec);
112:   VecESISetVector(*xout,nevec);
113:   nevec->deleteReference();
114:   return(0);
115: }

117: int VecDot_ESI(Vec xin,Vec yin,PetscScalar *z)
118: {
119:   Vec_ESI                   *x = (Vec_ESI*)xin->data;
120:   int                       ierr;
121:   ::esi::Vector<double,int> *ytmp;

124:   /* Make yin look like an esi:Vector */
125:   VecESIWrap(yin,&ytmp);
126:   x->evec->dot(*ytmp,*z);
127:   return(0);
128: }

130: int VecAXPY_ESI(const PetscScalar *a,Vec xin,Vec yin)
131: {
132:   Vec_ESI                   *x = (Vec_ESI*)xin->data;
133:   int                       ierr;
134:   ::esi::Vector<double,int> *ytmp;

137:   /* Make yin look like an esi:Vector */
138:   VecESIWrap(yin,&ytmp);
139:   ytmp->axpy(*x->evec,*a);
140:   return(0);
141: }

143: int VecAYPX_ESI(const PetscScalar *a,Vec xin,Vec yin)
144: {
145:   Vec_ESI                   *x = (Vec_ESI*)xin->data;
146:   int                       ierr;
147:   ::esi::Vector<double,int> *ytmp;

150:   /* Make yin look like an esi:Vector */
151:   VecESIWrap(yin,&ytmp);
152:   ytmp->aypx(*a,*x->evec);
153:   return(0);
154: }

156: int VecWAXPY_ESI(const PetscScalar *a,Vec xin,Vec yin,Vec win)
157: {
158:   Vec_ESI                   *x = (Vec_ESI*)xin->data;
159:   int                       ierr;
160:   ::esi::Vector<double,int> *ytmp,*wtmp;

163:   /* Make yin look like an esi:Vector */
164:   VecESIWrap(yin,&ytmp);
165:   VecESIWrap(win,&wtmp);
166:   wtmp->axpby(*a,*x->evec,1.0,*ytmp);
167:   return(0);
168: }

170: int VecCopy_ESI(Vec xin,Vec yin)
171: {
172:   Vec_ESI                   *x = (Vec_ESI*)xin->data;
173:   int                       ierr;
174:   ::esi::Vector<double,int> *ytmp;

177:   if (xin != yin) {
178:     /* Make yin look like an esi:Vector */
179:     VecESIWrap(yin,&ytmp);
180:     ytmp->copy(*x->evec);
181:   }
182:   return(0);
183: }

185: int VecPointwiseMult_ESI(Vec xin,Vec yin,Vec zin)
186: {
187:   Vec_ESI                   *x = (Vec_ESI*)xin->data;
188:   int                       ierr;
189:   ::esi::Vector<double,int> *ztmp;

192:   if (zin != yin) {
193:     VecCopy(yin,zin);
194:   }

196:   /* Make zin look like an esi:Vector */
197:   VecESIWrap(zin,&ztmp);
198:   ztmp->scaleDiagonal(*x->evec);
199:   return(0);
200: }

202: int VecPointwiseDivide_ESI(Vec xin,Vec yin,Vec win)
203: {
204:   int          n = xin->n,i,ierr;
205:   PetscScalar  *xx,*yy,*ww;

208:   VecGetArrayFast(yin,&yy);
209:   if (yin != xin) {VecGetArrayFast(xin,&xx);}
210:   else xx = yy;
211:   if (yin != win) {VecGetArrayFast(win,&ww);}
212:   else ww = yy;
213:   for (i=0; i<n; i++) ww[i] = xx[i] / yy[i];
214:   VecRestoreArrayFast(yin,&yy);
215:   if (yin != win) {VecRestoreArrayFast(win,&ww);}
216:   if (xin != win) {VecRestoreArrayFast(xin,&xx);}
217:   return(0);
218: }

220:  #include petscblaslapack.h
221: /*
222:     ESI does not provide a method for this 
223: */
224: int VecSwap_ESI(Vec xin,Vec yin)
225: {

229:   if (xin != yin) {
230:     PetscScalar *ya,*xa;
231:     int         one = 1;

233:     VecGetArrayFast(yin,&ya);
234:     VecGetArrayFast(xin,&xa);
235:     BLswap_(&xin->n,xa,&one,ya,&one);
236:     VecRestoreArrayFast(xin,&xa);
237:     VecRestoreArrayFast(yin,&ya);
238:   }
239:   return(0);
240: }

242: int VecMDot_ESI(int nv,Vec xin,const Vec yin[],PetscScalar *z)
243: {
244:   Vec_ESI                   *x = (Vec_ESI *)xin->data;
245:   int                       ierr,i;
246:   ::esi::Vector<double,int> *ytmp;

249:   for (i=0; i<nv; i++) {
250:     /* Make yin look like an esi:Vector */
251:     VecESIWrap(yin[i],&ytmp);
252:     x->evec->dot(*ytmp,z[i]);
253:   }
254:   return(0);
255: }


258: int VecMAXPY_ESI(int nv,const PetscScalar *a,Vec xin, Vec yin[])
259: {
260:   Vec_ESI                   *x = (Vec_ESI *)xin->data;
261:   int                       ierr,i;
262:   ::esi::Vector<double,int> *ytmp;

265:   for (i=0; i<nv; i++) {
266:     /* Make yin look like an esi:Vector */
267:     VecESIWrap(yin[i],&ytmp);
268:     x->evec->axpy(*ytmp,a[i]);
269:   }
270:   return(0);
271: }


274: int VecGetSize_ESI(Vec vin,int *size)
275: {
276:   Vec_ESI *x = (Vec_ESI*)vin->data;
277:   int     ierr;

280:   x->evec->getGlobalSize(*size);
281:   return(0);
282: }

284: int VecGetLocalSize_ESI(Vec vin,int *size)
285: {
286:   Vec_ESI                  *x = (Vec_ESI*)vin->data;
287:   int                      ierr;
288:   ::esi::IndexSpace<int>   *map;

291:   x->evec->getIndexSpace(map);
292:   map->getLocalSize(*size);
293:   return(0);
294: }

296: int VecGetArray_ESI(Vec vin,PetscScalar **array)
297: {
298:   Vec_ESI *x = (Vec_ESI*)vin->data;
299:   int     ierr;

302:   x->evec->getCoefPtrReadWriteLock(*array);
303:   return(0);
304: }

306: int VecRestoreArray_ESI(Vec vin,PetscScalar **array)
307: {
308:   Vec_ESI *x = (Vec_ESI*)vin->data;
309:   int     ierr;

312:   x->evec->releaseCoefPtrLock(*array);
313:   return(0);
314: }

316: int VecScale_ESI(const PetscScalar *array,Vec vin)
317: {
318:   Vec_ESI *x = (Vec_ESI*)vin->data;
319:   int     ierr;

322:   x->evec->scale(*array);
323:   return(0);
324: }

326: int VecNorm_ESI(Vec vin,NormType ntype,PetscReal *norm)
327: {
328:   Vec_ESI *x = (Vec_ESI*)vin->data;
329:   int     ierr;

332:   if (ntype == NORM_2) {
333:     x->evec->norm2(*norm);
334:   } else if (ntype == NORM_1) {
335:     x->evec->norm1(*norm);
336:   } else if (ntype == NORM_INFINITY) {
337:     x->evec->normInfinity(*norm);
338:   } else SETERRQ1(1,"Unknown NormType %d",ntype);
339:   return(0);
340: }

342: extern int VecSetValues_MPI(Vec,int,const int[],const PetscScalar[],InsertMode);
343: extern int VecAssemblyBegin_MPI(Vec);
344: extern int VecAssemblyEnd_MPI(Vec);
345: extern int VecView_MPI(Vec,PetscViewer);
346: extern int VecReciprocal_Default(Vec);
347: extern int VecSetRandom_Seq(PetscRandom,Vec);
348: extern int VecSetValuesBlocked_MPI(Vec,int,const int[],const PetscScalar[],InsertMode);
349: extern int VecMax_MPI(Vec,int*,PetscReal*);
350: extern int VecMin_MPI(Vec,int*,PetscReal*);

352: /* ---------------------------------------------------------------------------------*/

354: int VecDestroy_ESI(Vec v)
355: {
356:   Vec_ESI *vs = (Vec_ESI*)v->data;
357:   int     ierr;

360:   if (vs->evec) {
361:     vs->evec->deleteReference();
362:   }
363:   VecStashDestroy_Private(&v->bstash);
364:   VecStashDestroy_Private(&v->stash);
365:   PetscFree(vs);
366:   return(0);
367: }

369: EXTERN_C_BEGIN
370: int VecCreate_PetscESI(Vec V)
371: {
372:   int                            ierr;
373:   Vec                            v;
374:   esi::petsc::Vector<double,int> *ve;

377:   V->ops->destroy = 0;  /* since this is called from VecSetType() we have to make sure it doesn't get destroyed twice */
378:   VecSetType(V,VECESI);
379:   VecCreate(V->comm,&v);
380:   VecSetSizes(v,V->n,V->N);
381:   if (V->bs > 1) {VecSetBlockSize(v,V->bs);}
382:   PetscObjectSetOptionsPrefix((PetscObject)v,"esi_");
383:   VecSetFromOptions(v);
384:   ve   = new esi::petsc::Vector<double,int>(v);
385:   VecESISetVector(V,ve);
386:   ve->deleteReference();
387:   PetscObjectDereference((PetscObject)v);
388:   return(0);
389: }
390: EXTERN_C_END

392: static struct _VecOps EvOps = {VecDuplicate_ESI,
393:                                VecDuplicateVecs_Default,
394:                                VecDestroyVecs_Default,
395:                                VecDot_ESI,
396:                                VecMDot_ESI,
397:                                VecNorm_ESI,
398:                                0,
399:                                0,
400:                                VecScale_ESI,
401:                                VecCopy_ESI,
402:                                VecSet_ESI,
403:                                VecSwap_ESI,
404:                                VecAXPY_ESI,
405:                                0,
406:                                VecMAXPY_ESI,
407:                                VecAYPX_ESI,
408:                                VecWAXPY_ESI,
409:                                VecPointwiseMult_ESI,
410:                                VecPointwiseDivide_ESI,
411:                                VecSetValues_MPI,
412:                                VecAssemblyBegin_MPI,
413:                                VecAssemblyEnd_MPI,
414:                                VecGetArray_ESI,
415:                                VecGetSize_ESI,
416:                                VecGetLocalSize_ESI,
417:                                VecRestoreArray_ESI,
418:                                VecMax_MPI,
419:                                VecMin_MPI,
420:                                VecSetRandom_Seq,
421:                                0,
422:                                VecSetValuesBlocked_MPI,
423:                                VecDestroy_ESI,
424:                                VecView_MPI,
425:                                VecPlaceArray_ESI,
426:                                0,
427:                                VecDot_Seq,
428:                                VecTDot_Seq,
429:                                VecNorm_Seq,
430:                                0,
431:                                VecReciprocal_Default};

433: int VecESISetFromOptions(Vec V)
434: {
435:   char       string[1024];
436:   PetscTruth flg;
437:   int        ierr;
438: 
440:   PetscTypeCompare((PetscObject)V,VECESI,&flg);
441:   if (flg) {
442:     PetscOptionsGetString(V->prefix,"-vec_esi_type",string,1024,&flg);
443:     if (flg) {
444:       VecESISetType(V,string);
445:     }
446:   }
447:   return(0);
448: }


451: EXTERN_C_BEGIN
452: int VecCreate_ESI(Vec V)
453: {
454:   Vec_ESI *s;
455:   int     ierr;
456: 
458:   ierr    = PetscNew(Vec_ESI,&s);
459:   ierr    = PetscMemzero(s,sizeof(Vec_ESI));

461:   s->evec        = 0;
462:   V->data        = (void*)s;
463:   V->petscnative = PETSC_FALSE;
464:   V->esivec      = 0;
465:   ierr           = PetscMemcpy(V->ops,&EvOps,sizeof(EvOps));
466:   return(0);
467: }
468: EXTERN_C_END

470: extern PetscFList CCAList;

472: /*@C
473:   ESICreateIndexSpace - Creates an esi::IndexSpace using the -is_esi_type type 

475:   Level: beginner
476:     
477: @*/
478: int ESICreateIndexSpace(const char * commname,void *comm,int m,::esi::IndexSpace<int>*&v)
479: {
480:   int                             ierr;
481:   ::esi::IndexSpace<int>::Factory *f;
482:   ::esi::IndexSpace<int>::Factory *(*r)(void);
483:   char                            name[1024];
484:   PetscTruth                      found;

487:   PetscOptionsGetString(PETSC_NULL,"-is_esi_type",name,1024,&found);
488:   if (!found) {
489:     PetscStrcpy(name,"esi::petsc::IndexSpace");
490:   }
491:   PetscFListFind(*(MPI_Comm*)comm,CCAList,name,(void(**)(void))&r);
492:   if (!r) SETERRQ1(1,"Unable to load esi::IndexSpace Factory constructor %s",name);
493:   f    = (*r)();
494:   f->create(commname,comm,m,PETSC_DECIDE,PETSC_DECIDE,v);
495:   delete f;
496:   return(0);
497: }

499: /*@C
500:     VecESISetType - Given a PETSc vector of type ESI loads the ESI constructor
501:           by name and wraps the ESI vector to look like a PETSc vector.

503:   Level: intermediate
504: @*/
505: int VecESISetType(Vec V,char *name)
506: {
507:   int                                ierr;
508:   ::esi::Vector<double,int>          *ve;
509:   ::esi::Vector<double,int>::Factory *f,*(*r)(void);
510:   ::esi::IndexSpace<int>             *map;

513:   PetscFListFind(V->comm,CCAList,name,(void(**)(void))&r);
514:   if (!r) SETERRQ1(1,"Unable to load esi::VectorFactory constructor %s",name);
515:   f    = (*r)();
516:   if (V->n == PETSC_DECIDE) {
517:     PetscSplitOwnership(V->comm,&V->n,&V->N);
518:   }
519:   ESICreateIndexSpace("MPI",&V->comm,V->n,map);
520:   f->create(*map,ve);
521:   map->deleteReference();
522:   delete f;
523:   VecESISetVector(V,ve);
524:   ve->deleteReference();
525:   return(0);
526: }

528: /*@C
529:     ESILoadFactory - Creates an object for any ESI factory class. Generally does
530:           this by dynamicly loading the constructor.

532:      Collective on MPI_Comm

534:     Input Parameters:
535: +     commname - name of parallel context; currently only "MPI" is supported
536: .     comm - communicator for parallel computing model, currently only MPI_Comm's are supported
537: -     name - name of class the factory constructs, for example "esi::petsc::Vector"

539:     Output Parameter:
540: .     f - the factory object

542:     Notes: The name of the class is the name of the class the factory CONSTRUCTS, not the name
543:            of the factory class

545:   Level: intermediate
546: @*/
547: int ESILoadFactory(char *commname,void *comm,char *classname,void *&f)
548: {
549:   int           ierr;
550:   void          *(*r)();
551:   PetscTruth    flag;

554:   PetscStrcmp(commname,"MPI",&flag);
555:   if (!flag) SETERRQ1(1,"Parallel computing model %s not supported",commname);
556:   PetscFListFind(*(MPI_Comm*)comm,CCAList,classname,(void(**)(void))&r);
557:   if (!r) SETERRQ1(1,"Unable to load constructor %s",classname);
558:   f    = (*r)();
559:   return(0);
560: }