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)