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