Actual source code: rvector.c

petsc-3.3-p5 2012-12-01
  2: /*
  3:      Provides the interface functions for vector operations that have PetscScalar/PetscReal in the signature
  4:    These are the vector functions the user calls.
  5: */
  6: #include <petsc-private/vecimpl.h>    /*I "petscvec.h" I*/
  7: static PetscInt VecGetSubVectorSavedStateId = -1;

 10:   if ((x)->map->N != (y)->map->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths"); \
 11:   if ((x)->map->n != (y)->map->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");


 16: /*@
 17:    VecMaxPointwiseDivide - Computes the maximum of the componentwise division max = max_i abs(x_i/y_i).

 19:    Logically Collective on Vec

 21:    Input Parameters:
 22: .  x, y  - the vectors

 24:    Output Parameter:
 25: .  max - the result

 27:    Level: advanced

 29:    Notes: x and y may be the same vector
 30:           if a particular y_i is zero, it is treated as 1 in the above formula

 32: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs()
 33: @*/
 34: PetscErrorCode  VecMaxPointwiseDivide(Vec x,Vec y,PetscReal *max)
 35: {


 47:   (*x->ops->maxpointwisedivide)(x,y,max);
 48:   return(0);
 49: }

 53: /*@
 54:    VecDot - Computes the vector dot product.

 56:    Collective on Vec

 58:    Input Parameters:
 59: .  x, y - the vectors

 61:    Output Parameter:
 62: .  val - the dot product

 64:    Performance Issues:
 65: $    per-processor memory bandwidth
 66: $    interprocessor latency
 67: $    work load inbalance that causes certain processes to arrive much earlier than others

 69:    Notes for Users of Complex Numbers:
 70:    For complex vectors, VecDot() computes 
 71: $     val = (x,y) = y^H x,
 72:    where y^H denotes the conjugate transpose of y. Note that this corresponds to the usual "mathematicians" complex 
 73:    inner product where the SECOND argument gets the complex conjugate. Since the BLASdot() complex conjugates the first
 74:    first argument we call the BLASdot() with the arguments reversed.

 76:    Use VecTDot() for the indefinite form
 77: $     val = (x,y) = y^T x,
 78:    where y^T denotes the transpose of y.

 80:    Level: intermediate

 82:    Concepts: inner product
 83:    Concepts: vector^inner product

 85: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd()
 86: @*/
 87: PetscErrorCode  VecDot(Vec x,Vec y,PetscScalar *val)
 88: {


100:   PetscLogEventBarrierBegin(VEC_DotBarrier,x,y,0,0,((PetscObject)x)->comm);
101:   (*x->ops->dot)(x,y,val);
102:   PetscLogEventBarrierEnd(VEC_DotBarrier,x,y,0,0,((PetscObject)x)->comm);
103:   if (PetscIsInfOrNanScalar(*val)) SETERRQ(((PetscObject)x)->comm,PETSC_ERR_FP,"Infinite or not-a-number generated in dot product");
104:   return(0);
105: }

109: /*@
110:    VecNorm  - Computes the vector norm.

112:    Collective on Vec

114:    Input Parameters:
115: +  x - the vector
116: -  type - one of NORM_1, NORM_2, NORM_INFINITY.  Also available
117:           NORM_1_AND_2, which computes both norms and stores them
118:           in a two element array.

120:    Output Parameter:
121: .  val - the norm 

123:    Notes:
124: $     NORM_1 denotes sum_i |x_i|
125: $     NORM_2 denotes sqrt(sum_i (x_i)^2)
126: $     NORM_INFINITY denotes max_i |x_i|

128:    Level: intermediate

130:    Performance Issues:
131: $    per-processor memory bandwidth
132: $    interprocessor latency
133: $    work load inbalance that causes certain processes to arrive much earlier than others

135:    Compile Option:
136:    PETSC_HAVE_SLOW_BLAS_NORM2 will cause a C (loop unrolled) version of the norm to be used, rather
137:  than the BLAS. This should probably only be used when one is using the FORTRAN BLAS routines 
138:  (as opposed to vendor provided) because the FORTRAN BLAS NRM2() routine is very slow. 

140:    Concepts: norm
141:    Concepts: vector^norm

143: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNormAvailable(),
144:           VecNormBegin(), VecNormEnd()

146: @*/
147: PetscErrorCode  VecNorm(Vec x,NormType type,PetscReal *val)
148: {
149:   PetscBool      flg;

156:   if (((PetscObject)x)->precision != sizeof(PetscScalar)) SETERRQ(((PetscObject)x)->comm,PETSC_ERR_SUP,"Wrong precision of input argument");

158:   /*
159:    * Cached data?
160:    */
161:   if (type!=NORM_1_AND_2) {
162:     PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,flg);
163:     if (flg) return(0);
164:   }

166:   PetscLogEventBarrierBegin(VEC_NormBarrier,x,0,0,0,((PetscObject)x)->comm);
167:   (*x->ops->norm)(x,type,val);
168:   PetscLogEventBarrierEnd(VEC_NormBarrier,x,0,0,0,((PetscObject)x)->comm);
169:   if (PetscIsInfOrNanScalar(*val)) SETERRQ(((PetscObject)x)->comm,PETSC_ERR_FP,"Infinite or not-a-number generated in norm");

171:   if (type!=NORM_1_AND_2) {
172:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[type],*val);
173:   }
174:   return(0);
175: }

179: /*@
180:    VecNormAvailable  - Returns the vector norm if it is already known.

182:    Not Collective

184:    Input Parameters:
185: +  x - the vector
186: -  type - one of NORM_1, NORM_2, NORM_INFINITY.  Also available
187:           NORM_1_AND_2, which computes both norms and stores them
188:           in a two element array.

190:    Output Parameter:
191: +  available - PETSC_TRUE if the val returned is valid
192: -  val - the norm 

194:    Notes:
195: $     NORM_1 denotes sum_i |x_i|
196: $     NORM_2 denotes sqrt(sum_i (x_i)^2)
197: $     NORM_INFINITY denotes max_i |x_i|

199:    Level: intermediate

201:    Performance Issues:
202: $    per-processor memory bandwidth
203: $    interprocessor latency
204: $    work load inbalance that causes certain processes to arrive much earlier than others

206:    Compile Option:
207:    PETSC_HAVE_SLOW_BLAS_NORM2 will cause a C (loop unrolled) version of the norm to be used, rather
208:  than the BLAS. This should probably only be used when one is using the FORTRAN BLAS routines 
209:  (as opposed to vendor provided) because the FORTRAN BLAS NRM2() routine is very slow. 

211:    Concepts: norm
212:    Concepts: vector^norm

214: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNorm()
215:           VecNormBegin(), VecNormEnd()

217: @*/
218: PetscErrorCode  VecNormAvailable(Vec x,NormType type,PetscBool  *available,PetscReal *val)
219: {


227:   *available = PETSC_FALSE;
228:   if (type!=NORM_1_AND_2) {
229:     PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,*available);
230:   }
231:   return(0);
232: }

236: /*@
237:    VecNormalize - Normalizes a vector by 2-norm. 

239:    Collective on Vec

241:    Input Parameters:
242: +  x - the vector

244:    Output Parameter:
245: .  x - the normalized vector
246: -  val - the vector norm before normalization

248:    Level: intermediate

250:    Concepts: vector^normalizing
251:    Concepts: normalizing^vector

253: @*/
254: PetscErrorCode  VecNormalize(Vec x,PetscReal *val)
255: {
257:   PetscReal      norm;

262:   PetscLogEventBegin(VEC_Normalize,x,0,0,0);
263:   VecNorm(x,NORM_2,&norm);
264:   if (norm == 0.0) {
265:     PetscInfo(x,"Vector of zero norm can not be normalized; Returning only the zero norm\n");
266:   } else if (norm != 1.0) {
267:     PetscScalar tmp = 1.0/norm;
268:     VecScale(x,tmp);
269:   }
270:   if (val) *val = norm;
271:   PetscLogEventEnd(VEC_Normalize,x,0,0,0);
272:   return(0);
273: }

277: /*@C
278:    VecMax - Determines the maximum vector component and its location.

280:    Collective on Vec

282:    Input Parameter:
283: .  x - the vector

285:    Output Parameters:
286: +  val - the maximum component
287: -  p - the location of val (pass PETSC_NULL if you don't want this)

289:    Notes:
290:    Returns the value PETSC_MIN_REAL and p = -1 if the vector is of length 0.

292:    Returns the smallest index with the maximum value
293:    Level: intermediate

295:    Concepts: maximum^of vector
296:    Concepts: vector^maximum value

298: .seealso: VecNorm(), VecMin()
299: @*/
300: PetscErrorCode  VecMax(Vec x,PetscInt *p,PetscReal *val)
301: {

308:   PetscLogEventBegin(VEC_Max,x,0,0,0);
309:   (*x->ops->max)(x,p,val);
310:   PetscLogEventEnd(VEC_Max,x,0,0,0);
311:   return(0);
312: }

316: /*@
317:    VecMin - Determines the minimum vector component and its location.

319:    Collective on Vec

321:    Input Parameters:
322: .  x - the vector

324:    Output Parameter:
325: +  val - the minimum component
326: -  p - the location of val (pass PETSC_NULL if you don't want this location)

328:    Level: intermediate

330:    Notes:
331:    Returns the value PETSC_MAX_REAL and p = -1 if the vector is of length 0.

333:    This returns the smallest index with the minumum value

335:    Concepts: minimum^of vector
336:    Concepts: vector^minimum entry

338: .seealso: VecMax()
339: @*/
340: PetscErrorCode  VecMin(Vec x,PetscInt *p,PetscReal *val)
341: {

348:   PetscLogEventBegin(VEC_Min,x,0,0,0);
349:   (*x->ops->min)(x,p,val);
350:   PetscLogEventEnd(VEC_Min,x,0,0,0);
351:   return(0);
352: }

356: /*@
357:    VecTDot - Computes an indefinite vector dot product. That is, this
358:    routine does NOT use the complex conjugate.

360:    Collective on Vec

362:    Input Parameters:
363: .  x, y - the vectors

365:    Output Parameter:
366: .  val - the dot product

368:    Notes for Users of Complex Numbers:
369:    For complex vectors, VecTDot() computes the indefinite form
370: $     val = (x,y) = y^T x,
371:    where y^T denotes the transpose of y.

373:    Use VecDot() for the inner product
374: $     val = (x,y) = y^H x,
375:    where y^H denotes the conjugate transpose of y.

377:    Level: intermediate

379:    Concepts: inner product^non-Hermitian
380:    Concepts: vector^inner product
381:    Concepts: non-Hermitian inner product

383: .seealso: VecDot(), VecMTDot()
384: @*/
385: PetscErrorCode  VecTDot(Vec x,Vec y,PetscScalar *val)
386: {


398:   PetscLogEventBegin(VEC_TDot,x,y,0,0);
399:   (*x->ops->tdot)(x,y,val);
400:   PetscLogEventEnd(VEC_TDot,x,y,0,0);
401:   return(0);
402: }

406: /*@
407:    VecScale - Scales a vector. 

409:    Not collective on Vec

411:    Input Parameters:
412: +  x - the vector
413: -  alpha - the scalar

415:    Output Parameter:
416: .  x - the scaled vector

418:    Note:
419:    For a vector with n components, VecScale() computes 
420: $      x[i] = alpha * x[i], for i=1,...,n.

422:    Level: intermediate

424:    Concepts: vector^scaling
425:    Concepts: scaling^vector

427: @*/
428: PetscErrorCode  VecScale (Vec x, PetscScalar alpha)
429: {
430:   PetscReal      norms[4] = {0.0,0.0,0.0, 0.0};
431:   PetscBool      flgs[4];
433:   PetscInt       i;

438:   if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
439:   PetscLogEventBegin(VEC_Scale,x,0,0,0);
440:   if (alpha != (PetscScalar)1.0) {
441:     /* get current stashed norms */
442:     for (i=0; i<4; i++) {
443:       PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],norms[i],flgs[i]);
444:     }
445:     (*x->ops->scale)(x,alpha);
446:     PetscObjectStateIncrease((PetscObject)x);
447:     /* put the scaled stashed norms back into the Vec */
448:     for (i=0; i<4; i++) {
449:       if (flgs[i]) {
450:         PetscObjectComposedDataSetReal((PetscObject)x,NormIds[i],PetscAbsScalar(alpha)*norms[i]);
451:       }
452:     }
453:   }
454:   PetscLogEventEnd(VEC_Scale,x,0,0,0);
455:   return(0);
456: }

460: /*@
461:    VecSet - Sets all components of a vector to a single scalar value. 

463:    Logically Collective on Vec

465:    Input Parameters:
466: +  x  - the vector
467: -  alpha - the scalar

469:    Output Parameter:
470: .  x  - the vector

472:    Note:
473:    For a vector of dimension n, VecSet() computes
474: $     x[i] = alpha, for i=1,...,n,
475:    so that all vector entries then equal the identical
476:    scalar value, alpha.  Use the more general routine
477:    VecSetValues() to set different vector entries.

479:    You CANNOT call this after you have called VecSetValues() but before you call 
480:    VecAssemblyBegin/End().

482:    Level: beginner

484: .seealso VecSetValues(), VecSetValuesBlocked(), VecSetRandom()

486:    Concepts: vector^setting to constant

488: @*/
489: PetscErrorCode  VecSet(Vec x,PetscScalar alpha)
490: {
491:   PetscReal      val;

497:   if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"You cannot call this after you have called VecSetValues() but\n before you have called VecAssemblyBegin/End()");

500:   PetscLogEventBegin(VEC_Set,x,0,0,0);
501:   (*x->ops->set)(x,alpha);
502:   PetscLogEventEnd(VEC_Set,x,0,0,0);
503:   PetscObjectStateIncrease((PetscObject)x);

505:   /*  norms can be simply set */
506:   val = PetscAbsScalar(alpha);
507:   PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],x->map->N * val);
508:   PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
509:   val = PetscSqrtReal((double)x->map->N) * val;
510:   PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],val);
511:   PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],val);
512:   return(0);
513: }


518: /*@
519:    VecAXPY - Computes y = alpha x + y. 

521:    Logically Collective on Vec

523:    Input Parameters:
524: +  alpha - the scalar
525: -  x, y  - the vectors

527:    Output Parameter:
528: .  y - output vector

530:    Level: intermediate

532:    Notes: x and y MUST be different vectors

534:    Concepts: vector^BLAS
535:    Concepts: BLAS

537: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY()
538: @*/
539: PetscErrorCode  VecAXPY(Vec y,PetscScalar alpha,Vec x)
540: {

550:   if (x == y) SETERRQ(((PetscObject)x)->comm,PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");

553:   PetscLogEventBegin(VEC_AXPY,x,y,0,0);
554:   (*y->ops->axpy)(y,alpha,x);
555:   PetscLogEventEnd(VEC_AXPY,x,y,0,0);
556:   PetscObjectStateIncrease((PetscObject)y);
557:   return(0);
558: }

562: /*@
563:    VecAXPBY - Computes y = alpha x + beta y. 

565:    Logically Collective on Vec

567:    Input Parameters:
568: +  alpha,beta - the scalars
569: -  x, y  - the vectors

571:    Output Parameter:
572: .  y - output vector

574:    Level: intermediate

576:    Notes: x and y MUST be different vectors 

578:    Concepts: BLAS
579:    Concepts: vector^BLAS

581: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY()
582: @*/
583: PetscErrorCode  VecAXPBY(Vec y,PetscScalar alpha,PetscScalar beta,Vec x)
584: {

594:   if (x == y) SETERRQ(((PetscObject)x)->comm,PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");

598:   PetscLogEventBegin(VEC_AXPY,x,y,0,0);
599:   (*y->ops->axpby)(y,alpha,beta,x);
600:   PetscLogEventEnd(VEC_AXPY,x,y,0,0);
601:   PetscObjectStateIncrease((PetscObject)y);
602:   return(0);
603: }

607: /*@
608:    VecAXPBYPCZ - Computes z = alpha x + beta y + gamma z

610:    Logically Collective on Vec

612:    Input Parameters:
613: +  alpha,beta, gamma - the scalars
614: -  x, y, z  - the vectors

616:    Output Parameter:
617: .  z - output vector

619:    Level: intermediate

621:    Notes: x, y and z must be different vectors 

623:    Developer Note:   alpha = 1 or gamma = 1 or gamma = 0.0 are handled as special cases

625:    Concepts: BLAS
626:    Concepts: vector^BLAS

628: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY()
629: @*/
630: PetscErrorCode  VecAXPBYPCZ(Vec z,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec x,Vec y)
631: {

645:   if (x == y || x == z) SETERRQ(((PetscObject)x)->comm,PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
646:   if (y == z) SETERRQ(((PetscObject)y)->comm,PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");

651:   PetscLogEventBegin(VEC_AXPBYPCZ,x,y,z,0);
652:   (*y->ops->axpbypcz)(z,alpha,beta,gamma,x,y);
653:   PetscLogEventEnd(VEC_AXPBYPCZ,x,y,z,0);
654:   PetscObjectStateIncrease((PetscObject)z);
655:   return(0);
656: }

660: /*@
661:    VecAYPX - Computes y = x + alpha y.

663:    Logically Collective on Vec

665:    Input Parameters:
666: +  alpha - the scalar
667: -  x, y  - the vectors

669:    Output Parameter:
670: .  y - output vector

672:    Level: intermediate

674:    Notes: x and y MUST be different vectors

676:    Concepts: vector^BLAS
677:    Concepts: BLAS

679: .seealso: VecAXPY(), VecWAXPY()
680: @*/
681: PetscErrorCode  VecAYPX(Vec y,PetscScalar alpha,Vec x)
682: {

690:   if (x == y) SETERRQ(((PetscObject)x)->comm,PETSC_ERR_ARG_IDN,"x and y must be different vectors");

693:   PetscLogEventBegin(VEC_AYPX,x,y,0,0);
694:    (*y->ops->aypx)(y,alpha,x);
695:   PetscLogEventEnd(VEC_AYPX,x,y,0,0);
696:   PetscObjectStateIncrease((PetscObject)y);
697:   return(0);
698: }


703: /*@
704:    VecWAXPY - Computes w = alpha x + y.

706:    Logically Collective on Vec

708:    Input Parameters:
709: +  alpha - the scalar
710: -  x, y  - the vectors

712:    Output Parameter:
713: .  w - the result

715:    Level: intermediate

717:    Notes: w cannot be either x or y, but x and y can be the same

719:    Concepts: vector^BLAS
720:    Concepts: BLAS

722: .seealso: VecAXPY(), VecAYPX(), VecAXPBY()
723: @*/
724: PetscErrorCode  VecWAXPY(Vec w,PetscScalar alpha,Vec x,Vec y)
725: {

739:   if (w == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector y, suggest VecAXPY()");
740:   if (w == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector x, suggest VecAYPX()");

743:   PetscLogEventBegin(VEC_WAXPY,x,y,w,0);
744:    (*w->ops->waxpy)(w,alpha,x,y);
745:   PetscLogEventEnd(VEC_WAXPY,x,y,w,0);
746:   PetscObjectStateIncrease((PetscObject)w);
747:   return(0);
748: }


753: /*@
754:    VecSetValues - Inserts or adds values into certain locations of a vector. 

756:    Not Collective

758:    Input Parameters:
759: +  x - vector to insert in
760: .  ni - number of elements to add
761: .  ix - indices where to add
762: .  y - array of values
763: -  iora - either INSERT_VALUES or ADD_VALUES, where
764:    ADD_VALUES adds values to any existing entries, and
765:    INSERT_VALUES replaces existing entries with new values

767:    Notes: 
768:    VecSetValues() sets x[ix[i]] = y[i], for i=0,...,ni-1.

770:    Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES 
771:    options cannot be mixed without intervening calls to the assembly
772:    routines.

774:    These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd() 
775:    MUST be called after all calls to VecSetValues() have been completed.

777:    VecSetValues() uses 0-based indices in Fortran as well as in C.

779:    If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE), 
780:    negative indices may be passed in ix. These rows are 
781:    simply ignored. This allows easily inserting element load matrices
782:    with homogeneous Dirchlet boundary conditions that you don't want represented
783:    in the vector.

785:    Level: beginner

787:    Concepts: vector^setting values

789: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesLocal(),
790:            VecSetValue(), VecSetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecGetValues()
791: @*/
792: PetscErrorCode  VecSetValues(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
793: {

801:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
802:   (*x->ops->setvalues)(x,ni,ix,y,iora);
803:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
804:   PetscObjectStateIncrease((PetscObject)x);
805:   return(0);
806: }

810: /*@
811:    VecGetValues - Gets values from certain locations of a vector. Currently 
812:           can only get values on the same processor

814:     Not Collective
815:  
816:    Input Parameters:
817: +  x - vector to get values from
818: .  ni - number of elements to get
819: -  ix - indices where to get them from (in global 1d numbering)

821:    Output Parameter:
822: .   y - array of values

824:    Notes: 
825:    The user provides the allocated array y; it is NOT allocated in this routine

827:    VecGetValues() gets y[i] = x[ix[i]], for i=0,...,ni-1.

829:    VecAssemblyBegin() and VecAssemblyEnd()  MUST be called before calling this

831:    VecGetValues() uses 0-based indices in Fortran as well as in C.

833:    If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
834:    negative indices may be passed in ix. These rows are
835:    simply ignored.

837:    Level: beginner

839:    Concepts: vector^getting values

841: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecGetValuesLocal(),
842:            VecGetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecSetValues()
843: @*/
844: PetscErrorCode  VecGetValues(Vec x,PetscInt ni,const PetscInt ix[],PetscScalar y[])
845: {

853:   (*x->ops->getvalues)(x,ni,ix,y);
854:   return(0);
855: }

859: /*@
860:    VecSetValuesBlocked - Inserts or adds blocks of values into certain locations of a vector. 

862:    Not Collective

864:    Input Parameters:
865: +  x - vector to insert in
866: .  ni - number of blocks to add
867: .  ix - indices where to add in block count, rather than element count
868: .  y - array of values
869: -  iora - either INSERT_VALUES or ADD_VALUES, where
870:    ADD_VALUES adds values to any existing entries, and
871:    INSERT_VALUES replaces existing entries with new values

873:    Notes: 
874:    VecSetValuesBlocked() sets x[bs*ix[i]+j] = y[bs*i+j], 
875:    for j=0,...,bs, for i=0,...,ni-1. where bs was set with VecSetBlockSize().

877:    Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 
878:    options cannot be mixed without intervening calls to the assembly
879:    routines.

881:    These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd() 
882:    MUST be called after all calls to VecSetValuesBlocked() have been completed.

884:    VecSetValuesBlocked() uses 0-based indices in Fortran as well as in C.

886:    Negative indices may be passed in ix, these rows are 
887:    simply ignored. This allows easily inserting element load matrices
888:    with homogeneous Dirchlet boundary conditions that you don't want represented
889:    in the vector.

891:    Level: intermediate

893:    Concepts: vector^setting values blocked

895: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesBlockedLocal(),
896:            VecSetValues()
897: @*/
898: PetscErrorCode  VecSetValuesBlocked(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
899: {

907:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
908:   (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);
909:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
910:   PetscObjectStateIncrease((PetscObject)x);
911:   return(0);
912: }


917: /*@
918:    VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
919:    using a local ordering of the nodes. 

921:    Not Collective

923:    Input Parameters:
924: +  x - vector to insert in
925: .  ni - number of elements to add
926: .  ix - indices where to add
927: .  y - array of values
928: -  iora - either INSERT_VALUES or ADD_VALUES, where
929:    ADD_VALUES adds values to any existing entries, and
930:    INSERT_VALUES replaces existing entries with new values

932:    Level: intermediate

934:    Notes: 
935:    VecSetValuesLocal() sets x[ix[i]] = y[i], for i=0,...,ni-1.

937:    Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES 
938:    options cannot be mixed without intervening calls to the assembly
939:    routines.

941:    These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd() 
942:    MUST be called after all calls to VecSetValuesLocal() have been completed.

944:    VecSetValuesLocal() uses 0-based indices in Fortran as well as in C.

946:    Concepts: vector^setting values with local numbering

948: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetLocalToGlobalMapping(),
949:            VecSetValuesBlockedLocal()
950: @*/
951: PetscErrorCode  VecSetValuesLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
952: {
954:   PetscInt       lixp[128],*lix = lixp;


962:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
963:   if (!x->ops->setvalueslocal) {
964:     if (!x->map->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMapping()");
965:     if (ni > 128) {
966:       PetscMalloc(ni*sizeof(PetscInt),&lix);
967:     }
968:     ISLocalToGlobalMappingApply(x->map->mapping,ni,(PetscInt*)ix,lix);
969:     (*x->ops->setvalues)(x,ni,lix,y,iora);
970:     if (ni > 128) {
971:       PetscFree(lix);
972:     }
973:   } else {
974:     (*x->ops->setvalueslocal)(x,ni,ix,y,iora);
975:   }
976:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
977:   PetscObjectStateIncrease((PetscObject)x);
978:   return(0);
979: }

983: /*@
984:    VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
985:    using a local ordering of the nodes. 

987:    Not Collective

989:    Input Parameters:
990: +  x - vector to insert in
991: .  ni - number of blocks to add
992: .  ix - indices where to add in block count, not element count
993: .  y - array of values
994: -  iora - either INSERT_VALUES or ADD_VALUES, where
995:    ADD_VALUES adds values to any existing entries, and
996:    INSERT_VALUES replaces existing entries with new values

998:    Level: intermediate

1000:    Notes: 
1001:    VecSetValuesBlockedLocal() sets x[bs*ix[i]+j] = y[bs*i+j], 
1002:    for j=0,..bs-1, for i=0,...,ni-1, where bs has been set with VecSetBlockSize().

1004:    Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 
1005:    options cannot be mixed without intervening calls to the assembly
1006:    routines.

1008:    These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd() 
1009:    MUST be called after all calls to VecSetValuesBlockedLocal() have been completed.

1011:    VecSetValuesBlockedLocal() uses 0-based indices in Fortran as well as in C.


1014:    Concepts: vector^setting values blocked with local numbering

1016: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesBlocked(), 
1017:            VecSetLocalToGlobalMappingBlock()
1018: @*/
1019: PetscErrorCode  VecSetValuesBlockedLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
1020: {
1022:   PetscInt       lixp[128],*lix = lixp;

1029:   if (!x->map->bmapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMappingBlock()");
1030:   if (ni > 128) {
1031:     PetscMalloc(ni*sizeof(PetscInt),&lix);
1032:   }

1034:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
1035:   ISLocalToGlobalMappingApply(x->map->bmapping,ni,(PetscInt*)ix,lix);
1036:   (*x->ops->setvaluesblocked)(x,ni,lix,y,iora);
1037:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
1038:   if (ni > 128) {
1039:     PetscFree(lix);
1040:   }
1041:   PetscObjectStateIncrease((PetscObject)x);
1042:   return(0);
1043: }

1047: /*@
1048:    VecMTDot - Computes indefinite vector multiple dot products. 
1049:    That is, it does NOT use the complex conjugate.

1051:    Collective on Vec

1053:    Input Parameters:
1054: +  x - one vector
1055: .  nv - number of vectors
1056: -  y - array of vectors.  Note that vectors are pointers

1058:    Output Parameter:
1059: .  val - array of the dot products

1061:    Notes for Users of Complex Numbers:
1062:    For complex vectors, VecMTDot() computes the indefinite form
1063: $      val = (x,y) = y^T x,
1064:    where y^T denotes the transpose of y.

1066:    Use VecMDot() for the inner product
1067: $      val = (x,y) = y^H x,
1068:    where y^H denotes the conjugate transpose of y.

1070:    Level: intermediate

1072:    Concepts: inner product^multiple
1073:    Concepts: vector^multiple inner products

1075: .seealso: VecMDot(), VecTDot()
1076: @*/
1077: PetscErrorCode  VecMTDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1078: {


1091:   PetscLogEventBegin(VEC_MTDot,x,*y,0,0);
1092:   (*x->ops->mtdot)(x,nv,y,val);
1093:   PetscLogEventEnd(VEC_MTDot,x,*y,0,0);
1094:   return(0);
1095: }

1099: /*@
1100:    VecMDot - Computes vector multiple dot products. 

1102:    Collective on Vec

1104:    Input Parameters:
1105: +  x - one vector
1106: .  nv - number of vectors
1107: -  y - array of vectors. 

1109:    Output Parameter:
1110: .  val - array of the dot products (does not allocate the array)

1112:    Notes for Users of Complex Numbers:
1113:    For complex vectors, VecMDot() computes 
1114: $     val = (x,y) = y^H x,
1115:    where y^H denotes the conjugate transpose of y.

1117:    Use VecMTDot() for the indefinite form
1118: $     val = (x,y) = y^T x,
1119:    where y^T denotes the transpose of y.

1121:    Level: intermediate

1123:    Concepts: inner product^multiple
1124:    Concepts: vector^multiple inner products

1126: .seealso: VecMTDot(), VecDot()
1127: @*/
1128: PetscErrorCode  VecMDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1129: {
1131:   PetscInt       i;

1135:   if (!nv) return(0);
1136:   if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);

1145:   PetscLogEventBarrierBegin(VEC_MDotBarrier,x,*y,0,0,((PetscObject)x)->comm);
1146:   (*x->ops->mdot)(x,nv,y,val);
1147:   PetscLogEventBarrierEnd(VEC_MDotBarrier,x,*y,0,0,((PetscObject)x)->comm);
1148:   for (i=0; i<nv; i++) {
1149:     if (PetscIsInfOrNanScalar(val[i])) SETERRQ1(((PetscObject)x)->comm,PETSC_ERR_FP,"Infinite or not-a-number generated in mdot, entry %D",i);
1150:   }
1151:   return(0);
1152: }

1156: /*@
1157:    VecMAXPY - Computes y = y + sum alpha[j] x[j]

1159:    Logically Collective on Vec

1161:    Input Parameters:
1162: +  nv - number of scalars and x-vectors
1163: .  alpha - array of scalars
1164: .  y - one vector
1165: -  x - array of vectors

1167:    Level: intermediate

1169:    Notes: y cannot be any of the x vectors

1171:    Concepts: BLAS

1173: .seealso: VecAXPY(), VecWAXPY(), VecAYPX()
1174: @*/
1175: PetscErrorCode  VecMAXPY(Vec y,PetscInt nv,const PetscScalar alpha[],Vec x[])
1176: {
1178:   PetscInt       i;

1182:   if (!nv) return(0);
1183:   if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1191:   for (i=0; i<nv; i++) {
1193:   }

1195:   PetscLogEventBegin(VEC_MAXPY,*x,y,0,0);
1196:   (*y->ops->maxpy)(y,nv,alpha,x);
1197:   PetscLogEventEnd(VEC_MAXPY,*x,y,0,0);
1198:   PetscObjectStateIncrease((PetscObject)y);
1199:   return(0);
1200: }

1204: /*@
1205:    VecGetSubVector - Gets a vector representing part of another vector

1207:    Collective on IS (and Vec if nonlocal entries are needed)

1209:    Input Arguments:
1210: + X - vector from which to extract a subvector
1211: - is - index set representing portion of X to extract

1213:    Output Arguments:
1214: . Y - subvector corresponding to is

1216:    Level: advanced

1218:    Notes:
1219:    The subvector Y should be returned with VecRestoreSubVector().

1221:    This function may return a subvector without making a copy, therefore it is not safe to use the original vector while
1222:    modifying the subvector.  Other non-overlapping subvectors can still be obtained from X using this function.

1224: .seealso: MatGetSubMatrix()
1225: @*/
1226: PetscErrorCode  VecGetSubVector(Vec X,IS is,Vec *Y)
1227: {
1229:   Vec            Z;
1230:   PetscInt       state;

1236:   if (X->ops->getsubvector) {
1237:     (*X->ops->getsubvector)(X,is,&Z);
1238:   } else {                      /* Default implementation currently does no caching */
1239:     PetscInt gstart,gend,start;
1240:     PetscBool contiguous,gcontiguous;
1241:     VecGetOwnershipRange(X,&gstart,&gend);
1242:     ISContiguousLocal(is,gstart,gend,&start,&contiguous);
1243:     MPI_Allreduce(&contiguous,&gcontiguous,1,MPI_INT,MPI_LAND,((PetscObject)is)->comm);
1244:     if (gcontiguous) {          /* We can do a no-copy implementation */
1245:       PetscInt n,N;
1246:       PetscScalar *x;
1247:       PetscMPIInt size;
1248:       ISGetLocalSize(is,&n);
1249:       VecGetArray(X,&x);
1250:       MPI_Comm_size(((PetscObject)X)->comm,&size);
1251:       if (size == 1) {
1252:         VecCreateSeqWithArray(((PetscObject)X)->comm,1,n,x+start,&Z);
1253:       } else {
1254:         ISGetSize(is,&N);
1255:         VecCreateMPIWithArray(((PetscObject)X)->comm,1,n,N,x+start,&Z);
1256:       }
1257:       VecRestoreArray(X,&x);
1258:     } else {                    /* Have to create a scatter and do a copy */
1259:       VecScatter scatter;
1260:       PetscInt   n,N;
1261:       ISGetLocalSize(is,&n);
1262:       ISGetSize(is,&N);
1263:       VecCreate(((PetscObject)is)->comm,&Z);
1264:       VecSetSizes(Z,n,N);
1265:       VecSetType(Z,((PetscObject)X)->type_name);
1266:       VecScatterCreate(X,is,Z,PETSC_NULL,&scatter);
1267:       VecScatterBegin(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
1268:       VecScatterEnd(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
1269:       VecScatterDestroy(&scatter);
1270:     }
1271:   }
1272:   /* Record the state when the subvector was gotten so we know whether its values need to be put back */
1273:   if (VecGetSubVectorSavedStateId < 0) {PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId);}
1274:   PetscObjectStateQuery((PetscObject)Z,&state);
1275:   PetscObjectComposedDataSetInt((PetscObject)Z,VecGetSubVectorSavedStateId,state);
1276:   *Y = Z;
1277:   return(0);
1278: }

1282: /*@
1283:    VecRestoreSubVector - Restores a subvector extracted using VecGetSubVector()

1285:    Collective on IS (and Vec if nonlocal entries need to be written)

1287:    Input Arguments:
1288: + X - vector from which subvector was obtained
1289: . is - index set representing the subset of X
1290: - Y - subvector being restored

1292:    Level: advanced

1294: .seealso: VecGetSubVector()
1295: @*/
1296: PetscErrorCode  VecRestoreSubVector(Vec X,IS is,Vec *Y)
1297: {

1305:   if (X->ops->restoresubvector) {
1306:     (*X->ops->restoresubvector)(X,is,Y);
1307:   } else {
1308:     PetscInt savedstate=0,newstate;
1309:     PetscBool valid;
1310:     PetscObjectComposedDataGetInt((PetscObject)*Y,VecGetSubVectorSavedStateId,savedstate,valid);
1311:     PetscObjectStateQuery((PetscObject)*Y,&newstate);
1312:     if (valid && savedstate < newstate) {
1313:       /* We might need to copy entries back, first check whether we have no-copy view */
1314:       PetscInt gstart,gend,start;
1315:       PetscBool contiguous,gcontiguous;
1316:       VecGetOwnershipRange(X,&gstart,&gend);
1317:       ISContiguousLocal(is,gstart,gend,&start,&contiguous);
1318:       MPI_Allreduce(&contiguous,&gcontiguous,1,MPI_INT,MPI_LAND,((PetscObject)is)->comm);
1319:       if (!gcontiguous) SETERRQ(((PetscObject)is)->comm,PETSC_ERR_SUP,"Unhandled case, values have been changed and need to be copied back into X");
1320:     }
1321:     VecDestroy(Y);
1322:   }
1323:   return(0);
1324: }

1326: /*MC
1327:    VecGetArray - Returns a pointer to a contiguous array that contains this 
1328:    processor's portion of the vector data. For the standard PETSc
1329:    vectors, VecGetArray() returns a pointer to the local data array and
1330:    does not use any copies. If the underlying vector data is not stored
1331:    in a contiquous array this routine will copy the data to a contiquous
1332:    array and return a pointer to that. You MUST call VecRestoreArray() 
1333:    when you no longer need access to the array.

1335:    Synopsis:
1336:    PetscErrorCode VecGetArray(Vec x,PetscScalar *a[])

1338:    Not Collective

1340:    Input Parameter:
1341: .  x - the vector

1343:    Output Parameter:
1344: .  a - location to put pointer to the array

1346:    Fortran Note:
1347:    This routine is used differently from Fortran 77
1348: $    Vec         x
1349: $    PetscScalar x_array(1)
1350: $    PetscOffset i_x
1351: $    PetscErrorCode ierr
1352: $       call VecGetArray(x,x_array,i_x,ierr)
1353: $
1354: $   Access first local entry in vector with
1355: $      value = x_array(i_x + 1)
1356: $
1357: $      ...... other code
1358: $       call VecRestoreArray(x,x_array,i_x,ierr)
1359:    For Fortran 90 see VecGetArrayF90()

1361:    See the Fortran chapter of the users manual and 
1362:    petsc/src/snes/examples/tutorials/ex5f.F for details.

1364:    Level: beginner

1366:    Concepts: vector^accessing local values

1368: .seealso: VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(), VecGetArray2d()
1369: M*/


1374: /*@C
1375:    VecGetArrays - Returns a pointer to the arrays in a set of vectors
1376:    that were created by a call to VecDuplicateVecs().  You MUST call
1377:    VecRestoreArrays() when you no longer need access to the array.

1379:    Not Collective

1381:    Input Parameter:
1382: +  x - the vectors
1383: -  n - the number of vectors

1385:    Output Parameter:
1386: .  a - location to put pointer to the array

1388:    Fortran Note:
1389:    This routine is not supported in Fortran.

1391:    Level: intermediate

1393: .seealso: VecGetArray(), VecRestoreArrays()
1394: @*/
1395: PetscErrorCode  VecGetArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1396: {
1398:   PetscInt       i;
1399:   PetscScalar    **q;

1405:   if (n <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must get at least one array n = %D",n);
1406:   PetscMalloc(n*sizeof(PetscScalar*),&q);
1407:   for (i=0; i<n; ++i) {
1408:     VecGetArray(x[i],&q[i]);
1409:   }
1410:   *a = q;
1411:   return(0);
1412: }

1416: /*@C
1417:    VecRestoreArrays - Restores a group of vectors after VecGetArrays()
1418:    has been called.

1420:    Not Collective

1422:    Input Parameters:
1423: +  x - the vector
1424: .  n - the number of vectors
1425: -  a - location of pointer to arrays obtained from VecGetArrays()

1427:    Notes:
1428:    For regular PETSc vectors this routine does not involve any copies. For
1429:    any special vectors that do not store local vector data in a contiguous
1430:    array, this routine will copy the data back into the underlying 
1431:    vector data structure from the arrays obtained with VecGetArrays().

1433:    Fortran Note:
1434:    This routine is not supported in Fortran.

1436:    Level: intermediate

1438: .seealso: VecGetArrays(), VecRestoreArray()
1439: @*/
1440: PetscErrorCode  VecRestoreArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1441: {
1443:   PetscInt       i;
1444:   PetscScalar    **q = *a;


1451:   for(i=0;i<n;++i) {
1452:     VecRestoreArray(x[i],&q[i]);
1453:  }
1454:   PetscFree(q);
1455:   return(0);
1456: }

1458: /*MC
1459:    VecRestoreArray - Restores a vector after VecGetArray() has been called.

1461:    Synopsis:
1462:    PetscErrorCode VecRestoreArray(Vec x,PetscScalar *a[])

1464:    Not Collective

1466:    Input Parameters:
1467: +  x - the vector
1468: -  a - location of pointer to array obtained from VecGetArray()

1470:    Level: beginner

1472:    Notes:
1473:    For regular PETSc vectors this routine does not involve any copies. For
1474:    any special vectors that do not store local vector data in a contiguous
1475:    array, this routine will copy the data back into the underlying 
1476:    vector data structure from the array obtained with VecGetArray().

1478:    This routine actually zeros out the a pointer. This is to prevent accidental
1479:    us of the array after it has been restored. If you pass null for a it will 
1480:    not zero the array pointer a.

1482:    Fortran Note:
1483:    This routine is used differently from Fortran 77
1484: $    Vec         x
1485: $    PetscScalar x_array(1)
1486: $    PetscOffset i_x
1487: $    PetscErrorCode ierr
1488: $       call VecGetArray(x,x_array,i_x,ierr)
1489: $
1490: $   Access first local entry in vector with
1491: $      value = x_array(i_x + 1)
1492: $
1493: $      ...... other code
1494: $       call VecRestoreArray(x,x_array,i_x,ierr)

1496:    See the Fortran chapter of the users manual and 
1497:    petsc/src/snes/examples/tutorials/ex5f.F for details.
1498:    For Fortran 90 see VecRestoreArrayF90()

1500: .seealso: VecGetArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(), VecRestoreArray2d()
1501: M*/

1505: /*@
1506:    VecPlaceArray - Allows one to replace the array in a vector with an
1507:    array provided by the user. This is useful to avoid copying an array
1508:    into a vector.

1510:    Not Collective

1512:    Input Parameters:
1513: +  vec - the vector
1514: -  array - the array

1516:    Notes:
1517:    You can return to the original array with a call to VecResetArray()

1519:    Level: developer

1521: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray()

1523: @*/
1524: PetscErrorCode  VecPlaceArray(Vec vec,const PetscScalar array[])
1525: {

1532:   if (vec->ops->placearray) {
1533:     (*vec->ops->placearray)(vec,array);
1534:   } else SETERRQ(((PetscObject)vec)->comm,PETSC_ERR_SUP,"Cannot place array in this type of vector");
1535:   PetscObjectStateIncrease((PetscObject)vec);
1536:   return(0);
1537: }


1542: /*@C
1543:    VecReplaceArray - Allows one to replace the array in a vector with an
1544:    array provided by the user. This is useful to avoid copying an array
1545:    into a vector.

1547:    Not Collective

1549:    Input Parameters:
1550: +  vec - the vector
1551: -  array - the array

1553:    Notes:
1554:    This permanently replaces the array and frees the memory associated
1555:    with the old array.

1557:    The memory passed in MUST be obtained with PetscMalloc() and CANNOT be
1558:    freed by the user. It will be freed when the vector is destroy. 

1560:    Not supported from Fortran

1562:    Level: developer

1564: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray()

1566: @*/
1567: PetscErrorCode  VecReplaceArray(Vec vec,const PetscScalar array[])
1568: {

1574:   if (vec->ops->replacearray) {
1575:     (*vec->ops->replacearray)(vec,array);
1576:   } else  SETERRQ(((PetscObject)vec)->comm,PETSC_ERR_SUP,"Cannot replace array in this type of vector");
1577:   PetscObjectStateIncrease((PetscObject)vec);
1578:   return(0);
1579: }

1581: /*MC
1582:     VecDuplicateVecsF90 - Creates several vectors of the same type as an existing vector
1583:     and makes them accessible via a Fortran90 pointer.

1585:     Synopsis:
1586:     VecDuplicateVecsF90(Vec x,PetscInt n,{Vec, pointer :: y(:)},integer ierr)

1588:     Collective on Vec

1590:     Input Parameters:
1591: +   x - a vector to mimic
1592: -   n - the number of vectors to obtain

1594:     Output Parameters:
1595: +   y - Fortran90 pointer to the array of vectors
1596: -   ierr - error code

1598:     Example of Usage: 
1599: .vb
1600:     Vec x
1601:     Vec, pointer :: y(:)
1602:     ....
1603:     call VecDuplicateVecsF90(x,2,y,ierr)
1604:     call VecSet(y(2),alpha,ierr)
1605:     call VecSet(y(2),alpha,ierr)
1606:     ....
1607:     call VecDestroyVecsF90(2,y,ierr)
1608: .ve

1610:     Notes:
1611:     Not yet supported for all F90 compilers

1613:     Use VecDestroyVecsF90() to free the space.

1615:     Level: beginner

1617: .seealso:  VecDestroyVecsF90(), VecDuplicateVecs()

1619: M*/

1621: /*MC
1622:     VecRestoreArrayF90 - Restores a vector to a usable state after a call to
1623:     VecGetArrayF90().

1625:     Synopsis:
1626:     VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

1628:     Not collective

1630:     Input Parameters:
1631: +   x - vector
1632: -   xx_v - the Fortran90 pointer to the array

1634:     Output Parameter:
1635: .   ierr - error code

1637:     Example of Usage: 
1638: .vb
1639:     PetscScalar, pointer :: xx_v(:)
1640:     ....
1641:     call VecGetArrayF90(x,xx_v,ierr)
1642:     a = xx_v(3)
1643:     call VecRestoreArrayF90(x,xx_v,ierr)
1644: .ve
1645:    
1646:     Level: beginner

1648: .seealso:  VecGetArrayF90(), VecGetArray(), VecRestoreArray(), UsingFortran

1650: M*/

1652: /*MC
1653:     VecDestroyVecsF90 - Frees a block of vectors obtained with VecDuplicateVecsF90().

1655:     Synopsis:
1656:     VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)

1658:     Collective on Vec

1660:     Input Parameters:
1661: +   n - the number of vectors previously obtained
1662: -   x - pointer to array of vector pointers

1664:     Output Parameter:
1665: .   ierr - error code

1667:     Notes:
1668:     Not yet supported for all F90 compilers

1670:     Level: beginner

1672: .seealso:  VecDestroyVecs(), VecDuplicateVecsF90()

1674: M*/

1676: /*MC
1677:     VecGetArrayF90 - Accesses a vector array from Fortran90. For default PETSc
1678:     vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
1679:     this routine is implementation dependent. You MUST call VecRestoreArrayF90() 
1680:     when you no longer need access to the array.

1682:     Synopsis:
1683:     VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

1685:     Not Collective 

1687:     Input Parameter:
1688: .   x - vector

1690:     Output Parameters:
1691: +   xx_v - the Fortran90 pointer to the array
1692: -   ierr - error code

1694:     Example of Usage: 
1695: .vb
1696:     PetscScalar, pointer :: xx_v(:)
1697:     ....
1698:     call VecGetArrayF90(x,xx_v,ierr)
1699:     a = xx_v(3)
1700:     call VecRestoreArrayF90(x,xx_v,ierr)
1701: .ve

1703:     Level: beginner

1705: .seealso:  VecRestoreArrayF90(), VecGetArray(), VecRestoreArray(), UsingFortran

1707: M*/


1712: /*@C
1713:    VecGetArray2d - Returns a pointer to a 2d contiguous array that contains this 
1714:    processor's portion of the vector data.  You MUST call VecRestoreArray2d() 
1715:    when you no longer need access to the array.

1717:    Not Collective

1719:    Input Parameter:
1720: +  x - the vector
1721: .  m - first dimension of two dimensional array
1722: .  n - second dimension of two dimensional array
1723: .  mstart - first index you will use in first coordinate direction (often 0)
1724: -  nstart - first index in the second coordinate direction (often 0)

1726:    Output Parameter:
1727: .  a - location to put pointer to the array

1729:    Level: developer

1731:   Notes:
1732:    For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
1733:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
1734:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
1735:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
1736:    
1737:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

1739:    Concepts: vector^accessing local values as 2d array

1741: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1742:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1743:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1744: @*/
1745: PetscErrorCode  VecGetArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
1746: {
1748:   PetscInt       i,N;
1749:   PetscScalar    *aa;

1755:   VecGetLocalSize(x,&N);
1756:   if (m*n != N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 2d array dimensions %D by %D",N,m,n);
1757:   VecGetArray(x,&aa);

1759:   PetscMalloc(m*sizeof(PetscScalar*),a);
1760:   for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
1761:   *a -= mstart;
1762:   return(0);
1763: }

1767: /*@C
1768:    VecRestoreArray2d - Restores a vector after VecGetArray2d() has been called.

1770:    Not Collective

1772:    Input Parameters:
1773: +  x - the vector
1774: .  m - first dimension of two dimensional array
1775: .  n - second dimension of the two dimensional array
1776: .  mstart - first index you will use in first coordinate direction (often 0)
1777: .  nstart - first index in the second coordinate direction (often 0)
1778: -  a - location of pointer to array obtained from VecGetArray2d()

1780:    Level: developer

1782:    Notes:
1783:    For regular PETSc vectors this routine does not involve any copies. For
1784:    any special vectors that do not store local vector data in a contiguous
1785:    array, this routine will copy the data back into the underlying 
1786:    vector data structure from the array obtained with VecGetArray().

1788:    This routine actually zeros out the a pointer. 

1790: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1791:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
1792:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1793: @*/
1794: PetscErrorCode  VecRestoreArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
1795: {
1797:   void           *dummy;

1803:   dummy = (void*)(*a + mstart);
1804:   PetscFree(dummy);
1805:   VecRestoreArray(x,PETSC_NULL);
1806:   return(0);
1807: }

1811: /*@C
1812:    VecGetArray1d - Returns a pointer to a 1d contiguous array that contains this 
1813:    processor's portion of the vector data.  You MUST call VecRestoreArray1d() 
1814:    when you no longer need access to the array.

1816:    Not Collective

1818:    Input Parameter:
1819: +  x - the vector
1820: .  m - first dimension of two dimensional array
1821: -  mstart - first index you will use in first coordinate direction (often 0)

1823:    Output Parameter:
1824: .  a - location to put pointer to the array

1826:    Level: developer

1828:   Notes:
1829:    For a vector obtained from DMCreateLocalVector() mstart are likely
1830:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
1831:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). 
1832:    
1833:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

1835: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1836:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1837:           VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1838: @*/
1839: PetscErrorCode  VecGetArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
1840: {
1842:   PetscInt       N;

1848:   VecGetLocalSize(x,&N);
1849:   if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
1850:   VecGetArray(x,a);
1851:   *a  -= mstart;
1852:   return(0);
1853: }

1857: /*@C
1858:    VecRestoreArray1d - Restores a vector after VecGetArray1d() has been called.

1860:    Not Collective

1862:    Input Parameters:
1863: +  x - the vector
1864: .  m - first dimension of two dimensional array
1865: .  mstart - first index you will use in first coordinate direction (often 0)
1866: -  a - location of pointer to array obtained from VecGetArray21()

1868:    Level: developer

1870:    Notes:
1871:    For regular PETSc vectors this routine does not involve any copies. For
1872:    any special vectors that do not store local vector data in a contiguous
1873:    array, this routine will copy the data back into the underlying 
1874:    vector data structure from the array obtained with VecGetArray1d().

1876:    This routine actually zeros out the a pointer. 

1878:    Concepts: vector^accessing local values as 1d array

1880: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1881:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
1882:           VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
1883: @*/
1884: PetscErrorCode  VecRestoreArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
1885: {

1891:   VecRestoreArray(x,PETSC_NULL);
1892:   return(0);
1893: }


1898: /*@C
1899:    VecGetArray3d - Returns a pointer to a 3d contiguous array that contains this 
1900:    processor's portion of the vector data.  You MUST call VecRestoreArray3d() 
1901:    when you no longer need access to the array.

1903:    Not Collective

1905:    Input Parameter:
1906: +  x - the vector
1907: .  m - first dimension of three dimensional array
1908: .  n - second dimension of three dimensional array
1909: .  p - third dimension of three dimensional array
1910: .  mstart - first index you will use in first coordinate direction (often 0)
1911: .  nstart - first index in the second coordinate direction (often 0)
1912: -  pstart - first index in the third coordinate direction (often 0)

1914:    Output Parameter:
1915: .  a - location to put pointer to the array

1917:    Level: developer

1919:   Notes:
1920:    For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
1921:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
1922:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
1923:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
1924:    
1925:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

1927:    Concepts: vector^accessing local values as 3d array

1929: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1930:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1931:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1932: @*/
1933: PetscErrorCode  VecGetArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
1934: {
1936:   PetscInt       i,N,j;
1937:   PetscScalar    *aa,**b;

1943:   VecGetLocalSize(x,&N);
1944:   if (m*n*p != N) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 3d array dimensions %D by %D by %D",N,m,n,p);
1945:   VecGetArray(x,&aa);

1947:   PetscMalloc(m*sizeof(PetscScalar**)+m*n*sizeof(PetscScalar*),a);
1948:   b    = (PetscScalar **)((*a) + m);
1949:   for (i=0; i<m; i++)   (*a)[i] = b + i*n - nstart;
1950:   for (i=0; i<m; i++) {
1951:     for (j=0; j<n; j++) {
1952:       b[i*n+j] = aa + i*n*p + j*p - pstart;
1953:     }
1954:   }
1955:   *a -= mstart;
1956:   return(0);
1957: }

1961: /*@C
1962:    VecRestoreArray3d - Restores a vector after VecGetArray3d() has been called.

1964:    Not Collective

1966:    Input Parameters:
1967: +  x - the vector
1968: .  m - first dimension of three dimensional array
1969: .  n - second dimension of the three dimensional array
1970: .  p - third dimension of the three dimensional array
1971: .  mstart - first index you will use in first coordinate direction (often 0)
1972: .  nstart - first index in the second coordinate direction (often 0)
1973: .  pstart - first index in the third coordinate direction (often 0)
1974: -  a - location of pointer to array obtained from VecGetArray3d()

1976:    Level: developer

1978:    Notes:
1979:    For regular PETSc vectors this routine does not involve any copies. For
1980:    any special vectors that do not store local vector data in a contiguous
1981:    array, this routine will copy the data back into the underlying 
1982:    vector data structure from the array obtained with VecGetArray().

1984:    This routine actually zeros out the a pointer. 

1986: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1987:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
1988:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
1989: @*/
1990: PetscErrorCode  VecRestoreArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
1991: {
1993:   void           *dummy;

1999:   dummy = (void*)(*a + mstart);
2000:   PetscFree(dummy);
2001:   VecRestoreArray(x,PETSC_NULL);
2002:   return(0);
2003: }

2007: /*@C
2008:    VecGetArray4d - Returns a pointer to a 4d contiguous array that contains this 
2009:    processor's portion of the vector data.  You MUST call VecRestoreArray4d() 
2010:    when you no longer need access to the array.

2012:    Not Collective

2014:    Input Parameter:
2015: +  x - the vector
2016: .  m - first dimension of four dimensional array
2017: .  n - second dimension of four dimensional array
2018: .  p - third dimension of four dimensional array
2019: .  q - fourth dimension of four dimensional array
2020: .  mstart - first index you will use in first coordinate direction (often 0)
2021: .  nstart - first index in the second coordinate direction (often 0)
2022: .  pstart - first index in the third coordinate direction (often 0)
2023: -  qstart - first index in the fourth coordinate direction (often 0)

2025:    Output Parameter:
2026: .  a - location to put pointer to the array

2028:    Level: beginner

2030:   Notes:
2031:    For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
2032:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2033:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
2034:    the arguments from DMDAGet[Ghost}Corners() are reversed in the call to VecGetArray3d().
2035:    
2036:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

2038:    Concepts: vector^accessing local values as 3d array

2040: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2041:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2042:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2043: @*/
2044: PetscErrorCode  VecGetArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
2045: {
2047:   PetscInt       i,N,j,k;
2048:   PetscScalar    *aa,***b,**c;

2054:   VecGetLocalSize(x,&N);
2055:   if (m*n*p*q != N) SETERRQ5(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 4d array dimensions %D by %D by %D by %D",N,m,n,p,q);
2056:   VecGetArray(x,&aa);

2058:   PetscMalloc(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p*sizeof(PetscScalar*),a);
2059:   b    = (PetscScalar ***)((*a) + m);
2060:   c    = (PetscScalar **)(b + m*n);
2061:   for (i=0; i<m; i++)   (*a)[i] = b + i*n - nstart;
2062:   for (i=0; i<m; i++) {
2063:     for (j=0; j<n; j++) {
2064:       b[i*n+j] = c + i*n*p + j*p - pstart;
2065:     }
2066:   }
2067:   for (i=0; i<m; i++) {
2068:     for (j=0; j<n; j++) {
2069:       for (k=0; k<p; k++) {
2070:         c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
2071:       }
2072:     }
2073:   }
2074:   *a -= mstart;
2075:   return(0);
2076: }

2080: /*@C
2081:    VecRestoreArray4d - Restores a vector after VecGetArray3d() has been called.

2083:    Not Collective

2085:    Input Parameters:
2086: +  x - the vector
2087: .  m - first dimension of four dimensional array
2088: .  n - second dimension of the four dimensional array
2089: .  p - third dimension of the four dimensional array
2090: .  q - fourth dimension of the four dimensional array
2091: .  mstart - first index you will use in first coordinate direction (often 0)
2092: .  nstart - first index in the second coordinate direction (often 0)
2093: .  pstart - first index in the third coordinate direction (often 0)
2094: .  qstart - first index in the fourth coordinate direction (often 0)
2095: -  a - location of pointer to array obtained from VecGetArray4d()

2097:    Level: beginner

2099:    Notes:
2100:    For regular PETSc vectors this routine does not involve any copies. For
2101:    any special vectors that do not store local vector data in a contiguous
2102:    array, this routine will copy the data back into the underlying 
2103:    vector data structure from the array obtained with VecGetArray().

2105:    This routine actually zeros out the a pointer. 

2107: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2108:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2109:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
2110: @*/
2111: PetscErrorCode  VecRestoreArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
2112: {
2114:   void           *dummy;

2120:   dummy = (void*)(*a + mstart);
2121:   PetscFree(dummy);
2122:   VecRestoreArray(x,PETSC_NULL);
2123:   return(0);
2124: }