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: }