Actual source code: ebvec1.c

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


 5:  #include src/vec/vecimpl.h
 6:  #include src/vec/impls/dvecimpl.h
 7:  #include esi/petsc/vector.h

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

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

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

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

 35:   Level: intermediate

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

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

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

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

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

 76: /* ---------------------------------------------------------------------------------*/

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

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

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

 96:   x->evec->put(*alpha);
 97:   return(0);
 98: }

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

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

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

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

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

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

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

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

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

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

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

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

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

190:   if (zin != yin) {
191:     VecCopy(yin,zin);
192:   }

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

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

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

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

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

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

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

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


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

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


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

278:   x->evec->getGlobalSize(*size);
279:   return(0);
280: }

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

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

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

300:   x->evec->getCoefPtrReadWriteLock(*array);
301:   return(0);
302: }

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

310:   x->evec->releaseCoefPtrLock(*array);
311:   return(0);
312: }

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

320:   x->evec->scale(*array);
321:   return(0);
322: }

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

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

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

350: /* ---------------------------------------------------------------------------------*/

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

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

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

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

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

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


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

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

467: extern PetscFList CCAList;

469: /*@C
470:   ESICreateIndexSpace - Creates an esi::IndexSpace using the -is_esi_type type 

472:   Level: beginner
473:     
474: @*/
475: int ESICreateIndexSpace(const char * commname,void *comm,int m,::esi::IndexSpace<int>*&v)
476: {
477:   int                           ierr;
478:   ::esi::IndexSpaceFactory<int> *f;
479: #if defined(PETSC_HAVE_CCA)
480:   ::gov::cca::Component         *(*r)(void);
481: #else
482:   ::esi::IndexSpaceFactory<int> *(*r)(void);
483: #endif
484:   char                          name[1024];
485:   PetscTruth                    found;

488:   PetscOptionsGetString(PETSC_NULL,"-is_esi_type",name,1024,&found);
489:   if (!found) {
490:     PetscStrcpy(name,"esi::petsc::IndexSpace");
491:   }
492:   PetscFListFind(*(MPI_Comm*)comm,CCAList,name,(void(**)(void))&r);
493:   if (!r) SETERRQ1(1,"Unable to load esi::IndexSpace Factory constructor %s",name);
494: #if defined(PETSC_HAVE_CCA)
495:   gov::cca::Component *component = (*r)();
496:   gov::cca::Port      *port      = dynamic_cast<gov::cca::Port*>(component);
497:   f    = dynamic_cast<esi::IndexSpaceFactory<int>*>(port);
498: #else
499:   f    = (*r)();
500: #endif
501:   f->getIndexSpace(commname,comm,m,v);
502:   delete f;
503:   return(0);
504: }

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

510:   Level: intermediate
511: @*/
512: int VecESISetType(Vec V,char *name)
513: {
514:   int                              ierr;
515:   ::esi::Vector<double,int>        *ve;
516:   ::esi::VectorFactory<double,int> *f;
517: #if defined(PETSC_HAVE_CCA)
518:   ::gov::cca::Component            *(*r)(void);
519: #else
520:   ::esi::VectorFactory<double,int> *(*r)(void);
521: #endif
522:   ::esi::IndexSpace<int>           *map;

525:   PetscFListFind(V->comm,CCAList,name,(void(**)(void))&r);
526:   if (!r) SETERRQ1(1,"Unable to load esi::VectorFactory constructor %s",name);
527: #if defined(PETSC_HAVE_CCA)
528:   gov::cca::Component *component = (*r)();
529:   gov::cca::Port      *port      = dynamic_cast<gov::cca::Port*>(component);
530:   f    = dynamic_cast<esi::VectorFactory<double,int>*>(port);
531: #else
532:   f    = (*r)();
533: #endif
534:   if (V->n == PETSC_DECIDE) {
535:     PetscSplitOwnership(V->comm,&V->n,&V->N);
536:   }
537:   ESICreateIndexSpace("MPI",&V->comm,V->n,map);
538:   f->getVector(*map,ve);
539:   map->deleteReference();
540:   delete f;
541:   VecESISetVector(V,ve);
542:   ve->deleteReference();
543:   return(0);
544: }