Actual source code: veccomp.c
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-2011, Universitat 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 "private/vecimpl.h" /*I "petscvec.h" I*/
23: #include <private/vecimplslepc.h> /*I "slepcvec.h" I*/
25: #include "veccomp0.h"
28: #include "veccomp0.h"
32: PetscErrorCode VecDestroy_Comp(Vec v)
33: {
34: Vec_Comp *vs = (Vec_Comp*)v->data;
35: PetscInt i;
39: /* if memory was published with AMS then destroy it */
40: PetscObjectDepublish(v);
42: #if defined(PETSC_USE_LOG)
43: PetscLogObjectState((PetscObject)v,"Length=%D",v->map->n);
44: #endif
45: for(i=0; i<vs->nx; i++) {
46: VecDestroy(&vs->x[i]);
47: }
48: if(--vs->n->friends <= 0) {
49: PetscFree(vs->n);
50: }
51: PetscFree(vs->x);
52: PetscFree(vs);
53: return(0);
54: }
56: static struct _VecOps DvOps = {VecDuplicate_Comp, /* 1 */
57: VecDuplicateVecs_Default,
58: VecDestroyVecs_Default,
59: VecDot_Comp_MPI,
60: VecMDot_Comp_MPI,
61: VecNorm_Comp_MPI,
62: 0,
63: 0,
64: VecScale_Comp,
65: VecCopy_Comp, /* 10 */
66: VecSet_Comp,
67: VecSwap_Comp,
68: VecAXPY_Comp,
69: VecAXPBY_Comp,
70: VecMAXPY_Comp,
71: VecAYPX_Comp,
72: VecWAXPY_Comp,
73: VecAXPBYPCZ_Comp,
74: VecPointwiseMult_Comp,
75: VecPointwiseDivide_Comp,
76: 0, /* 20 */
77: 0,0,
78: 0 /*VecGetArray_Seq*/,
79: VecGetSize_Comp,
80: VecGetLocalSize_Comp,
81: 0/*VecRestoreArray_Seq*/,
82: VecMax_Comp,
83: VecMin_Comp,
84: VecSetRandom_Comp,
85: 0, /* 30 */
86: 0,
87: VecDestroy_Comp,
88: VecView_Comp,
89: 0/*VecPlaceArray_Seq*/,
90: 0/*VecReplaceArray_Seq*/,
91: VecDot_Comp_Seq,
92: 0,
93: VecNorm_Comp_Seq,
94: VecMDot_Comp_Seq,
95: 0, /* 40 */
96: 0,
97: VecReciprocal_Comp,
98: VecConjugate_Comp,
99: 0,0,
100: 0/*VecResetArray_Seq*/,
101: 0,
102: VecMaxPointwiseDivide_Comp,
103: VecPointwiseMax_Comp,
104: VecPointwiseMaxAbs_Comp,
105: VecPointwiseMin_Comp,
106: 0,
107: VecSqrtAbs_Comp,
108: VecAbs_Comp,
109: VecExp_Comp,
110: VecLog_Comp,
111: 0/*VecShift_Comp*/,
112: 0,
113: 0,
114: 0,
115: VecDotNorm2_Comp_MPI
116: };
120: static PetscErrorCode VecCreate_Comp_Private(Vec v,Vec *x,PetscInt nx,PetscBool x_to_me,Vec_Comp_N *n)
121: {
122: Vec_Comp *s;
124: PetscInt N=0,lN=0,i,k;
127: /* Allocate a new Vec_Comp */
128: if (v->data) { PetscFree(v->data); }
129: PetscNewLog(v,Vec_Comp,&s);
130: PetscMemcpy(v->ops,&DvOps,sizeof(DvOps));
131: v->data = (void*)s;
132: v->petscnative = PETSC_FALSE;
134: /* Allocate the array of Vec, if it is needed to be done */
135: if (x_to_me != PETSC_TRUE) {
136: PetscMalloc(sizeof(Vec)*nx,&s->x);
137: PetscMemcpy(s->x,x,sizeof(Vec)*nx);
138: } else s->x = x;
140: s->nx = nx;
141: for (i=0;i<nx;i++) {
142: VecGetSize(x[i],&k);
143: N+= k;
144: VecGetLocalSize(x[i],&k);
145: lN+= k;
146: }
147:
148: /* Allocate the shared structure, if it is not given */
149: if (!n) {
150: PetscNewLog(v,Vec_Comp_N,&n);
151: s->n = n;
152: n->n = nx;
153: n->N = N;
154: n->lN = lN;
155: n->friends = 1;
156: } else { /* If not, check in the vector in the shared structure */
157: s->n = n;
158: s->n->friends++;
159: s->n->n = nx;
160: }
162: /* Set the virtual sizes as the real sizes of the vector */
163: VecSetSizes(v,s->n->lN,s->n->N);
165: PetscObjectChangeTypeName((PetscObject)v,VECCOMP);
166: return(0);
167: }
172: PetscErrorCode VecCreate_Comp(Vec V)
173: {
177: VecCreate_Comp_Private(V,PETSC_NULL,0,PETSC_FALSE,PETSC_NULL);
178: return(0);
179: }
184: PetscErrorCode VecRegister_Comp(const char path[])
185: {
189: VecRegisterDynamic(VECCOMP,path,"VecCreate_Comp",VecCreate_Comp);
190: VecNormCompInit();
191: return(0);
192: }
196: /*@C
197: VecCreateComp - Creates a new vector containing several subvectors, each stored separately
199: Collective on Vec
201: Input Parameter:
202: + comm - communicator for the new Vec
203: . Nx - array of (initial) global sizes of child vectors
204: . n - number of child vectors
205: . t - type of the child vectors
206: - Vparent - (optional) template vector
208: Output Parameter:
209: . V - new vector
211: Notes:
212: This is similar to PETSc's VecNest but customized for SLEPc's needs. In particular,
213: the number of child vectors can be modified dynamically, with VecCompSetSubVecs().
215: Level: developer
217: .seealso: VecCreateCompWithVecs(), VecCompSetSubVecs()
218: @*/
219: PetscErrorCode VecCreateComp(MPI_Comm comm,PetscInt *Nx,PetscInt n,const VecType t,Vec Vparent,Vec *V)
220: {
222: Vec *x;
223: PetscInt i;
226: VecCreate(comm,V);
227: PetscMalloc(sizeof(Vec)*n,&x);
228: for(i=0;i<n;i++) {
229: VecCreate(comm,&x[i]);
230: VecSetSizes(x[i],PETSC_DECIDE,Nx[i]);
231: VecSetType(x[i],t);
232: }
233: VecCreate_Comp_Private(*V,x,n,PETSC_TRUE,
234: Vparent?((Vec_Comp*)Vparent->data)->n:PETSC_NULL);
235: return(0);
236: }
240: /*@C
241: VecCreateCompWithVecs - Creates a new vector containing several subvectors,
242: each stored separately, from an array of Vecs
244: Collective on Vec
246: Input Parameter:
247: + x - array of Vecs
248: . n - number of child vectors
249: - Vparent - (optional) template vector
251: Output Parameter:
252: . V - new vector
254: Level: developer
256: .seealso: VecCreateComp()
257: @*/
258: PetscErrorCode VecCreateCompWithVecs(Vec *x,PetscInt n,Vec Vparent,Vec *V)
259: {
261: PetscInt i;
264: VecCreate(((PetscObject)x[0])->comm,V);
265: for(i=0;i<n;i++) {
266: PetscObjectReference((PetscObject)x[i]);
267: }
268: VecCreate_Comp_Private(*V,x,n,PETSC_FALSE,
269: Vparent?((Vec_Comp*)Vparent->data)->n:PETSC_NULL);
270: return(0);
271: }
275: PetscErrorCode VecDuplicate_Comp(Vec win,Vec *V)
276: {
278: Vec *x;
279: PetscInt i;
280: Vec_Comp *s = (Vec_Comp*)win->data;
284: VecCreate(((PetscObject)win)->comm,V);
285: PetscMalloc(sizeof(Vec)*s->nx,&x);
286: for (i=0;i<s->nx;i++) {
287: VecDuplicate(s->x[i],&x[i]);
288: }
289: VecCreate_Comp_Private(*V,x,s->nx,PETSC_TRUE,s->n);
290: return(0);
291: }
295: /*@C
296: VecCompGetSubVecs - Returns the entire array of vectors defining a compound vector
298: Collective on Vec
300: Input Parameter:
301: . win - compound vector
303: Output Parameter:
304: + n - number of child vectors
305: - x - array of child vectors
307: Level: developer
309: .seealso: VecCreateComp()
310: @*/
311: PetscErrorCode VecCompGetSubVecs(Vec win,PetscInt *n,const Vec **x)
312: {
313: Vec_Comp *s = (Vec_Comp*)win->data;
317: if(x) *x = s->x;
318: if(n) *n = s->nx;
319: return(0);
320: }
324: /*@C
325: VecCompSetSubVecs - Resets the number of subvectors defining a compound vector,
326: of replaces the subvectors
328: Collective on Vec
330: Input Parameters:
331: + win - compound vector
332: . n - number of child vectors
333: - x - array of child vectors
335: Level: developer
337: .seealso: VecCreateComp()
338: @*/
339: PetscErrorCode VecCompSetSubVecs(Vec win,PetscInt n,Vec *x)
340: {
341: Vec_Comp *s = (Vec_Comp*)win->data;
346: if(x) {
347: if (n > s->nx) {
348: PetscFree(s->x);
349: PetscMalloc(sizeof(Vec)*n,&s->x);
350: }
351: PetscMemcpy(s->x,x,sizeof(Vec)*n);
352: s->nx = n;
353: }
354: s->n->n = n;
355: return(0);
356: }
360: PetscErrorCode VecAXPY_Comp(Vec v,PetscScalar alpha,Vec w)
361: {
363: Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
364: PetscInt i;
369: for (i=0;i<vs->n->n;i++) {
370: VecAXPY(vs->x[i],alpha,ws->x[i]);
371: }
372: return(0);
373: }
377: PetscErrorCode VecAYPX_Comp(Vec v,PetscScalar alpha,Vec w)
378: {
380: Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
381: PetscInt i;
386: for (i=0;i<vs->n->n;i++) {
387: VecAYPX(vs->x[i],alpha,ws->x[i]);
388: }
389: return(0);
390: }
394: PetscErrorCode VecAXPBY_Comp(Vec v,PetscScalar alpha,PetscScalar beta,Vec w)
395: {
397: Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
398: PetscInt i;
403: for (i=0;i<vs->n->n;i++) {
404: VecAXPBY(vs->x[i],alpha,beta,ws->x[i]);
405: }
406: return(0);
407: }
411: PetscErrorCode VecMAXPY_Comp(Vec v,PetscInt n,const PetscScalar *alpha,Vec *w)
412: {
414: Vec_Comp *vs = (Vec_Comp*)v->data;
415: Vec *wx;
416: PetscInt i,j;
422: PetscMalloc(sizeof(Vec)*n,&wx);
424: for (j=0;j<vs->n->n;j++) {
425: for (i=0;i<n;i++) wx[i] = ((Vec_Comp*)w[i]->data)->x[j];
426: VecMAXPY(vs->x[j],n,alpha,wx);
427: }
429: PetscFree(wx);
430: return(0);
431: }
435: PetscErrorCode VecWAXPY_Comp(Vec v,PetscScalar alpha,Vec w,Vec z)
436: {
438: Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data,*zs = (Vec_Comp*)z->data;
439: PetscInt i;
445: for (i=0;i<vs->n->n;i++) {
446: VecWAXPY(vs->x[i],alpha,ws->x[i],zs->x[i]);
447: }
448: return(0);
449: }
453: PetscErrorCode VecAXPBYPCZ_Comp(Vec v,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec w,Vec z)
454: {
455: PetscErrorCode ierr;
456: Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data,*zs = (Vec_Comp*)z->data;
457: PetscInt i;
463: for (i=0;i<vs->n->n;i++) {
464: VecAXPBYPCZ(vs->x[i],alpha,beta,gamma,ws->x[i],zs->x[i]);
465: }
466: return(0);
467: }
471: PetscErrorCode VecGetSize_Comp(Vec v,PetscInt *size)
472: {
473: Vec_Comp *vs = (Vec_Comp*)v->data;
478: *size = vs->n->N;
479: return(0);
480: }
484: PetscErrorCode VecGetLocalSize_Comp(Vec v,PetscInt *size)
485: {
486: Vec_Comp *vs = (Vec_Comp*)v->data;
491: *size = vs->n->lN;
492: return(0);
493: }
497: PetscErrorCode VecMax_Comp(Vec v,PetscInt *idx,PetscReal *z)
498: {
500: Vec_Comp *vs = (Vec_Comp*)v->data;
501: PetscInt idxp,s=0,s0;
502: PetscReal zp,z0;
503: PetscInt i;
507: if (!idx && !z) return(0);
509: if (vs->n->n > 0) {
510: VecMax(vs->x[0],idx?&idxp:PETSC_NULL,&zp);
511: }
512: for (i=1;i<vs->n->n;i++) {
513: VecGetSize(vs->x[i-1],&s0);
514: s+= s0;
515: VecMax(vs->x[i],idx?&idxp:PETSC_NULL,&z0);
516: if (zp < z0) {
517: if (idx) *idx = s+idxp;
518: zp = z0;
519: }
520: }
521: if (z) *z = zp;
522: return(0);
523: }
527: PetscErrorCode VecMin_Comp(Vec v,PetscInt *idx,PetscReal *z)
528: {
530: Vec_Comp *vs = (Vec_Comp*)v->data;
531: PetscInt idxp,s=0,s0;
532: PetscReal zp,z0;
533: PetscInt i;
537: if (!idx && !z) return(0);
539: if (vs->n->n > 0) {
540: VecMin(vs->x[0],idx?&idxp:PETSC_NULL,&zp);
541: }
542: for (i=1;i<vs->n->n;i++) {
543: VecGetSize(vs->x[i-1],&s0);
544: s+= s0;
545: VecMin(vs->x[i],idx?&idxp:PETSC_NULL,&z0);
546: if(zp > z0) {
547: if(idx) *idx = s+idxp;
548: zp = z0;
549: }
550: }
551: if (z) *z = zp;
552: return(0);
553: }
557: PetscErrorCode VecMaxPointwiseDivide_Comp(Vec v,Vec w,PetscReal *m)
558: {
560: Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
561: PetscReal work;
562: PetscInt i;
567: if (!m || vs->n->n == 0) return(0);
568: VecMaxPointwiseDivide(vs->x[0],ws->x[0],m);
569: for (i=1;i<vs->n->n;i++) {
570: VecMaxPointwiseDivide(vs->x[i],ws->x[i],&work);
571: *m = PetscMax(*m,work);
572: }
573: return(0);
574: }
582: PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v) \
583: { \
584: PetscErrorCode ierr; \
585: Vec_Comp *vs = (Vec_Comp*)v->data; \
586: PetscInt i; \
587: \
590: for (i=0;i<vs->n->n;i++) { \
591: __COMPOSE2__(Vec,NAME)(vs->x[i]); \
592: } \
593: return(0);\
594: }
598: __FUNC_TEMPLATE1__(Conjugate)
602: __FUNC_TEMPLATE1__(Reciprocal)
606: __FUNC_TEMPLATE1__(SqrtAbs)
610: __FUNC_TEMPLATE1__(Abs)
614: __FUNC_TEMPLATE1__(Exp)
618: __FUNC_TEMPLATE1__(Log)
622: PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v,T0 __a) \
623: { \
624: PetscErrorCode ierr; \
625: Vec_Comp *vs = (Vec_Comp*)v->data; \
626: PetscInt i; \
627: \
630: for (i=0;i<vs->n->n;i++) { \
631: __COMPOSE2__(Vec,NAME)(vs->x[i],__a); \
632: } \
633: return(0);\
634: }
638: __FUNC_TEMPLATE2__(Set,PetscScalar)
642: __FUNC_TEMPLATE2__(View,PetscViewer)
646: __FUNC_TEMPLATE2__(Scale,PetscScalar)
650: __FUNC_TEMPLATE2__(SetRandom,PetscRandom)
654: __FUNC_TEMPLATE2__(Shift,PetscScalar)
658: PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v,Vec w) \
659: { \
660: PetscErrorCode ierr; \
661: Vec_Comp *vs = (Vec_Comp*)v->data,\
662: *ws = (Vec_Comp*)w->data; \
663: PetscInt i; \
664: \
668: for (i=0;i<vs->n->n;i++) { \
669: __COMPOSE2__(Vec,NAME)(vs->x[i],ws->x[i]); \
670: } \
671: return(0);\
672: }
676: __FUNC_TEMPLATE3__(Copy)
680: __FUNC_TEMPLATE3__(Swap)
684: PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v,Vec w,Vec z) \
685: { \
686: PetscErrorCode ierr; \
687: Vec_Comp *vs = (Vec_Comp*)v->data, \
688: *ws = (Vec_Comp*)w->data, \
689: *zs = (Vec_Comp*)z->data; \
690: PetscInt i; \
691: \
696: for (i=0;i<vs->n->n;i++) { \
697: __COMPOSE2__(Vec,NAME)(vs->x[i],ws->x[i],zs->x[i]); \
698: } \
699: return(0);\
700: }
704: __FUNC_TEMPLATE4__(PointwiseMax)
708: __FUNC_TEMPLATE4__(PointwiseMaxAbs)
712: __FUNC_TEMPLATE4__(PointwiseMin)
716: __FUNC_TEMPLATE4__(PointwiseMult)
720: __FUNC_TEMPLATE4__(PointwiseDivide)