Actual source code: veccomp.c
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-2010, Universidad Politecnica de Valencia, Spain
6: This file is part of SLEPc.
7:
8: SLEPc is free software: you can redistribute it and/or modify it under the
9: terms of version 3 of the GNU Lesser General Public License as published by
10: the Free Software Foundation.
12: SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
13: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14: FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15: more details.
17: You should have received a copy of the GNU Lesser General Public License
18: along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
19: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
20: */
22: #include "petscmat.h"
23: #include "private/vecimpl.h" /*I "petscvec.h" I*/
24: #include "veccomp_private.h"
25: #include slepcvec.h
27: typedef struct {
28: PetscInt n, /* number of active subvectors */
29: N, /* virtual global size */
30: lN, /* virtual local size */
31: friends; /* number of vectors sharing this structure */
32: } Vec_Comp_N;
34: typedef struct {
35: Vec *x; /* the vectors */
36: PetscInt nx; /* number of available subvectors */
37: Vec_Comp_N *n; /* structure shared by friend vectors */
38: } Vec_Comp;
40: #if defined(PETSC_USE_DEBUG)
42: if (((Vec_Comp*)(x)->data)->nx < ((Vec_Comp*)(x)->data)->n->n) { \
43: return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,1,0,"Invalid number of subvectors required!");}
44: #else
46: #endif
48: static PetscErrorCode VecCreate_Comp_Private(Vec v, Vec *x, PetscInt nx,
49: PetscTruth x_to_me, Vec_Comp_N* n);
51: #include "veccomp0.h"
54: #include "veccomp0.h"
58: PetscErrorCode PETSCVEC_DLLEXPORT VecRegister_Comp(const char path[])
59: {
64: VecRegisterDynamic(VECCOMP, path, "VecCreate_Comp", VecCreate_Comp);
65:
67: return(0);
68: }
73: PetscErrorCode VecDestroy_Comp(Vec v)
74: {
75: Vec_Comp *vs = (Vec_Comp*)v->data;
76: PetscInt i;
81: /* if memory was published with AMS then destroy it */
82: PetscObjectDepublish(v);
84: #if defined(PETSC_USE_LOG)
85: PetscLogObjectState((PetscObject)v,"Length=%D",v->map->n);
86: #endif
87: for(i=0; i<vs->nx; i++) {
88: VecDestroy(vs->x[i]);
89: }
90: if(--vs->n->friends <= 0) {
91: PetscFree(vs->n);
92: }
93: PetscFree(vs->x);
94: PetscFree(vs);
96: return(0);
97: }
100: static struct _VecOps DvOps = {VecDuplicate_Comp, /* 1 */
101: VecDuplicateVecs_Default,
102: VecDestroyVecs_Default,
103: VecDot_Comp_MPI,
104: VecMDot_Comp_MPI,
105: VecNorm_Comp_MPI,
106: 0,
107: 0,
108: VecScale_Comp,
109: VecCopy_Comp, /* 10 */
110: VecSet_Comp,
111: VecSwap_Comp,
112: VecAXPY_Comp,
113: VecAXPBY_Comp,
114: VecMAXPY_Comp,
115: VecAYPX_Comp,
116: VecWAXPY_Comp,
117: VecAXPBYPCZ_Comp,
118: VecPointwiseMult_Comp,
119: VecPointwiseDivide_Comp,
120: 0, /* 20 */
121: 0,0,
122: 0 /*VecGetArray_Seq*/,
123: VecGetSize_Comp,
124: VecGetLocalSize_Comp,
125: 0/*VecRestoreArray_Seq*/,
126: VecMax_Comp,
127: VecMin_Comp,
128: VecSetRandom_Comp,
129: 0, /* 30 */
130: 0,
131: VecDestroy_Comp,
132: VecView_Comp,
133: 0/*VecPlaceArray_Seq*/,
134: 0/*VecReplaceArray_Seq*/,
135: VecDot_Comp_Seq,
136: 0,
137: VecNorm_Comp_Seq,
138: VecMDot_Comp_Seq,
139: 0, /* 40 */
140: 0,
141: 0, /* VecLoadIntoVectorNative */
142: VecReciprocal_Comp,
143: 0, /* VecViewNative */
144: VecConjugate_Comp,
145: 0,0,
146: 0/*VecResetArray_Seq*/,
147: 0,
148: VecMaxPointwiseDivide_Comp,
149: 0/*VecLoad_Binary*/, /* 50 */
150: VecPointwiseMax_Comp,
151: VecPointwiseMaxAbs_Comp,
152: VecPointwiseMin_Comp,
153: 0,
154: VecSqrt_Comp,
155: VecAbs_Comp,
156: VecExp_Comp,
157: VecLog_Comp,
158: 0/*VecShift_Comp*/,
159: 0,
160: VecDotNorm2_Comp_MPI
161: };
165: static PetscErrorCode VecCreate_Comp_Private(Vec v, Vec *x, PetscInt nx,
166: PetscTruth x_to_me, Vec_Comp_N *n)
167: {
168: Vec_Comp *s;
169: PetscErrorCode ierr;
170: PetscInt N=0, lN=0, i, k;
174: /* Allocate a new Vec_Comp */
175: if (v->data) { PetscFree(v->data); }
176: PetscNewLog(v, Vec_Comp, &s);
177: PetscMemcpy(v->ops, &DvOps, sizeof(DvOps));
178: v->data = (void*)s;
179: v->petscnative = PETSC_FALSE;
181: /* Allocate the array of Vec, if it is needed to be done */
182: if (x_to_me != PETSC_TRUE) {
183: PetscMalloc(sizeof(Vec)*nx, &s->x);
184: PetscMemcpy(s->x, x, sizeof(Vec)*nx);
185: } else
186: s->x = x;
188: s->nx = nx;
189: for(i=0; i<nx; i++) {
190: VecGetSize(x[i], &k); N+= k;
191: VecGetLocalSize(x[i], &k); lN+= k;
192: }
193:
194: /* Allocate the shared structure, if it is not given */
195: if (!n) {
196: PetscNewLog(v, Vec_Comp_N, &n);
197: s->n = n;
198: n->n = nx;
199: n->N = N;
200: n->lN = lN;
201: n->friends = 1;
202: }
204: /* If not, check in the vector in the shared structure */
205: else {
206: s->n = n;
207: s->n->friends++;
208: s->n->n = nx;
209: }
211: /* Set the virtual sizes as the real sizes of the vector */
212: VecSetSizes(v, s->n->lN, s->n->N);
214: PetscObjectChangeTypeName((PetscObject)v,VECCOMP);
215: PetscPublishAll(v);
217: return(0);
218: }
224: PetscErrorCode PETSCVEC_DLLEXPORT VecCreate_Comp(Vec V)
225: {
226: PetscErrorCode ierr;
230: VecCreate_Comp_Private(V, PETSC_NULL, 0, PETSC_FALSE, PETSC_NULL);
231:
233: return(0);
234: }
240: PetscErrorCode PETSCVEC_DLLEXPORT VecCreateComp(MPI_Comm comm, PetscInt *Nx,
241: PetscInt n, const VecType t,
242: Vec Vparent, Vec *V)
243: {
244: PetscErrorCode ierr;
245: Vec *x;
246: PetscInt i;
250: VecCreate(comm, V);
251: PetscMalloc(sizeof(Vec)*n, &x);
252: for(i=0; i<n; i++) {
253: VecCreate(comm, &x[i]);
254: VecSetSizes(x[i], PETSC_DECIDE, Nx[i]);
255: VecSetType(x[i], t);
256: }
257: VecCreate_Comp_Private(*V, x, n, PETSC_TRUE,
258: Vparent?((Vec_Comp*)Vparent->data)->n:PETSC_NULL);
259:
261: return(0);
262: }
266: PetscErrorCode PETSCVEC_DLLEXPORT VecCreateCompWithVecs(Vec *x, PetscInt n,
267: Vec Vparent, Vec *V)
268: {
269: PetscErrorCode ierr;
270: PetscInt i;
274: VecCreate(((PetscObject)x[0])->comm, V);
275: for(i=0; i<n; i++) {
276: PetscObjectReference((PetscObject)x[i]);
277: }
278: VecCreate_Comp_Private(*V, x, n, PETSC_FALSE,
279: Vparent?((Vec_Comp*)Vparent->data)->n:PETSC_NULL);
280:
282: return(0);
283: }
288: PetscErrorCode VecDuplicate_Comp(Vec win, Vec *V)
289: {
290: PetscErrorCode ierr;
291: Vec *x;
292: PetscInt i;
293: Vec_Comp *s = (Vec_Comp*)win->data;
299: VecCreate(((PetscObject)win)->comm, V);
300: PetscMalloc(sizeof(Vec)*s->nx, &x);
301: for(i=0; i<s->nx; i++) {
302: VecDuplicate(s->x[i], &x[i]);
303: }
304: VecCreate_Comp_Private(*V, x, s->nx, PETSC_TRUE, s->n);
306: return(0);
307: }
312: PetscErrorCode VecCompGetVecs(Vec win, const Vec **x, PetscInt *n)
313: {
314: Vec_Comp *s = (Vec_Comp*)win->data;
320: if(x) *x = s->x;
321: if(n) *n = s->nx;
323: return(0);
324: }
329: PetscErrorCode VecCompSetVecs(Vec win, Vec *x, PetscInt n)
330: {
331: Vec_Comp *s = (Vec_Comp*)win->data;
332: PetscErrorCode ierr;
338: if(x) {
339: if (n > s->nx) {
340: PetscFree(s->x);
341: PetscMalloc(sizeof(Vec)*n, &s->x);
342: }
343: PetscMemcpy(s->x, x, sizeof(Vec)*n);
344: s->nx = n;
345: }
346: s->n->n = n;
348: return(0);
349: }
354: PetscErrorCode VecAXPY_Comp(Vec v, PetscScalar alpha, Vec w)
355: {
356: PetscErrorCode ierr;
357: Vec_Comp *vs = (Vec_Comp*)v->data,
358: *ws = (Vec_Comp*)w->data;
359: PetscInt i;
366: for(i=0; i<vs->n->n; i++) {
367: VecAXPY(vs->x[i], alpha, ws->x[i]);
368: }
370: return(0);
371: }
376: PetscErrorCode VecAYPX_Comp(Vec v, PetscScalar alpha, Vec w)
377: {
378: PetscErrorCode ierr;
379: Vec_Comp *vs = (Vec_Comp*)v->data,
380: *ws = (Vec_Comp*)w->data;
381: PetscInt i;
388: for(i=0; i<vs->n->n; i++) {
389: VecAYPX(vs->x[i], alpha, ws->x[i]);
390: }
392: return(0);
393: }
398: PetscErrorCode VecAXPBY_Comp(Vec v, PetscScalar alpha, PetscScalar beta, Vec w)
399: {
400: PetscErrorCode ierr;
401: Vec_Comp *vs = (Vec_Comp*)v->data,
402: *ws = (Vec_Comp*)w->data;
403: PetscInt i;
410: for(i=0; i<vs->n->n; i++) {
411: VecAXPBY(vs->x[i], alpha, beta, ws->x[i]);
412: }
414: return(0);
415: }
420: PetscErrorCode VecMAXPY_Comp(Vec v, PetscInt n, const PetscScalar *alpha,
421: Vec *w)
422: {
423: PetscErrorCode ierr;
424: Vec_Comp *vs = (Vec_Comp*)v->data;
425: Vec *wx;
426: PetscInt i, j;
433: PetscMalloc(sizeof(Vec)*n, &wx);
435: for(j=0; j<vs->n->n; j++) {
436: for(i=0; i<n; i++) wx[i] = ((Vec_Comp*)w[i]->data)->x[j];
437: VecMAXPY(vs->x[j], n, alpha, wx);
438: }
440: PetscFree(wx);
442: return(0);
443: }
448: PetscErrorCode VecWAXPY_Comp(Vec v, PetscScalar alpha, Vec w, Vec z)
449: {
450: PetscErrorCode ierr;
451: Vec_Comp *vs = (Vec_Comp*)v->data,
452: *ws = (Vec_Comp*)w->data,
453: *zs = (Vec_Comp*)z->data;
454: PetscInt i;
462: for(i=0; i<vs->n->n; i++) {
463: VecWAXPY(vs->x[i], alpha, ws->x[i], zs->x[i]);
464: }
466: return(0);
467: }
472: PetscErrorCode VecAXPBYPCZ_Comp(Vec v, PetscScalar alpha, PetscScalar beta,
473: PetscScalar gamma, Vec w, Vec z)
474: {
475: PetscErrorCode ierr;
476: Vec_Comp *vs = (Vec_Comp*)v->data,
477: *ws = (Vec_Comp*)w->data,
478: *zs = (Vec_Comp*)z->data;
479: PetscInt i;
487: for(i=0; i<vs->n->n; i++) {
488: VecAXPBYPCZ(vs->x[i], alpha, beta, gamma, ws->x[i], zs->x[i]);
489:
490: }
492: return(0);
493: }
498: PetscErrorCode VecGetSize_Comp(Vec v, PetscInt *size)
499: {
500: Vec_Comp *vs = (Vec_Comp*)v->data;
506: if (size) *size = vs->n->N;
508: return(0);
509: }
514: PetscErrorCode VecGetLocalSize_Comp(Vec v, PetscInt *size)
515: {
516: Vec_Comp *vs = (Vec_Comp*)v->data;
522: if (size) *size = vs->n->lN;
524: return(0);
525: }
531: PetscErrorCode VecMax_Comp(Vec v, PetscInt *idx, PetscReal *z)
532: {
533: PetscErrorCode ierr;
534: Vec_Comp *vs = (Vec_Comp*)v->data;
535: PetscInt idxp, s=0, s0;
536: PetscReal zp, z0;
537: PetscInt i;
543: if(!idx && !z)
544: return(0);
546: if (vs->n->n > 0) {
547: VecMax(vs->x[0], idx?&idxp:PETSC_NULL, &zp);
548: }
549: for (i=1; i<vs->n->n; i++) {
550: VecGetSize(vs->x[i-1], &s0); s+= s0;
551: VecMax(vs->x[i], idx?&idxp:PETSC_NULL, &z0);
552: if(zp < z0) {
553: if(idx) *idx = s+idxp;
554: zp = z0;
555: }
556: }
557: if (z) *z = zp;
559: return(0);
560: }
565: PetscErrorCode VecMin_Comp(Vec v, PetscInt *idx, PetscReal *z)
566: {
567: PetscErrorCode ierr;
568: Vec_Comp *vs = (Vec_Comp*)v->data;
569: PetscInt idxp, s=0, s0;
570: PetscReal zp, z0;
571: PetscInt i;
577: if(!idx && !z)
578: return(0);
580: if (vs->n->n > 0) {
581: VecMin(vs->x[0], idx?&idxp:PETSC_NULL, &zp);
582: }
583: for (i=1; i<vs->n->n; i++) {
584: VecGetSize(vs->x[i-1], &s0); s+= s0;
585: VecMin(vs->x[i], idx?&idxp:PETSC_NULL, &z0);
586: if(zp > z0) {
587: if(idx) *idx = s+idxp;
588: zp = z0;
589: }
590: }
591: if (z) *z = zp;
593: return(0);
594: }
599: PetscErrorCode VecMaxPointwiseDivide_Comp(Vec v, Vec w, PetscReal *m)
600: {
601: PetscErrorCode ierr;
602: Vec_Comp *vs = (Vec_Comp*)v->data,
603: *ws = (Vec_Comp*)w->data;
604: PetscReal work;
605: PetscInt i;
612: if(!m || vs->n->n == 0)
613: return(0);
614: VecMaxPointwiseDivide(vs->x[0], ws->x[0], m);
615: for (i=1; i<vs->n->n; i++) {
616: VecMaxPointwiseDivide(vs->x[i], ws->x[i], &work);
617: *m = PetscMax(*m, work);
618: }
620: return(0);
621: }
629: PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v) \
630: { \
631: PetscErrorCode ierr; \
632: Vec_Comp *vs = (Vec_Comp*)v->data; \
633: PetscInt i; \
634: \
636: \
638: \
639: for(i=0; i<vs->n->n; i++) { \
640: __COMPOSE2__(Vec,NAME)(vs->x[i]); \
641: } \
642: \
643: return(0);\
644: } \
648: __FUNC_TEMPLATE1__(Conjugate)
652: __FUNC_TEMPLATE1__(Reciprocal)
656: __FUNC_TEMPLATE1__(Sqrt)
660: __FUNC_TEMPLATE1__(Abs)
664: __FUNC_TEMPLATE1__(Exp)
668: __FUNC_TEMPLATE1__(Log)
672: PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v, T0 __a) \
673: { \
674: PetscErrorCode ierr; \
675: Vec_Comp *vs = (Vec_Comp*)v->data; \
676: PetscInt i; \
677: \
679: \
681: \
682: for(i=0; i<vs->n->n; i++) { \
683: __COMPOSE2__(Vec,NAME)(vs->x[i], __a); \
684: } \
685: \
686: return(0);\
687: } \
691: __FUNC_TEMPLATE2__(Set, PetscScalar)
695: __FUNC_TEMPLATE2__(View, PetscViewer)
699: __FUNC_TEMPLATE2__(Scale, PetscScalar)
703: __FUNC_TEMPLATE2__(SetRandom, PetscRandom)
707: __FUNC_TEMPLATE2__(Shift, PetscScalar)
711: PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v, Vec w) \
712: { \
713: PetscErrorCode ierr; \
714: Vec_Comp *vs = (Vec_Comp*)v->data, \
715: *ws = (Vec_Comp*)w->data; \
716: PetscInt i; \
717: \
719: \
722: \
723: for(i=0; i<vs->n->n; i++) { \
724: __COMPOSE2__(Vec,NAME)(vs->x[i], ws->x[i]); \
725: } \
726: \
727: return(0);\
728: } \
732: __FUNC_TEMPLATE3__(Copy)
736: __FUNC_TEMPLATE3__(Swap)
740: PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v, Vec w, Vec z) \
741: { \
742: PetscErrorCode ierr; \
743: Vec_Comp *vs = (Vec_Comp*)v->data, \
744: *ws = (Vec_Comp*)w->data, \
745: *zs = (Vec_Comp*)z->data; \
746: PetscInt i; \
747: \
749: \
753: \
754: for(i=0; i<vs->n->n; i++) { \
755: __COMPOSE2__(Vec,NAME)(vs->x[i], ws->x[i], zs->x[i]); \
756: \
757: } \
758: \
759: return(0);\
760: } \
764: __FUNC_TEMPLATE4__(PointwiseMax)
768: __FUNC_TEMPLATE4__(PointwiseMaxAbs)
772: __FUNC_TEMPLATE4__(PointwiseMin)
776: __FUNC_TEMPLATE4__(PointwiseMult)
780: __FUNC_TEMPLATE4__(PointwiseDivide)