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)