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/vecimplslepc.h> /*I "slepcvec.h" I*/
24: #include "veccomp0.h"
27: #include "veccomp0.h"
31: PetscErrorCode VecDestroy_Comp(Vec v)
32: {
33: Vec_Comp *vs = (Vec_Comp*)v->data;
34: PetscInt i;
38: /* if memory was published with AMS then destroy it */
39: PetscObjectDepublish(v);
41: #if defined(PETSC_USE_LOG)
42: PetscLogObjectState((PetscObject)v,"Length=%D",v->map->n);
43: #endif
44: for(i=0; i<vs->nx; i++) {
45: VecDestroy(&vs->x[i]);
46: }
47: if(--vs->n->friends <= 0) {
48: PetscFree(vs->n);
49: }
50: PetscFree(vs->x);
51: PetscFree(vs);
52: return(0);
53: }
55: static struct _VecOps DvOps = {VecDuplicate_Comp, /* 1 */
56: VecDuplicateVecs_Default,
57: VecDestroyVecs_Default,
58: VecDot_Comp_MPI,
59: VecMDot_Comp_MPI,
60: VecNorm_Comp_MPI,
61: VecTDot_Comp_MPI,
62: VecMTDot_Comp_MPI,
63: VecScale_Comp,
64: VecCopy_Comp, /* 10 */
65: VecSet_Comp,
66: VecSwap_Comp,
67: VecAXPY_Comp,
68: VecAXPBY_Comp,
69: VecMAXPY_Comp,
70: VecAYPX_Comp,
71: VecWAXPY_Comp,
72: VecAXPBYPCZ_Comp,
73: VecPointwiseMult_Comp,
74: VecPointwiseDivide_Comp,
75: 0, /* 20 */
76: 0,0,
77: 0 /*VecGetArray_Seq*/,
78: VecGetSize_Comp,
79: VecGetLocalSize_Comp,
80: 0/*VecRestoreArray_Seq*/,
81: VecMax_Comp,
82: VecMin_Comp,
83: VecSetRandom_Comp,
84: 0, /* 30 */
85: 0,
86: VecDestroy_Comp,
87: VecView_Comp,
88: 0/*VecPlaceArray_Seq*/,
89: 0/*VecReplaceArray_Seq*/,
90: VecDot_Comp_Seq,
91: 0,
92: VecNorm_Comp_Seq,
93: VecMDot_Comp_Seq,
94: 0, /* 40 */
95: 0,
96: VecReciprocal_Comp,
97: VecConjugate_Comp,
98: 0,0,
99: 0/*VecResetArray_Seq*/,
100: 0,
101: VecMaxPointwiseDivide_Comp,
102: VecPointwiseMax_Comp,
103: VecPointwiseMaxAbs_Comp,
104: VecPointwiseMin_Comp,
105: 0,
106: VecSqrtAbs_Comp,
107: VecAbs_Comp,
108: VecExp_Comp,
109: VecLog_Comp,
110: 0/*VecShift_Comp*/,
111: 0,
112: 0,
113: 0,
114: VecDotNorm2_Comp_MPI
115: };
119: static PetscErrorCode VecCreate_Comp_Private(Vec v,Vec *x,PetscInt nx,PetscBool x_to_me,Vec_Comp_N *n)
120: {
121: Vec_Comp *s;
123: PetscInt N=0,lN=0,i,k;
126: /* Allocate a new Vec_Comp */
127: if (v->data) { PetscFree(v->data); }
128: PetscNewLog(v,Vec_Comp,&s);
129: PetscMemcpy(v->ops,&DvOps,sizeof(DvOps));
130: v->data = (void*)s;
131: v->petscnative = PETSC_FALSE;
133: /* Allocate the array of Vec, if it is needed to be done */
134: if (x_to_me != PETSC_TRUE) {
135: PetscMalloc(sizeof(Vec)*nx,&s->x);
136: PetscMemcpy(s->x,x,sizeof(Vec)*nx);
137: } else s->x = x;
139: s->nx = nx;
140: for (i=0;i<nx;i++) {
141: VecGetSize(x[i],&k);
142: N+= k;
143: VecGetLocalSize(x[i],&k);
144: lN+= k;
145: }
146:
147: /* Allocate the shared structure, if it is not given */
148: if (!n) {
149: PetscNewLog(v,Vec_Comp_N,&n);
150: s->n = n;
151: n->n = nx;
152: n->N = N;
153: n->lN = lN;
154: n->friends = 1;
155: } else { /* If not, check in the vector in the shared structure */
156: s->n = n;
157: s->n->friends++;
158: s->n->n = nx;
159: }
161: /* Set the virtual sizes as the real sizes of the vector */
162: VecSetSizes(v,s->n->lN,s->n->N);
164: PetscObjectChangeTypeName((PetscObject)v,VECCOMP);
165: return(0);
166: }
168: EXTERN_C_BEGIN
171: PetscErrorCode VecCreate_Comp(Vec V)
172: {
176: VecCreate_Comp_Private(V,PETSC_NULL,0,PETSC_FALSE,PETSC_NULL);
177: return(0);
178: }
179: EXTERN_C_END
183: PetscErrorCode VecRegister_Comp(const char path[])
184: {
188: VecRegisterDynamic(VECCOMP,path,"VecCreate_Comp",VecCreate_Comp);
189: VecNormCompInit();
190: return(0);
191: }
195: /*@C
196: VecCreateComp - Creates a new vector containing several subvectors, each stored separately
198: Collective on Vec
200: Input Parameter:
201: + comm - communicator for the new Vec
202: . Nx - array of (initial) global sizes of child vectors
203: . n - number of child vectors
204: . t - type of the child vectors
205: - Vparent - (optional) template vector
207: Output Parameter:
208: . V - new vector
210: Notes:
211: This is similar to PETSc's VecNest but customized for SLEPc's needs. In particular,
212: the number of child vectors can be modified dynamically, with VecCompSetSubVecs().
214: Level: developer
216: .seealso: VecCreateCompWithVecs(), VecCompSetSubVecs()
217: @*/
218: PetscErrorCode VecCreateComp(MPI_Comm comm,PetscInt *Nx,PetscInt n,const VecType t,Vec Vparent,Vec *V)
219: {
221: Vec *x;
222: PetscInt i;
225: VecCreate(comm,V);
226: PetscMalloc(sizeof(Vec)*n,&x);
227: for(i=0;i<n;i++) {
228: VecCreate(comm,&x[i]);
229: VecSetSizes(x[i],PETSC_DECIDE,Nx[i]);
230: VecSetType(x[i],t);
231: }
232: VecCreate_Comp_Private(*V,x,n,PETSC_TRUE,
233: Vparent?((Vec_Comp*)Vparent->data)->n:PETSC_NULL);
234: return(0);
235: }
239: /*@C
240: VecCreateCompWithVecs - Creates a new vector containing several subvectors,
241: each stored separately, from an array of Vecs
243: Collective on Vec
245: Input Parameter:
246: + x - array of Vecs
247: . n - number of child vectors
248: - Vparent - (optional) template vector
250: Output Parameter:
251: . V - new vector
253: Level: developer
255: .seealso: VecCreateComp()
256: @*/
257: PetscErrorCode VecCreateCompWithVecs(Vec *x,PetscInt n,Vec Vparent,Vec *V)
258: {
260: PetscInt i;
263: VecCreate(((PetscObject)x[0])->comm,V);
264: for(i=0;i<n;i++) {
265: PetscObjectReference((PetscObject)x[i]);
266: }
267: VecCreate_Comp_Private(*V,x,n,PETSC_FALSE,
268: Vparent?((Vec_Comp*)Vparent->data)->n:PETSC_NULL);
269: return(0);
270: }
274: PetscErrorCode VecDuplicate_Comp(Vec win,Vec *V)
275: {
277: Vec *x;
278: PetscInt i;
279: Vec_Comp *s = (Vec_Comp*)win->data;
283: VecCreate(((PetscObject)win)->comm,V);
284: PetscMalloc(sizeof(Vec)*s->nx,&x);
285: for (i=0;i<s->nx;i++) {
286: VecDuplicate(s->x[i],&x[i]);
287: }
288: VecCreate_Comp_Private(*V,x,s->nx,PETSC_TRUE,s->n);
289: return(0);
290: }
294: /*@C
295: VecCompGetSubVecs - Returns the entire array of vectors defining a compound vector
297: Collective on Vec
299: Input Parameter:
300: . win - compound vector
302: Output Parameter:
303: + n - number of child vectors
304: - x - array of child vectors
306: Level: developer
308: .seealso: VecCreateComp()
309: @*/
310: PetscErrorCode VecCompGetSubVecs(Vec win,PetscInt *n,const Vec **x)
311: {
312: Vec_Comp *s = (Vec_Comp*)win->data;
316: if(x) *x = s->x;
317: if(n) *n = s->nx;
318: return(0);
319: }
323: /*@C
324: VecCompSetSubVecs - Resets the number of subvectors defining a compound vector,
325: of replaces the subvectors
327: Collective on Vec
329: Input Parameters:
330: + win - compound vector
331: . n - number of child vectors
332: - x - array of child vectors
334: Level: developer
336: .seealso: VecCreateComp()
337: @*/
338: PetscErrorCode VecCompSetSubVecs(Vec win,PetscInt n,Vec *x)
339: {
340: Vec_Comp *s = (Vec_Comp*)win->data;
345: if(x) {
346: if (n > s->nx) {
347: PetscFree(s->x);
348: PetscMalloc(sizeof(Vec)*n,&s->x);
349: }
350: PetscMemcpy(s->x,x,sizeof(Vec)*n);
351: s->nx = n;
352: }
353: s->n->n = n;
354: return(0);
355: }
359: PetscErrorCode VecAXPY_Comp(Vec v,PetscScalar alpha,Vec w)
360: {
362: Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
363: PetscInt i;
368: for (i=0;i<vs->n->n;i++) {
369: VecAXPY(vs->x[i],alpha,ws->x[i]);
370: }
371: return(0);
372: }
376: PetscErrorCode VecAYPX_Comp(Vec v,PetscScalar alpha,Vec w)
377: {
379: Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
380: PetscInt i;
385: for (i=0;i<vs->n->n;i++) {
386: VecAYPX(vs->x[i],alpha,ws->x[i]);
387: }
388: return(0);
389: }
393: PetscErrorCode VecAXPBY_Comp(Vec v,PetscScalar alpha,PetscScalar beta,Vec w)
394: {
396: Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
397: PetscInt i;
402: for (i=0;i<vs->n->n;i++) {
403: VecAXPBY(vs->x[i],alpha,beta,ws->x[i]);
404: }
405: return(0);
406: }
410: PetscErrorCode VecMAXPY_Comp(Vec v,PetscInt n,const PetscScalar *alpha,Vec *w)
411: {
413: Vec_Comp *vs = (Vec_Comp*)v->data;
414: Vec *wx;
415: PetscInt i,j;
421: PetscMalloc(sizeof(Vec)*n,&wx);
423: for (j=0;j<vs->n->n;j++) {
424: for (i=0;i<n;i++) wx[i] = ((Vec_Comp*)w[i]->data)->x[j];
425: VecMAXPY(vs->x[j],n,alpha,wx);
426: }
428: PetscFree(wx);
429: return(0);
430: }
434: PetscErrorCode VecWAXPY_Comp(Vec v,PetscScalar alpha,Vec w,Vec z)
435: {
437: Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data,*zs = (Vec_Comp*)z->data;
438: PetscInt i;
444: for (i=0;i<vs->n->n;i++) {
445: VecWAXPY(vs->x[i],alpha,ws->x[i],zs->x[i]);
446: }
447: return(0);
448: }
452: PetscErrorCode VecAXPBYPCZ_Comp(Vec v,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec w,Vec z)
453: {
454: PetscErrorCode ierr;
455: Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data,*zs = (Vec_Comp*)z->data;
456: PetscInt i;
462: for (i=0;i<vs->n->n;i++) {
463: VecAXPBYPCZ(vs->x[i],alpha,beta,gamma,ws->x[i],zs->x[i]);
464: }
465: return(0);
466: }
470: PetscErrorCode VecGetSize_Comp(Vec v,PetscInt *size)
471: {
472: Vec_Comp *vs = (Vec_Comp*)v->data;
477: *size = vs->n->N;
478: return(0);
479: }
483: PetscErrorCode VecGetLocalSize_Comp(Vec v,PetscInt *size)
484: {
485: Vec_Comp *vs = (Vec_Comp*)v->data;
490: *size = vs->n->lN;
491: return(0);
492: }
496: PetscErrorCode VecMax_Comp(Vec v,PetscInt *idx,PetscReal *z)
497: {
499: Vec_Comp *vs = (Vec_Comp*)v->data;
500: PetscInt idxp,s=0,s0;
501: PetscReal zp,z0;
502: PetscInt i;
506: if (!idx && !z) return(0);
508: if (vs->n->n > 0) {
509: VecMax(vs->x[0],idx?&idxp:PETSC_NULL,&zp);
510: }
511: for (i=1;i<vs->n->n;i++) {
512: VecGetSize(vs->x[i-1],&s0);
513: s+= s0;
514: VecMax(vs->x[i],idx?&idxp:PETSC_NULL,&z0);
515: if (zp < z0) {
516: if (idx) *idx = s+idxp;
517: zp = z0;
518: }
519: }
520: if (z) *z = zp;
521: return(0);
522: }
526: PetscErrorCode VecMin_Comp(Vec v,PetscInt *idx,PetscReal *z)
527: {
529: Vec_Comp *vs = (Vec_Comp*)v->data;
530: PetscInt idxp,s=0,s0;
531: PetscReal zp,z0;
532: PetscInt i;
536: if (!idx && !z) return(0);
538: if (vs->n->n > 0) {
539: VecMin(vs->x[0],idx?&idxp:PETSC_NULL,&zp);
540: }
541: for (i=1;i<vs->n->n;i++) {
542: VecGetSize(vs->x[i-1],&s0);
543: s+= s0;
544: VecMin(vs->x[i],idx?&idxp:PETSC_NULL,&z0);
545: if(zp > z0) {
546: if(idx) *idx = s+idxp;
547: zp = z0;
548: }
549: }
550: if (z) *z = zp;
551: return(0);
552: }
556: PetscErrorCode VecMaxPointwiseDivide_Comp(Vec v,Vec w,PetscReal *m)
557: {
559: Vec_Comp *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
560: PetscReal work;
561: PetscInt i;
566: if (!m || vs->n->n == 0) return(0);
567: VecMaxPointwiseDivide(vs->x[0],ws->x[0],m);
568: for (i=1;i<vs->n->n;i++) {
569: VecMaxPointwiseDivide(vs->x[i],ws->x[i],&work);
570: *m = PetscMax(*m,work);
571: }
572: return(0);
573: }
581: PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v) \
582: { \
583: PetscErrorCode ierr; \
584: Vec_Comp *vs = (Vec_Comp*)v->data; \
585: PetscInt i; \
586: \
589: for (i=0;i<vs->n->n;i++) { \
590: __COMPOSE2__(Vec,NAME)(vs->x[i]); \
591: } \
592: return(0);\
593: }
597: __FUNC_TEMPLATE1__(Conjugate)
601: __FUNC_TEMPLATE1__(Reciprocal)
605: __FUNC_TEMPLATE1__(SqrtAbs)
609: __FUNC_TEMPLATE1__(Abs)
613: __FUNC_TEMPLATE1__(Exp)
617: __FUNC_TEMPLATE1__(Log)
621: PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v,T0 __a) \
622: { \
623: PetscErrorCode ierr; \
624: Vec_Comp *vs = (Vec_Comp*)v->data; \
625: PetscInt i; \
626: \
629: for (i=0;i<vs->n->n;i++) { \
630: __COMPOSE2__(Vec,NAME)(vs->x[i],__a); \
631: } \
632: return(0);\
633: }
637: __FUNC_TEMPLATE2__(Set,PetscScalar)
641: __FUNC_TEMPLATE2__(View,PetscViewer)
645: __FUNC_TEMPLATE2__(Scale,PetscScalar)
649: __FUNC_TEMPLATE2__(SetRandom,PetscRandom)
653: __FUNC_TEMPLATE2__(Shift,PetscScalar)
657: PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v,Vec w) \
658: { \
659: PetscErrorCode ierr; \
660: Vec_Comp *vs = (Vec_Comp*)v->data,\
661: *ws = (Vec_Comp*)w->data; \
662: PetscInt i; \
663: \
667: for (i=0;i<vs->n->n;i++) { \
668: __COMPOSE2__(Vec,NAME)(vs->x[i],ws->x[i]); \
669: } \
670: return(0);\
671: }
675: __FUNC_TEMPLATE3__(Copy)
679: __FUNC_TEMPLATE3__(Swap)
683: PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v,Vec w,Vec z) \
684: { \
685: PetscErrorCode ierr; \
686: Vec_Comp *vs = (Vec_Comp*)v->data, \
687: *ws = (Vec_Comp*)w->data, \
688: *zs = (Vec_Comp*)z->data; \
689: PetscInt i; \
690: \
695: for (i=0;i<vs->n->n;i++) { \
696: __COMPOSE2__(Vec,NAME)(vs->x[i],ws->x[i],zs->x[i]); \
697: } \
698: return(0);\
699: }
703: __FUNC_TEMPLATE4__(PointwiseMax)
707: __FUNC_TEMPLATE4__(PointwiseMaxAbs)
711: __FUNC_TEMPLATE4__(PointwiseMin)
715: __FUNC_TEMPLATE4__(PointwiseMult)
719: __FUNC_TEMPLATE4__(PointwiseDivide)