Actual source code: rvector.c

  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 <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.

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

 78:    Level: intermediate

 80:    Concepts: inner product
 81:    Concepts: vector^inner product

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


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

107: /*@
108:    VecNorm  - Computes the vector norm.

110:    Collective on Vec

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

118:    Output Parameter:
119: .  val - the norm 

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

126:    Level: intermediate

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

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

138:    Concepts: norm
139:    Concepts: vector^norm

141: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNormAvailable(),
142:           VecNormBegin(), VecNormEnd()

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

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

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

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

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

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

180:    Not Collective

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

188:    Output Parameter:
189: +  available - PETSC_TRUE if the val returned is valid
190: -  val - the norm 

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

197:    Level: intermediate

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

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

209:    Concepts: norm
210:    Concepts: vector^norm

212: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNorm()
213:           VecNormBegin(), VecNormEnd()

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


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

234: /*@
235:    VecNormalize - Normalizes a vector by 2-norm. 

237:    Collective on Vec

239:    Input Parameters:
240: +  x - the vector

242:    Output Parameter:
243: .  x - the normalized vector
244: -  val - the vector norm before normalization

246:    Level: intermediate

248:    Concepts: vector^normalizing
249:    Concepts: normalizing^vector

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

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

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

278:    Collective on Vec

280:    Input Parameter:
281: .  x - the vector

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

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

290:    Returns the smallest index with the maximum value
291:    Level: intermediate

293:    Concepts: maximum^of vector
294:    Concepts: vector^maximum value

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

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

314: /*@
315:    VecMin - Determines the minimum vector component and its location.

317:    Collective on Vec

319:    Input Parameters:
320: .  x - the vector

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

326:    Level: intermediate

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

331:    This returns the smallest index with the minumum value

333:    Concepts: minimum^of vector
334:    Concepts: vector^minimum entry

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

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

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

358:    Collective on Vec

360:    Input Parameters:
361: .  x, y - the vectors

363:    Output Parameter:
364: .  val - the dot product

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

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

375:    Level: intermediate

377:    Concepts: inner product^non-Hermitian
378:    Concepts: vector^inner product
379:    Concepts: non-Hermitian inner product

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


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

404: /*@
405:    VecScale - Scales a vector. 

407:    Not collective on Vec

409:    Input Parameters:
410: +  x - the vector
411: -  alpha - the scalar

413:    Output Parameter:
414: .  x - the scaled vector

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

420:    Level: intermediate

422:    Concepts: vector^scaling
423:    Concepts: scaling^vector

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

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

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

461:    Logically Collective on Vec

463:    Input Parameters:
464: +  x  - the vector
465: -  alpha - the scalar

467:    Output Parameter:
468: .  x  - the vector

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

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

480:    Level: beginner

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

484:    Concepts: vector^setting to constant

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

495:   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()");

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

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


516: /*@
517:    VecAXPY - Computes y = alpha x + y. 

519:    Logically Collective on Vec

521:    Input Parameters:
522: +  alpha - the scalar
523: -  x, y  - the vectors

525:    Output Parameter:
526: .  y - output vector

528:    Level: intermediate

530:    Notes: x and y MUST be different vectors

532:    Concepts: vector^BLAS
533:    Concepts: BLAS

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

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

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

560: /*@
561:    VecAXPBY - Computes y = alpha x + beta y. 

563:    Logically Collective on Vec

565:    Input Parameters:
566: +  alpha,beta - the scalars
567: -  x, y  - the vectors

569:    Output Parameter:
570: .  y - output vector

572:    Level: intermediate

574:    Notes: x and y MUST be different vectors 

576:    Concepts: BLAS
577:    Concepts: vector^BLAS

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

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

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

605: /*@
606:    VecAXPBYPCZ - Computes z = alpha x + beta y + gamma z

608:    Logically Collective on Vec

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

614:    Output Parameter:
615: .  z - output vector

617:    Level: intermediate

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

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

623:    Concepts: BLAS
624:    Concepts: vector^BLAS

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

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

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

658: /*@
659:    VecAYPX - Computes y = x + alpha y.

661:    Logically Collective on Vec

663:    Input Parameters:
664: +  alpha - the scalar
665: -  x, y  - the vectors

667:    Output Parameter:
668: .  y - output vector

670:    Level: intermediate

672:    Notes: x and y MUST be different vectors

674:    Concepts: vector^BLAS
675:    Concepts: BLAS

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

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

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


701: /*@
702:    VecWAXPY - Computes w = alpha x + y.

704:    Logically Collective on Vec

706:    Input Parameters:
707: +  alpha - the scalar
708: -  x, y  - the vectors

710:    Output Parameter:
711: .  w - the result

713:    Level: intermediate

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

717:    Concepts: vector^BLAS
718:    Concepts: BLAS

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

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

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


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

754:    Not Collective

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

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

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

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

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

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

783:    Level: beginner

785:    Concepts: vector^setting values

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

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

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

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

819:    Output Parameter:
820: .   y - array of values

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

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

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

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

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

835:    Level: beginner

837:    Concepts: vector^getting values

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

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

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

860:    Not Collective

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

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

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

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

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

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

889:    Level: intermediate

891:    Concepts: vector^setting values blocked

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

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


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

919:    Not Collective

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

930:    Level: intermediate

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

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

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

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

944:    Concepts: vector^setting values with local numbering

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


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

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

985:    Not Collective

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

996:    Level: intermediate

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

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

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

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


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

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

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

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

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

1049:    Collective on Vec

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

1056:    Output Parameter:
1057: .  val - array of the dot products

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

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

1068:    Level: intermediate

1070:    Concepts: inner product^multiple
1071:    Concepts: vector^multiple inner products

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


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

1097: /*@
1098:    VecMDot - Computes vector multiple dot products. 

1100:    Collective on Vec

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

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

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

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

1119:    Level: intermediate

1121:    Concepts: inner product^multiple
1122:    Concepts: vector^multiple inner products

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

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

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

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

1157:    Logically Collective on Vec

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

1165:    Level: intermediate

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

1169:    Concepts: BLAS

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

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

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

1202: /*@
1203:    VecGetSubVector - Gets a vector representing part of another vector

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

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

1211:    Output Arguments:
1212: . Y - subvector corresponding to is

1214:    Level: advanced

1216:    Notes:
1217:    The subvector Y should be returned with VecRestoreSubVector().

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

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

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

1280: /*@
1281:    VecRestoreSubVector - Restores a subvector extracted using VecGetSubVector()

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

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

1290:    Level: advanced

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

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

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

1333:    Synopsis:
1334:    PetscErrorCode VecGetArray(Vec x,PetscScalar *a[])

1336:    Not Collective

1338:    Input Parameter:
1339: .  x - the vector

1341:    Output Parameter:
1342: .  a - location to put pointer to the array

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

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

1362:    Level: beginner

1364:    Concepts: vector^accessing local values

1366: .seealso: VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(), VecGetArray2d()
1367: M*/


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

1377:    Not Collective

1379:    Input Parameter:
1380: +  x - the vectors
1381: -  n - the number of vectors

1383:    Output Parameter:
1384: .  a - location to put pointer to the array

1386:    Fortran Note:
1387:    This routine is not supported in Fortran.

1389:    Level: intermediate

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

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

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

1418:    Not Collective

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

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

1431:    Fortran Note:
1432:    This routine is not supported in Fortran.

1434:    Level: intermediate

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


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

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

1459:    Synopsis:
1460:    PetscErrorCode VecRestoreArray(Vec x,PetscScalar *a[])

1462:    Not Collective

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

1468:    Level: beginner

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

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

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

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

1498: .seealso: VecGetArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(), VecRestoreArray2d()
1499: M*/

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

1508:    Not Collective

1510:    Input Parameters:
1511: +  vec - the vector
1512: -  array - the array

1514:    Notes:
1515:    You can return to the original array with a call to VecResetArray()

1517:    Level: developer

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

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

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


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

1545:    Not Collective

1547:    Input Parameters:
1548: +  vec - the vector
1549: -  array - the array

1551:    Notes:
1552:    This permanently replaces the array and frees the memory associated
1553:    with the old array.

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

1558:    Not supported from Fortran

1560:    Level: developer

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

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

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

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

1583:     Synopsis:
1584:     VecDuplicateVecsF90(Vec x,int n,{Vec, pointer :: y(:)},integer ierr)

1586:     Collective on Vec

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

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

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

1608:     Notes:
1609:     Not yet supported for all F90 compilers

1611:     Use VecDestroyVecsF90() to free the space.

1613:     Level: beginner

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

1617: M*/

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

1623:     Synopsis:
1624:     VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

1626:     Not collective

1628:     Input Parameters:
1629: +   x - vector
1630: -   xx_v - the Fortran90 pointer to the array

1632:     Output Parameter:
1633: .   ierr - error code

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

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

1648: M*/

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

1653:     Synopsis:
1654:     VecDestroyVecsF90({Vec, pointer :: x(:)},integer n,integer ierr)

1656:     Collective on Vec

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

1662:     Output Parameter:
1663: .   ierr - error code

1665:     Notes:
1666:     Not yet supported for all F90 compilers

1668:     Level: beginner

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

1672: M*/

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

1680:     Synopsis:
1681:     VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

1683:     Not Collective 

1685:     Input Parameter:
1686: .   x - vector

1688:     Output Parameters:
1689: +   xx_v - the Fortran90 pointer to the array
1690: -   ierr - error code

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

1701:     Level: beginner

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

1705: M*/


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

1715:    Not Collective

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

1724:    Output Parameter:
1725: .  a - location to put pointer to the array

1727:    Level: developer

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

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

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

1753:   VecGetLocalSize(x,&N);
1754:   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);
1755:   VecGetArray(x,&aa);

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

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

1768:    Not Collective

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

1778:    Level: developer

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

1786:    This routine actually zeros out the a pointer. 

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

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

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

1814:    Not Collective

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

1821:    Output Parameter:
1822: .  a - location to put pointer to the array

1824:    Level: developer

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

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

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

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

1858:    Not Collective

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

1866:    Level: developer

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

1874:    This routine actually zeros out the a pointer. 

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

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

1889:   VecRestoreArray(x,PETSC_NULL);
1890:   return(0);
1891: }


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

1901:    Not Collective

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

1912:    Output Parameter:
1913: .  a - location to put pointer to the array

1915:    Level: developer

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

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

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

1941:   VecGetLocalSize(x,&N);
1942:   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);
1943:   VecGetArray(x,&aa);

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

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

1962:    Not Collective

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

1974:    Level: developer

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

1982:    This routine actually zeros out the a pointer. 

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

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

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

2010:    Not Collective

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

2023:    Output Parameter:
2024: .  a - location to put pointer to the array

2026:    Level: beginner

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

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

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

2052:   VecGetLocalSize(x,&N);
2053:   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);
2054:   VecGetArray(x,&aa);

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

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

2081:    Not Collective

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

2095:    Level: beginner

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

2103:    This routine actually zeros out the a pointer. 

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

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