Actual source code: rvector.c

petsc-3.12.4 2020-02-04
Report Typos and Errors
  1: /*
  2:      Provides the interface functions for vector operations that have PetscScalar/PetscReal in the signature
  3:    These are the vector functions the user calls.
  4: */
  5:  #include <petsc/private/vecimpl.h>
  6: #if defined(PETSC_HAVE_CUDA)
  7:  #include <../src/vec/vec/impls/dvecimpl.h>
  8:  #include <../src/vec/vec/impls/seq/seqcuda/cudavecimpl.h>
  9: #endif
 10: static PetscInt VecGetSubVectorSavedStateId = -1;

 12: PETSC_EXTERN PetscErrorCode VecValidValues(Vec vec,PetscInt argnum,PetscBool begin)
 13: {
 14: #if defined(PETSC_USE_DEBUG)
 15:   PetscErrorCode    ierr;
 16:   PetscInt          n,i;
 17:   const PetscScalar *x;

 20: #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL)
 21:   if ((vec->petscnative || vec->ops->getarray) && (vec->offloadmask & PETSC_OFFLOAD_CPU)) {
 22: #else
 23:   if (vec->petscnative || vec->ops->getarray) {
 24: #endif
 25:     VecGetLocalSize(vec,&n);
 26:     VecGetArrayRead(vec,&x);
 27:     for (i=0; i<n; i++) {
 28:       if (begin) {
 29:         if (PetscIsInfOrNanScalar(x[i])) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FP,"Vec entry at local location %D is not-a-number or infinite at beginning of function: Parameter number %D",i,argnum);
 30:       } else {
 31:         if (PetscIsInfOrNanScalar(x[i])) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FP,"Vec entry at local location %D is not-a-number or infinite at end of function: Parameter number %D",i,argnum);
 32:       }
 33:     }
 34:     VecRestoreArrayRead(vec,&x);
 35:   }
 36:   return(0);
 37: #else
 38:   return 0;
 39: #endif
 40: }

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

 45:    Logically Collective on Vec

 47:    Input Parameters:
 48: .  x, y  - the vectors

 50:    Output Parameter:
 51: .  max - the result

 53:    Level: advanced

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

 59: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs()
 60: @*/
 61: PetscErrorCode  VecMaxPointwiseDivide(Vec x,Vec y,PetscReal *max)
 62: {

 72:   VecCheckSameSize(x,1,y,2);
 73:   (*x->ops->maxpointwisedivide)(x,y,max);
 74:   return(0);
 75: }

 77: /*@
 78:    VecDot - Computes the vector dot product.

 80:    Collective on Vec

 82:    Input Parameters:
 83: .  x, y - the vectors

 85:    Output Parameter:
 86: .  val - the dot product

 88:    Performance Issues:
 89: $    per-processor memory bandwidth
 90: $    interprocessor latency
 91: $    work load inbalance that causes certain processes to arrive much earlier than others

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

100:    Use VecTDot() for the indefinite form
101: $     val = (x,y) = y^T x,
102:    where y^T denotes the transpose of y.

104:    Level: intermediate


107: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecDotRealPart()
108: @*/
109: PetscErrorCode  VecDot(Vec x,Vec y,PetscScalar *val)
110: {

120:   VecCheckSameSize(x,1,y,2);

122:   PetscLogEventBegin(VEC_Dot,x,y,0,0);
123:   (*x->ops->dot)(x,y,val);
124:   PetscLogEventEnd(VEC_Dot,x,y,0,0);
125:   return(0);
126: }

128: /*@
129:    VecDotRealPart - Computes the real part of the vector dot product.

131:    Collective on Vec

133:    Input Parameters:
134: .  x, y - the vectors

136:    Output Parameter:
137: .  val - the real part of the dot product;

139:    Performance Issues:
140: $    per-processor memory bandwidth
141: $    interprocessor latency
142: $    work load inbalance that causes certain processes to arrive much earlier than others

144:    Notes for Users of Complex Numbers:
145:      See VecDot() for more details on the definition of the dot product for complex numbers

147:      For real numbers this returns the same value as VecDot()

149:      For complex numbers in C^n (that is a vector of n components with a complex number for each component) this is equal to the usual real dot product on the
150:      the space R^{2n} (that is a vector of 2n components with the real or imaginary part of the complex numbers for components)

152:    Developer Note: This is not currently optimized to compute only the real part of the dot product.

154:    Level: intermediate


157: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecDot(), VecDotNorm2()
158: @*/
159: PetscErrorCode  VecDotRealPart(Vec x,Vec y,PetscReal *val)
160: {
162:   PetscScalar    fdot;

165:   VecDot(x,y,&fdot);
166:   *val = PetscRealPart(fdot);
167:   return(0);
168: }

170: /*@
171:    VecNorm  - Computes the vector norm.

173:    Collective on Vec

175:    Input Parameters:
176: +  x - the vector
177: -  type - one of NORM_1, NORM_2, NORM_INFINITY.  Also available
178:           NORM_1_AND_2, which computes both norms and stores them
179:           in a two element array.

181:    Output Parameter:
182: .  val - the norm

184:    Notes:
185: $     NORM_1 denotes sum_i |x_i|
186: $     NORM_2 denotes sqrt(sum_i |x_i|^2)
187: $     NORM_INFINITY denotes max_i |x_i|

189:       For complex numbers NORM_1 will return the traditional 1 norm of the 2 norm of the complex numbers; that is the 1
190:       norm of the absolutely values of the complex entries. In PETSc 3.6 and earlier releases it returned the 1 norm of
191:       the 1 norm of the complex entries (what is returned by the BLAS routine asum()). Both are valid norms but most
192:       people expect the former.

194:    Level: intermediate

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


202: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNormAvailable(),
203:           VecNormBegin(), VecNormEnd()

205: @*/

207: PetscErrorCode  VecNorm(Vec x,NormType type,PetscReal *val)
208: {
209:   PetscBool      flg;


217:   /*
218:    * Cached data?
219:    */
220:   if (type!=NORM_1_AND_2) {
221:     PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,flg);
222:     if (flg) return(0);
223:   }
224:   PetscLogEventBegin(VEC_Norm,x,0,0,0);
225:   (*x->ops->norm)(x,type,val);
226:   PetscLogEventEnd(VEC_Norm,x,0,0,0);
227:   if (type!=NORM_1_AND_2) {
228:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[type],*val);
229:   }
230:   return(0);
231: }

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

236:    Not Collective

238:    Input Parameters:
239: +  x - the vector
240: -  type - one of NORM_1, NORM_2, NORM_INFINITY.  Also available
241:           NORM_1_AND_2, which computes both norms and stores them
242:           in a two element array.

244:    Output Parameter:
245: +  available - PETSC_TRUE if the val returned is valid
246: -  val - the norm

248:    Notes:
249: $     NORM_1 denotes sum_i |x_i|
250: $     NORM_2 denotes sqrt(sum_i (x_i)^2)
251: $     NORM_INFINITY denotes max_i |x_i|

253:    Level: intermediate

255:    Performance Issues:
256: $    per-processor memory bandwidth
257: $    interprocessor latency
258: $    work load inbalance that causes certain processes to arrive much earlier than others

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


266: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNorm()
267:           VecNormBegin(), VecNormEnd()

269: @*/
270: PetscErrorCode  VecNormAvailable(Vec x,NormType type,PetscBool  *available,PetscReal *val)
271: {


279:   *available = PETSC_FALSE;
280:   if (type!=NORM_1_AND_2) {
281:     PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,*available);
282:   }
283:   return(0);
284: }

286: /*@
287:    VecNormalize - Normalizes a vector by 2-norm.

289:    Collective on Vec

291:    Input Parameters:
292: +  x - the vector

294:    Output Parameter:
295: .  x - the normalized vector
296: -  val - the vector norm before normalization

298:    Level: intermediate


301: @*/
302: PetscErrorCode  VecNormalize(Vec x,PetscReal *val)
303: {
305:   PetscReal      norm;

310:   PetscLogEventBegin(VEC_Normalize,x,0,0,0);
311:   VecNorm(x,NORM_2,&norm);
312:   if (norm == 0.0) {
313:     PetscInfo(x,"Vector of zero norm can not be normalized; Returning only the zero norm\n");
314:   } else if (norm != 1.0) {
315:     PetscScalar tmp = 1.0/norm;
316:     VecScale(x,tmp);
317:   }
318:   if (val) *val = norm;
319:   PetscLogEventEnd(VEC_Normalize,x,0,0,0);
320:   return(0);
321: }

323: /*@C
324:    VecMax - Determines the vector component with maximum real part and its location.

326:    Collective on Vec

328:    Input Parameter:
329: .  x - the vector

331:    Output Parameters:
332: +  p - the location of val (pass NULL if you don't want this)
333: -  val - the maximum component

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

338:    Returns the smallest index with the maximum value
339:    Level: intermediate


342: .seealso: VecNorm(), VecMin()
343: @*/
344: PetscErrorCode  VecMax(Vec x,PetscInt *p,PetscReal *val)
345: {

352:   PetscLogEventBegin(VEC_Max,x,0,0,0);
353:   (*x->ops->max)(x,p,val);
354:   PetscLogEventEnd(VEC_Max,x,0,0,0);
355:   return(0);
356: }

358: /*@C
359:    VecMin - Determines the vector component with minimum real part and its location.

361:    Collective on Vec

363:    Input Parameters:
364: .  x - the vector

366:    Output Parameter:
367: +  p - the location of val (pass NULL if you don't want this location)
368: -  val - the minimum component

370:    Level: intermediate

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

375:    This returns the smallest index with the minumum value


378: .seealso: VecMax()
379: @*/
380: PetscErrorCode  VecMin(Vec x,PetscInt *p,PetscReal *val)
381: {

388:   PetscLogEventBegin(VEC_Min,x,0,0,0);
389:   (*x->ops->min)(x,p,val);
390:   PetscLogEventEnd(VEC_Min,x,0,0,0);
391:   return(0);
392: }

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

398:    Collective on Vec

400:    Input Parameters:
401: .  x, y - the vectors

403:    Output Parameter:
404: .  val - the dot product

406:    Notes for Users of Complex Numbers:
407:    For complex vectors, VecTDot() computes the indefinite form
408: $     val = (x,y) = y^T x,
409:    where y^T denotes the transpose of y.

411:    Use VecDot() for the inner product
412: $     val = (x,y) = y^H x,
413:    where y^H denotes the conjugate transpose of y.

415:    Level: intermediate

417: .seealso: VecDot(), VecMTDot()
418: @*/
419: PetscErrorCode  VecTDot(Vec x,Vec y,PetscScalar *val)
420: {

430:   VecCheckSameSize(x,1,y,2);

432:   PetscLogEventBegin(VEC_TDot,x,y,0,0);
433:   (*x->ops->tdot)(x,y,val);
434:   PetscLogEventEnd(VEC_TDot,x,y,0,0);
435:   return(0);
436: }

438: /*@
439:    VecScale - Scales a vector.

441:    Not collective on Vec

443:    Input Parameters:
444: +  x - the vector
445: -  alpha - the scalar

447:    Output Parameter:
448: .  x - the scaled vector

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

454:    Level: intermediate


457: @*/
458: PetscErrorCode  VecScale(Vec x, PetscScalar alpha)
459: {
460:   PetscReal      norms[4] = {0.0,0.0,0.0, 0.0};
461:   PetscBool      flgs[4];
463:   PetscInt       i;

468:   if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
469:   PetscLogEventBegin(VEC_Scale,x,0,0,0);
470:   if (alpha != (PetscScalar)1.0) {
471:     /* get current stashed norms */
472:     for (i=0; i<4; i++) {
473:       PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],norms[i],flgs[i]);
474:     }
475:     (*x->ops->scale)(x,alpha);
476:     PetscObjectStateIncrease((PetscObject)x);
477:     /* put the scaled stashed norms back into the Vec */
478:     for (i=0; i<4; i++) {
479:       if (flgs[i]) {
480:         PetscObjectComposedDataSetReal((PetscObject)x,NormIds[i],PetscAbsScalar(alpha)*norms[i]);
481:       }
482:     }
483:   }
484:   PetscLogEventEnd(VEC_Scale,x,0,0,0);
485:   return(0);
486: }

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

491:    Logically Collective on Vec

493:    Input Parameters:
494: +  x  - the vector
495: -  alpha - the scalar

497:    Output Parameter:
498: .  x  - the vector

500:    Note:
501:    For a vector of dimension n, VecSet() computes
502: $     x[i] = alpha, for i=1,...,n,
503:    so that all vector entries then equal the identical
504:    scalar value, alpha.  Use the more general routine
505:    VecSetValues() to set different vector entries.

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

510:    Level: beginner

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

514: @*/
515: PetscErrorCode  VecSet(Vec x,PetscScalar alpha)
516: {
517:   PetscReal      val;

523:   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()");
525:   VecSetErrorIfLocked(x,1);

527:   PetscLogEventBegin(VEC_Set,x,0,0,0);
528:   (*x->ops->set)(x,alpha);
529:   PetscLogEventEnd(VEC_Set,x,0,0,0);
530:   PetscObjectStateIncrease((PetscObject)x);

532:   /*  norms can be simply set (if |alpha|*N not too large) */
533:   val  = PetscAbsScalar(alpha);
534:   if (x->map->N == 0) {
535:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],0.0l);
536:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],0.0);
537:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],0.0);
538:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],0.0);
539:   } else if (val > PETSC_MAX_REAL/x->map->N) {
540:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
541:   } else {
542:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],x->map->N * val);
543:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
544:     val  = PetscSqrtReal((PetscReal)x->map->N) * val;
545:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],val);
546:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],val);
547:   }
548:   return(0);
549: }


552: /*@
553:    VecAXPY - Computes y = alpha x + y.

555:    Logically Collective on Vec

557:    Input Parameters:
558: +  alpha - the scalar
559: -  x, y  - the vectors

561:    Output Parameter:
562: .  y - output vector

564:    Level: intermediate

566:    Notes:
567:     x and y MUST be different vectors
568:     This routine is optimized for alpha of 0.0, otherwise it calls the BLAS routine

570: $    VecAXPY(y,alpha,x)                   y = alpha x           +      y
571: $    VecAYPX(y,beta,x)                    y =       x           + beta y
572: $    VecAXPBY(y,alpha,beta,x)             y = alpha x           + beta y
573: $    VecWAXPY(w,alpha,x,y)                w = alpha x           +      y
574: $    VecAXPBYPCZ(w,alpha,beta,gamma,x,y)  z = alpha x           + beta y + gamma z
575: $    VecMAXPY(y,nv,alpha[],x[])           y = sum alpha[i] x[i] +      y


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

590:   VecCheckSameSize(x,1,y,3);
591:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
593:   VecSetErrorIfLocked(y,1);

595:   VecLockReadPush(x);
596:   PetscLogEventBegin(VEC_AXPY,x,y,0,0);
597:   (*y->ops->axpy)(y,alpha,x);
598:   PetscLogEventEnd(VEC_AXPY,x,y,0,0);
599:   VecLockReadPop(x);
600:   PetscObjectStateIncrease((PetscObject)y);
601:   return(0);
602: }

604: /*@
605:    VecAXPBY - Computes y = alpha x + beta y.

607:    Logically Collective on Vec

609:    Input Parameters:
610: +  alpha,beta - the scalars
611: -  x, y  - the vectors

613:    Output Parameter:
614: .  y - output vector

616:    Level: intermediate

618:    Notes:
619:     x and y MUST be different vectors
620:     The implementation is optimized for alpha and/or beta values of 0.0 and 1.0


623: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ()
624: @*/
625: PetscErrorCode  VecAXPBY(Vec y,PetscScalar alpha,PetscScalar beta,Vec x)
626: {

635:   VecCheckSameSize(y,1,x,4);
636:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
639:   PetscLogEventBegin(VEC_AXPY,x,y,0,0);
640:   (*y->ops->axpby)(y,alpha,beta,x);
641:   PetscLogEventEnd(VEC_AXPY,x,y,0,0);
642:   PetscObjectStateIncrease((PetscObject)y);
643:   return(0);
644: }

646: /*@
647:    VecAXPBYPCZ - Computes z = alpha x + beta y + gamma z

649:    Logically Collective on Vec

651:    Input Parameters:
652: +  alpha,beta, gamma - the scalars
653: -  x, y, z  - the vectors

655:    Output Parameter:
656: .  z - output vector

658:    Level: intermediate

660:    Notes:
661:     x, y and z must be different vectors
662:     The implementation is optimized for alpha of 1.0 and gamma of 1.0 or 0.0


665: .seealso:  VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBY()
666: @*/
667: PetscErrorCode  VecAXPBYPCZ(Vec z,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec x,Vec y)
668: {

680:   VecCheckSameSize(x,1,y,5);
681:   VecCheckSameSize(x,1,z,6);
682:   if (x == y || x == z) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
683:   if (y == z) SETERRQ(PetscObjectComm((PetscObject)y),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");

688:   PetscLogEventBegin(VEC_AXPBYPCZ,x,y,z,0);
689:   (*y->ops->axpbypcz)(z,alpha,beta,gamma,x,y);
690:   PetscLogEventEnd(VEC_AXPBYPCZ,x,y,z,0);
691:   PetscObjectStateIncrease((PetscObject)z);
692:   return(0);
693: }

695: /*@
696:    VecAYPX - Computes y = x + beta y.

698:    Logically Collective on Vec

700:    Input Parameters:
701: +  beta - the scalar
702: -  x, y  - the vectors

704:    Output Parameter:
705: .  y - output vector

707:    Level: intermediate

709:    Notes:
710:     x and y MUST be different vectors
711:     The implementation is optimized for beta of -1.0, 0.0, and 1.0


714: .seealso:  VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ(), VecAXPBY()
715: @*/
716: PetscErrorCode  VecAYPX(Vec y,PetscScalar beta,Vec x)
717: {

726:   VecCheckSameSize(x,1,y,3);
727:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y must be different vectors");

730:   PetscLogEventBegin(VEC_AYPX,x,y,0,0);
731:    (*y->ops->aypx)(y,beta,x);
732:   PetscLogEventEnd(VEC_AYPX,x,y,0,0);
733:   PetscObjectStateIncrease((PetscObject)y);
734:   return(0);
735: }


738: /*@
739:    VecWAXPY - Computes w = alpha x + y.

741:    Logically Collective on Vec

743:    Input Parameters:
744: +  alpha - the scalar
745: -  x, y  - the vectors

747:    Output Parameter:
748: .  w - the result

750:    Level: intermediate

752:    Notes:
753:     w cannot be either x or y, but x and y can be the same
754:     The implementation is optimzed for alpha of -1.0, 0.0, and 1.0


757: .seealso: VecAXPY(), VecAYPX(), VecAXPBY(), VecMAXPY(), VecAXPBYPCZ()
758: @*/
759: PetscErrorCode  VecWAXPY(Vec w,PetscScalar alpha,Vec x,Vec y)
760: {

772:   VecCheckSameSize(x,3,y,4);
773:   VecCheckSameSize(x,3,w,1);
774:   if (w == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector y, suggest VecAXPY()");
775:   if (w == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector x, suggest VecAYPX()");

778:   PetscLogEventBegin(VEC_WAXPY,x,y,w,0);
779:    (*w->ops->waxpy)(w,alpha,x,y);
780:   PetscLogEventEnd(VEC_WAXPY,x,y,w,0);
781:   PetscObjectStateIncrease((PetscObject)w);
782:   return(0);
783: }


786: /*@C
787:    VecSetValues - Inserts or adds values into certain locations of a vector.

789:    Not Collective

791:    Input Parameters:
792: +  x - vector to insert in
793: .  ni - number of elements to add
794: .  ix - indices where to add
795: .  y - array of values
796: -  iora - either INSERT_VALUES or ADD_VALUES, where
797:    ADD_VALUES adds values to any existing entries, and
798:    INSERT_VALUES replaces existing entries with new values

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

803:    Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
804:    options cannot be mixed without intervening calls to the assembly
805:    routines.

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

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

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

818:    Level: beginner

820: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesLocal(),
821:            VecSetValue(), VecSetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecGetValues()
822: @*/
823: PetscErrorCode  VecSetValues(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
824: {

829:   if (!ni) return(0);
833:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
834:   (*x->ops->setvalues)(x,ni,ix,y,iora);
835:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
836:   PetscObjectStateIncrease((PetscObject)x);
837:   return(0);
838: }

840: /*@
841:    VecGetValues - Gets values from certain locations of a vector. Currently
842:           can only get values on the same processor

844:     Not Collective

846:    Input Parameters:
847: +  x - vector to get values from
848: .  ni - number of elements to get
849: -  ix - indices where to get them from (in global 1d numbering)

851:    Output Parameter:
852: .   y - array of values

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

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

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

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

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

867:    Level: beginner

869: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues()
870: @*/
871: PetscErrorCode  VecGetValues(Vec x,PetscInt ni,const PetscInt ix[],PetscScalar y[])
872: {

877:   if (!ni) return(0);
881:   (*x->ops->getvalues)(x,ni,ix,y);
882:   return(0);
883: }

885: /*@C
886:    VecSetValuesBlocked - Inserts or adds blocks of values into certain locations of a vector.

888:    Not Collective

890:    Input Parameters:
891: +  x - vector to insert in
892: .  ni - number of blocks to add
893: .  ix - indices where to add in block count, rather than element count
894: .  y - array of values
895: -  iora - either INSERT_VALUES or ADD_VALUES, where
896:    ADD_VALUES adds values to any existing entries, and
897:    INSERT_VALUES replaces existing entries with new values

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

903:    Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
904:    options cannot be mixed without intervening calls to the assembly
905:    routines.

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

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

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

917:    Level: intermediate

919: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesBlockedLocal(),
920:            VecSetValues()
921: @*/
922: PetscErrorCode  VecSetValuesBlocked(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
923: {

928:   if (!ni) return(0);
932:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
933:   (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);
934:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
935:   PetscObjectStateIncrease((PetscObject)x);
936:   return(0);
937: }


940: /*@C
941:    VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
942:    using a local ordering of the nodes.

944:    Not Collective

946:    Input Parameters:
947: +  x - vector to insert in
948: .  ni - number of elements to add
949: .  ix - indices where to add
950: .  y - array of values
951: -  iora - either INSERT_VALUES or ADD_VALUES, where
952:    ADD_VALUES adds values to any existing entries, and
953:    INSERT_VALUES replaces existing entries with new values

955:    Level: intermediate

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

960:    Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
961:    options cannot be mixed without intervening calls to the assembly
962:    routines.

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

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

969: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetLocalToGlobalMapping(),
970:            VecSetValuesBlockedLocal()
971: @*/
972: PetscErrorCode  VecSetValuesLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
973: {
975:   PetscInt       lixp[128],*lix = lixp;

979:   if (!ni) return(0);

984:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
985:   if (!x->ops->setvalueslocal) {
986:     if (!x->map->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMapping()");
987:     if (ni > 128) {
988:       PetscMalloc1(ni,&lix);
989:     }
990:     ISLocalToGlobalMappingApply(x->map->mapping,ni,(PetscInt*)ix,lix);
991:     (*x->ops->setvalues)(x,ni,lix,y,iora);
992:     if (ni > 128) {
993:       PetscFree(lix);
994:     }
995:   } else {
996:     (*x->ops->setvalueslocal)(x,ni,ix,y,iora);
997:   }
998:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
999:   PetscObjectStateIncrease((PetscObject)x);
1000:   return(0);
1001: }

1003: /*@
1004:    VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
1005:    using a local ordering of the nodes.

1007:    Not Collective

1009:    Input Parameters:
1010: +  x - vector to insert in
1011: .  ni - number of blocks to add
1012: .  ix - indices where to add in block count, not element count
1013: .  y - array of values
1014: -  iora - either INSERT_VALUES or ADD_VALUES, where
1015:    ADD_VALUES adds values to any existing entries, and
1016:    INSERT_VALUES replaces existing entries with new values

1018:    Level: intermediate

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

1024:    Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1025:    options cannot be mixed without intervening calls to the assembly
1026:    routines.

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

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


1034: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesBlocked(),
1035:            VecSetLocalToGlobalMapping()
1036: @*/
1037: PetscErrorCode  VecSetValuesBlockedLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
1038: {
1040:   PetscInt       lixp[128],*lix = lixp;

1044:   if (!ni) return(0);
1048:   if (ni > 128) {
1049:     PetscMalloc1(ni,&lix);
1050:   }

1052:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
1053:   ISLocalToGlobalMappingApplyBlock(x->map->mapping,ni,(PetscInt*)ix,lix);
1054:   (*x->ops->setvaluesblocked)(x,ni,lix,y,iora);
1055:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
1056:   if (ni > 128) {
1057:     PetscFree(lix);
1058:   }
1059:   PetscObjectStateIncrease((PetscObject)x);
1060:   return(0);
1061: }

1063: /*@
1064:    VecMTDot - Computes indefinite vector multiple dot products.
1065:    That is, it does NOT use the complex conjugate.

1067:    Collective on Vec

1069:    Input Parameters:
1070: +  x - one vector
1071: .  nv - number of vectors
1072: -  y - array of vectors.  Note that vectors are pointers

1074:    Output Parameter:
1075: .  val - array of the dot products

1077:    Notes for Users of Complex Numbers:
1078:    For complex vectors, VecMTDot() computes the indefinite form
1079: $      val = (x,y) = y^T x,
1080:    where y^T denotes the transpose of y.

1082:    Use VecMDot() for the inner product
1083: $      val = (x,y) = y^H x,
1084:    where y^H denotes the conjugate transpose of y.

1086:    Level: intermediate


1089: .seealso: VecMDot(), VecTDot()
1090: @*/
1091: PetscErrorCode  VecMTDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1092: {

1098:   if (!nv) return(0);
1105:   VecCheckSameSize(x,1,*y,3);

1107:   PetscLogEventBegin(VEC_MTDot,x,*y,0,0);
1108:   (*x->ops->mtdot)(x,nv,y,val);
1109:   PetscLogEventEnd(VEC_MTDot,x,*y,0,0);
1110:   return(0);
1111: }

1113: /*@
1114:    VecMDot - Computes vector multiple dot products.

1116:    Collective on Vec

1118:    Input Parameters:
1119: +  x - one vector
1120: .  nv - number of vectors
1121: -  y - array of vectors.

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

1126:    Notes for Users of Complex Numbers:
1127:    For complex vectors, VecMDot() computes
1128: $     val = (x,y) = y^H x,
1129:    where y^H denotes the conjugate transpose of y.

1131:    Use VecMTDot() for the indefinite form
1132: $     val = (x,y) = y^T x,
1133:    where y^T denotes the transpose of y.

1135:    Level: intermediate


1138: .seealso: VecMTDot(), VecDot()
1139: @*/
1140: PetscErrorCode  VecMDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1141: {

1147:   if (!nv) return(0);
1148:   if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1155:   VecCheckSameSize(x,1,*y,3);

1157:   PetscLogEventBegin(VEC_MDot,x,*y,0,0);
1158:   (*x->ops->mdot)(x,nv,y,val);
1159:   PetscLogEventEnd(VEC_MDot,x,*y,0,0);
1160:   return(0);
1161: }

1163: /*@
1164:    VecMAXPY - Computes y = y + sum alpha[i] x[i]

1166:    Logically Collective on Vec

1168:    Input Parameters:
1169: +  nv - number of scalars and x-vectors
1170: .  alpha - array of scalars
1171: .  y - one vector
1172: -  x - array of vectors

1174:    Level: intermediate

1176:    Notes:
1177:     y cannot be any of the x vectors

1179: .seealso:  VecAYPX(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ(), VecAXPBY()
1180: @*/
1181: PetscErrorCode  VecMAXPY(Vec y,PetscInt nv,const PetscScalar alpha[],Vec x[])
1182: {
1184:   PetscInt       i;

1189:   if (!nv) return(0);
1190:   if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1197:   VecCheckSameSize(y,1,*x,4);

1200:   PetscLogEventBegin(VEC_MAXPY,*x,y,0,0);
1201:   (*y->ops->maxpy)(y,nv,alpha,x);
1202:   PetscLogEventEnd(VEC_MAXPY,*x,y,0,0);
1203:   PetscObjectStateIncrease((PetscObject)y);
1204:   return(0);
1205: }

1207: /*@
1208:    VecGetSubVector - Gets a vector representing part of another vector

1210:    Collective on IS

1212:    Input Arguments:
1213: + X - vector from which to extract a subvector
1214: - is - index set representing portion of X to extract

1216:    Output Arguments:
1217: . Y - subvector corresponding to is

1219:    Level: advanced

1221:    Notes:
1222:    The subvector Y should be returned with VecRestoreSubVector().

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

1227: .seealso: MatCreateSubMatrix()
1228: @*/
1229: PetscErrorCode  VecGetSubVector(Vec X,IS is,Vec *Y)
1230: {
1231:   PetscErrorCode   ierr;
1232:   Vec              Z;

1238:   if (X->ops->getsubvector) {
1239:     (*X->ops->getsubvector)(X,is,&Z);
1240:   } else { /* Default implementation currently does no caching */
1241:     PetscInt  gstart,gend,start;
1242:     PetscBool contiguous,gcontiguous;
1243:     VecGetOwnershipRange(X,&gstart,&gend);
1244:     ISContiguousLocal(is,gstart,gend,&start,&contiguous);
1245:     MPIU_Allreduce(&contiguous,&gcontiguous,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));
1246:     if (gcontiguous) { /* We can do a no-copy implementation */
1247:       PetscInt n,N,bs;
1248:       PetscInt state;

1250:       ISGetSize(is,&N);
1251:       ISGetLocalSize(is,&n);
1252:       VecGetBlockSize(X,&bs);
1253:       if (n%bs || bs == 1 || !n) bs = -1; /* Do not decide block size if we do not have to */
1254:       VecLockGet(X,&state);
1255:       if (state) {
1256:         const PetscScalar *x;
1257:         VecGetArrayRead(X,&x);
1258:         VecCreate(PetscObjectComm((PetscObject)X),&Z);
1259:         VecSetType(Z,((PetscObject)X)->type_name);
1260:         VecSetSizes(Z,n,N);
1261:         VecSetBlockSize(Z,bs);
1262:         VecPlaceArray(Z,(PetscScalar*)x+start);
1263:         VecLockReadPush(Z);
1264:         VecRestoreArrayRead(X,&x);
1265:       } else {
1266:         PetscScalar *x;
1267:         VecGetArray(X,&x);
1268:         VecCreate(PetscObjectComm((PetscObject)X),&Z);
1269:         VecSetType(Z,((PetscObject)X)->type_name);
1270:         VecSetSizes(Z,n,N);
1271:         VecSetBlockSize(Z,bs);
1272:         VecPlaceArray(Z,(PetscScalar*)x+start);
1273:         VecRestoreArray(X,&x);
1274:       }
1275:     } else { /* Have to create a scatter and do a copy */
1276:       VecScatter scatter;
1277:       PetscInt   n,N;
1278:       ISGetLocalSize(is,&n);
1279:       ISGetSize(is,&N);
1280:       VecCreate(PetscObjectComm((PetscObject)is),&Z);
1281:       VecSetSizes(Z,n,N);
1282:       VecSetType(Z,((PetscObject)X)->type_name);
1283:       VecScatterCreate(X,is,Z,NULL,&scatter);
1284:       VecScatterBegin(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
1285:       VecScatterEnd(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
1286:       PetscObjectCompose((PetscObject)Z,"VecGetSubVector_Scatter",(PetscObject)scatter);
1287:       VecScatterDestroy(&scatter);
1288:     }
1289:   }
1290:   /* Record the state when the subvector was gotten so we know whether its values need to be put back */
1291:   if (VecGetSubVectorSavedStateId < 0) {PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId);}
1292:   PetscObjectComposedDataSetInt((PetscObject)Z,VecGetSubVectorSavedStateId,1);
1293:   *Y   = Z;
1294:   return(0);
1295: }

1297: /*@
1298:    VecRestoreSubVector - Restores a subvector extracted using VecGetSubVector()

1300:    Collective on IS

1302:    Input Arguments:
1303: + X - vector from which subvector was obtained
1304: . is - index set representing the subset of X
1305: - Y - subvector being restored

1307:    Level: advanced

1309: .seealso: VecGetSubVector()
1310: @*/
1311: PetscErrorCode  VecRestoreSubVector(Vec X,IS is,Vec *Y)
1312: {

1320:   if (X->ops->restoresubvector) {
1321:     (*X->ops->restoresubvector)(X,is,Y);
1322:   } else {
1323:     PETSC_UNUSED PetscObjectState dummystate = 0;
1324:     PetscBool valid;
1325:     PetscObjectComposedDataGetInt((PetscObject)*Y,VecGetSubVectorSavedStateId,dummystate,valid);
1326:     if (!valid) {
1327:       VecScatter scatter;

1329:       PetscObjectQuery((PetscObject)*Y,"VecGetSubVector_Scatter",(PetscObject*)&scatter);
1330:       if (scatter) {
1331:         VecScatterBegin(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);
1332:         VecScatterEnd(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);
1333:       }
1334:     }
1335:     VecDestroy(Y);
1336:   }
1337:   return(0);
1338: }

1340: /*@
1341:    VecGetLocalVectorRead - Maps the local portion of a vector into a
1342:    vector.  You must call VecRestoreLocalVectorRead() when the local
1343:    vector is no longer needed.

1345:    Not collective.

1347:    Input parameter:
1348: .  v - The vector for which the local vector is desired.

1350:    Output parameter:
1351: .  w - Upon exit this contains the local vector.

1353:    Level: beginner

1355:    Notes:
1356:    This function is similar to VecGetArrayRead() which maps the local
1357:    portion into a raw pointer.  VecGetLocalVectorRead() is usually
1358:    almost as efficient as VecGetArrayRead() but in certain circumstances
1359:    VecGetLocalVectorRead() can be much more efficient than
1360:    VecGetArrayRead().  This is because the construction of a contiguous
1361:    array representing the vector data required by VecGetArrayRead() can
1362:    be an expensive operation for certain vector types.  For example, for
1363:    GPU vectors VecGetArrayRead() requires that the data between device
1364:    and host is synchronized.

1366:    Unlike VecGetLocalVector(), this routine is not collective and
1367:    preserves cached information.

1369: .seealso: VecRestoreLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
1370: @*/
1371: PetscErrorCode VecGetLocalVectorRead(Vec v,Vec w)
1372: {
1374:   PetscScalar    *a;

1379:   VecCheckSameLocalSize(v,1,w,2);
1380:   if (v->ops->getlocalvectorread) {
1381:     (*v->ops->getlocalvectorread)(v,w);
1382:   } else {
1383:     VecGetArrayRead(v,(const PetscScalar**)&a);
1384:     VecPlaceArray(w,a);
1385:   }
1386:   return(0);
1387: }

1389: /*@
1390:    VecRestoreLocalVectorRead - Unmaps the local portion of a vector
1391:    previously mapped into a vector using VecGetLocalVectorRead().

1393:    Not collective.

1395:    Input parameter:
1396: +  v - The local portion of this vector was previously mapped into w using VecGetLocalVectorRead().
1397: -  w - The vector into which the local portion of v was mapped.

1399:    Level: beginner

1401: .seealso: VecGetLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
1402: @*/
1403: PetscErrorCode VecRestoreLocalVectorRead(Vec v,Vec w)
1404: {
1406:   PetscScalar    *a;

1411:   if (v->ops->restorelocalvectorread) {
1412:     (*v->ops->restorelocalvectorread)(v,w);
1413:   } else {
1414:     VecGetArrayRead(w,(const PetscScalar**)&a);
1415:     VecRestoreArrayRead(v,(const PetscScalar**)&a);
1416:     VecResetArray(w);
1417:   }
1418:   return(0);
1419: }

1421: /*@
1422:    VecGetLocalVector - Maps the local portion of a vector into a
1423:    vector.

1425:    Collective on v, not collective on w.

1427:    Input parameter:
1428: .  v - The vector for which the local vector is desired.

1430:    Output parameter:
1431: .  w - Upon exit this contains the local vector.

1433:    Level: beginner

1435:    Notes:
1436:    This function is similar to VecGetArray() which maps the local
1437:    portion into a raw pointer.  VecGetLocalVector() is usually about as
1438:    efficient as VecGetArray() but in certain circumstances
1439:    VecGetLocalVector() can be much more efficient than VecGetArray().
1440:    This is because the construction of a contiguous array representing
1441:    the vector data required by VecGetArray() can be an expensive
1442:    operation for certain vector types.  For example, for GPU vectors
1443:    VecGetArray() requires that the data between device and host is
1444:    synchronized.

1446: .seealso: VecRestoreLocalVector(), VecGetLocalVectorRead(), VecGetArrayRead(), VecGetArray()
1447: @*/
1448: PetscErrorCode VecGetLocalVector(Vec v,Vec w)
1449: {
1451:   PetscScalar    *a;

1456:   VecCheckSameLocalSize(v,1,w,2);
1457:   if (v->ops->getlocalvector) {
1458:     (*v->ops->getlocalvector)(v,w);
1459:   } else {
1460:     VecGetArray(v,&a);
1461:     VecPlaceArray(w,a);
1462:   }
1463:   return(0);
1464: }

1466: /*@
1467:    VecRestoreLocalVector - Unmaps the local portion of a vector
1468:    previously mapped into a vector using VecGetLocalVector().

1470:    Logically collective.

1472:    Input parameter:
1473: +  v - The local portion of this vector was previously mapped into w using VecGetLocalVector().
1474: -  w - The vector into which the local portion of v was mapped.

1476:    Level: beginner

1478: .seealso: VecGetLocalVector(), VecGetLocalVectorRead(), VecRestoreLocalVectorRead(), LocalVectorRead(), VecGetArrayRead(), VecGetArray()
1479: @*/
1480: PetscErrorCode VecRestoreLocalVector(Vec v,Vec w)
1481: {
1483:   PetscScalar    *a;

1488:   if (v->ops->restorelocalvector) {
1489:     (*v->ops->restorelocalvector)(v,w);
1490:   } else {
1491:     VecGetArray(w,&a);
1492:     VecRestoreArray(v,&a);
1493:     VecResetArray(w);
1494:   }
1495:   return(0);
1496: }

1498: /*@C
1499:    VecGetArray - Returns a pointer to a contiguous array that contains this
1500:    processor's portion of the vector data. For the standard PETSc
1501:    vectors, VecGetArray() returns a pointer to the local data array and
1502:    does not use any copies. If the underlying vector data is not stored
1503:    in a contiguous array this routine will copy the data to a contiguous
1504:    array and return a pointer to that. You MUST call VecRestoreArray()
1505:    when you no longer need access to the array.

1507:    Logically Collective on Vec

1509:    Input Parameter:
1510: .  x - the vector

1512:    Output Parameter:
1513: .  a - location to put pointer to the array

1515:    Fortran Note:
1516:    This routine is used differently from Fortran 77
1517: $    Vec         x
1518: $    PetscScalar x_array(1)
1519: $    PetscOffset i_x
1520: $    PetscErrorCode ierr
1521: $       call VecGetArray(x,x_array,i_x,ierr)
1522: $
1523: $   Access first local entry in vector with
1524: $      value = x_array(i_x + 1)
1525: $
1526: $      ...... other code
1527: $       call VecRestoreArray(x,x_array,i_x,ierr)
1528:    For Fortran 90 see VecGetArrayF90()

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

1533:    Level: beginner

1535: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
1536:           VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite(), VecRestoreArrayWrite()
1537: @*/
1538: PetscErrorCode VecGetArray(Vec x,PetscScalar **a)
1539: {
1541: #if defined(PETSC_HAVE_VIENNACL)
1542:   PetscBool      is_viennacltype = PETSC_FALSE;
1543: #endif

1547:   VecSetErrorIfLocked(x,1);
1548:   if (x->petscnative) {
1549: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1550:     if (x->offloadmask == PETSC_OFFLOAD_GPU) {
1551: #if defined(PETSC_HAVE_VIENNACL)
1552:       PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
1553:       if (is_viennacltype) {
1554:         VecViennaCLCopyFromGPU(x);
1555:       } else
1556: #endif
1557:       {
1558: #if defined(PETSC_HAVE_CUDA)
1559:         VecCUDACopyFromGPU(x);
1560: #endif
1561:       }
1562:     } else if (x->offloadmask == PETSC_OFFLOAD_UNALLOCATED) {
1563: #if defined(PETSC_HAVE_VIENNACL)
1564:       PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
1565:       if (is_viennacltype) {
1566:         VecViennaCLAllocateCheckHost(x);
1567:       } else
1568: #endif
1569:       {
1570: #if defined(PETSC_HAVE_CUDA)
1571:         VecCUDAAllocateCheckHost(x);
1572: #endif
1573:       }
1574:     }
1575: #endif
1576:     *a = *((PetscScalar**)x->data);
1577:   } else {
1578:     if (x->ops->getarray) {
1579:       (*x->ops->getarray)(x,a);
1580:     } else SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot get array for vector type \"%s\"",((PetscObject)x)->type_name);
1581:   }
1582:   return(0);
1583: }

1585: /*@C
1586:    VecGetArrayInPlace - Like VecGetArray(), but if this is a CUDA vector and it is currently offloaded to GPU,
1587:    the returned pointer will be a GPU pointer to the GPU memory that contains this processor's portion of the
1588:    vector data. Otherwise, it functions as VecGetArray().

1590:    Logically Collective on Vec

1592:    Input Parameter:
1593: .  x - the vector

1595:    Output Parameter:
1596: .  a - location to put pointer to the array

1598:    Level: beginner

1600: .seealso: VecRestoreArrayInPlace(), VecRestoreArrayInPlace(), VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(),
1601:           VecPlaceArray(), VecGetArray2d(), VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite(), VecRestoreArrayWrite()
1602: @*/
1603: PetscErrorCode VecGetArrayInPlace(Vec x,PetscScalar **a)
1604: {

1609:   VecSetErrorIfLocked(x,1);

1611: #if defined(PETSC_HAVE_CUDA)
1612:   if (x->petscnative && (x->offloadmask & PETSC_OFFLOAD_GPU)) { /* Prefer working on GPU when offloadmask is PETSC_OFFLOAD_BOTH */
1613:     PetscBool is_cudatype = PETSC_FALSE;
1614:     PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");
1615:     if (is_cudatype) {
1616:       VecCUDAGetArray(x,a);
1617:       x->offloadmask = PETSC_OFFLOAD_GPU; /* Change the mask once GPU gets write access, don't wait until restore array */
1618:       return(0);
1619:     }
1620:   }
1621: #endif
1622:   VecGetArray(x,a);
1623:   return(0);
1624: }

1626: /*@C
1627:    VecGetArrayWrite - Returns a pointer to a contiguous array that WILL contains this
1628:    processor's portion of the vector data. The values in this array are NOT valid, the routine calling this
1629:    routine is responsible for putting values into the array; any values it does not set will be invalid

1631:    Logically Collective on Vec

1633:    Input Parameter:
1634: .  x - the vector

1636:    Output Parameter:
1637: .  a - location to put pointer to the array

1639:    Level: intermediate

1641:    This is for vectors associate with GPUs, the vector is not copied up before giving access. If you need correct
1642:    values in the array use VecGetArray()

1644:    Concepts: vector^accessing local values

1646: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
1647:           VecGetArrayPair(), VecRestoreArrayPair(), VecGetArray(), VecRestoreArrayWrite()
1648: @*/
1649: PetscErrorCode VecGetArrayWrite(Vec x,PetscScalar **a)
1650: {

1655:   VecSetErrorIfLocked(x,1);
1656:   if (!x->ops->getarraywrite) {
1657:     VecGetArray(x,a);
1658:   } else {
1659:     (*x->ops->getarraywrite)(x,a);
1660:   }
1661:   return(0);
1662: }

1664: /*@C
1665:    VecGetArrayRead - Get read-only pointer to contiguous array containing this processor's portion of the vector data.

1667:    Not Collective

1669:    Input Parameters:
1670: .  x - the vector

1672:    Output Parameter:
1673: .  a - the array

1675:    Level: beginner

1677:    Notes:
1678:    The array must be returned using a matching call to VecRestoreArrayRead().

1680:    Unlike VecGetArray(), this routine is not collective and preserves cached information like vector norms.

1682:    Standard PETSc vectors use contiguous storage so that this routine does not perform a copy.  Other vector
1683:    implementations may require a copy, but must such implementations should cache the contiguous representation so that
1684:    only one copy is performed when this routine is called multiple times in sequence.

1686: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
1687: @*/
1688: PetscErrorCode VecGetArrayRead(Vec x,const PetscScalar **a)
1689: {
1691: #if defined(PETSC_HAVE_VIENNACL)
1692:   PetscBool      is_viennacltype = PETSC_FALSE;
1693: #endif

1697:   if (x->petscnative) {
1698: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1699:     if (x->offloadmask == PETSC_OFFLOAD_GPU) {
1700: #if defined(PETSC_HAVE_VIENNACL)
1701:       PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
1702:       if (is_viennacltype) {
1703:         VecViennaCLCopyFromGPU(x);
1704:       } else
1705: #endif
1706:       {
1707: #if defined(PETSC_HAVE_CUDA)
1708:         VecCUDACopyFromGPU(x);
1709: #endif
1710:       }
1711:     }
1712: #endif
1713:     *a = *((PetscScalar **)x->data);
1714:   } else if (x->ops->getarrayread) {
1715:     (*x->ops->getarrayread)(x,a);
1716:   } else {
1717:     (*x->ops->getarray)(x,(PetscScalar**)a);
1718:   }
1719:   return(0);
1720: }

1722: /*@C
1723:    VecGetArrayReadInPlace - Like VecGetArrayRead(), but if this is a CUDA vector and it is currently offloaded to GPU,
1724:    the returned pointer will be a GPU pointer to the GPU memory that contains this processor's portion of the
1725:    vector data. Otherwise, it functions as VecGetArrayRead().

1727:    Not Collective

1729:    Input Parameters:
1730: .  x - the vector

1732:    Output Parameter:
1733: .  a - the array

1735:    Level: beginner

1737:    Notes:
1738:    The array must be returned using a matching call to VecRestoreArrayReadInPlace().


1741: .seealso: VecRestoreArrayReadInPlace(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayInPlace()
1742: @*/
1743: PetscErrorCode VecGetArrayReadInPlace(Vec x,const PetscScalar **a)
1744: {

1749: #if defined(PETSC_HAVE_CUDA)
1750:   if (x->petscnative && x->offloadmask & PETSC_OFFLOAD_GPU) {
1751:     PetscBool is_cudatype = PETSC_FALSE;
1752:     PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");
1753:     if (is_cudatype) {
1754:       VecCUDAGetArrayRead(x,a);
1755:       return(0);
1756:     }
1757:   }
1758: #endif
1759:   VecGetArrayRead(x,a);
1760:   return(0);
1761: }

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

1768:    Logically Collective on Vec

1770:    Input Parameter:
1771: +  x - the vectors
1772: -  n - the number of vectors

1774:    Output Parameter:
1775: .  a - location to put pointer to the array

1777:    Fortran Note:
1778:    This routine is not supported in Fortran.

1780:    Level: intermediate

1782: .seealso: VecGetArray(), VecRestoreArrays()
1783: @*/
1784: PetscErrorCode  VecGetArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1785: {
1787:   PetscInt       i;
1788:   PetscScalar    **q;

1794:   if (n <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must get at least one array n = %D",n);
1795:   PetscMalloc1(n,&q);
1796:   for (i=0; i<n; ++i) {
1797:     VecGetArray(x[i],&q[i]);
1798:   }
1799:   *a = q;
1800:   return(0);
1801: }

1803: /*@C
1804:    VecRestoreArrays - Restores a group of vectors after VecGetArrays()
1805:    has been called.

1807:    Logically Collective on Vec

1809:    Input Parameters:
1810: +  x - the vector
1811: .  n - the number of vectors
1812: -  a - location of pointer to arrays obtained from VecGetArrays()

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

1820:    Fortran Note:
1821:    This routine is not supported in Fortran.

1823:    Level: intermediate

1825: .seealso: VecGetArrays(), VecRestoreArray()
1826: @*/
1827: PetscErrorCode  VecRestoreArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1828: {
1830:   PetscInt       i;
1831:   PetscScalar    **q = *a;


1838:   for (i=0; i<n; ++i) {
1839:     VecRestoreArray(x[i],&q[i]);
1840:   }
1841:   PetscFree(q);
1842:   return(0);
1843: }

1845: /*@C
1846:    VecRestoreArray - Restores a vector after VecGetArray() has been called.

1848:    Logically Collective on Vec

1850:    Input Parameters:
1851: +  x - the vector
1852: -  a - location of pointer to array obtained from VecGetArray()

1854:    Level: beginner

1856: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
1857:           VecGetArrayPair(), VecRestoreArrayPair()
1858: @*/
1859: PetscErrorCode VecRestoreArray(Vec x,PetscScalar **a)
1860: {

1865:   if (x->petscnative) {
1866: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1867:     x->offloadmask = PETSC_OFFLOAD_CPU;
1868: #endif
1869:   } else {
1870:     (*x->ops->restorearray)(x,a);
1871:   }
1872:   if (a) *a = NULL;
1873:   PetscObjectStateIncrease((PetscObject)x);
1874:   return(0);
1875: }

1877: /*@C
1878:    VecRestoreArrayInPlace - Restores a vector after VecGetArrayInPlace() has been called.

1880:    Logically Collective on Vec

1882:    Input Parameters:
1883: +  x - the vector
1884: -  a - location of pointer to array obtained from VecGetArrayInPlace()

1886:    Level: beginner

1888: .seealso: VecGetArrayInPlace(), VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(),
1889:           VecPlaceArray(), VecRestoreArray2d(), VecGetArrayPair(), VecRestoreArrayPair()
1890: @*/
1891: PetscErrorCode VecRestoreArrayInPlace(Vec x,PetscScalar **a)
1892: {

1897: #if defined(PETSC_HAVE_CUDA)
1898:   if (x->petscnative && x->offloadmask == PETSC_OFFLOAD_GPU) {
1899:     PetscBool is_cudatype = PETSC_FALSE;
1900:     PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");
1901:     if (is_cudatype) {
1902:       VecCUDARestoreArray(x,a);
1903:       return(0);
1904:     }
1905:   }
1906: #endif
1907:   VecRestoreArray(x,a);
1908:   return(0);
1909: }


1912: /*@C
1913:    VecRestoreArrayWrite - Restores a vector after VecGetArrayWrite() has been called.

1915:    Logically Collective on Vec

1917:    Input Parameters:
1918: +  x - the vector
1919: -  a - location of pointer to array obtained from VecGetArray()

1921:    Level: beginner

1923: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
1924:           VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite()
1925: @*/
1926: PetscErrorCode VecRestoreArrayWrite(Vec x,PetscScalar **a)
1927: {

1932:   if (x->petscnative) {
1933: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1934:     x->offloadmask = PETSC_OFFLOAD_CPU;
1935: #endif
1936:   } else {
1937:     if (x->ops->restorearraywrite) {
1938:       (*x->ops->restorearraywrite)(x,a);
1939:     } else {
1940:       (*x->ops->restorearray)(x,a);
1941:     }
1942:   }
1943:   if (a) *a = NULL;
1944:   PetscObjectStateIncrease((PetscObject)x);
1945:   return(0);
1946: }

1948: /*@C
1949:    VecRestoreArrayRead - Restore array obtained with VecGetArrayRead()

1951:    Not Collective

1953:    Input Parameters:
1954: +  vec - the vector
1955: -  array - the array

1957:    Level: beginner

1959: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
1960: @*/
1961: PetscErrorCode VecRestoreArrayRead(Vec x,const PetscScalar **a)
1962: {

1967:   if (x->petscnative) {
1968:     /* nothing */
1969:   } else if (x->ops->restorearrayread) {
1970:     (*x->ops->restorearrayread)(x,a);
1971:   } else {
1972:     (*x->ops->restorearray)(x,(PetscScalar**)a);
1973:   }
1974:   if (a) *a = NULL;
1975:   return(0);
1976: }

1978: /*@C
1979:    VecRestoreArrayReadInPlace - Restore array obtained with VecGetArrayReadInPlace()

1981:    Not Collective

1983:    Input Parameters:
1984: +  vec - the vector
1985: -  array - the array

1987:    Level: beginner

1989: .seealso: VecGetArrayReadInPlace(), VecRestoreArrayInPlace(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
1990: @*/
1991: PetscErrorCode VecRestoreArrayReadInPlace(Vec x,const PetscScalar **a)
1992: {

1996:   VecRestoreArrayRead(x,a);
1997:   return(0);
1998: }

2000: /*@
2001:    VecPlaceArray - Allows one to replace the array in a vector with an
2002:    array provided by the user. This is useful to avoid copying an array
2003:    into a vector.

2005:    Not Collective

2007:    Input Parameters:
2008: +  vec - the vector
2009: -  array - the array

2011:    Notes:
2012:    You can return to the original array with a call to VecResetArray()

2014:    Level: developer

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

2018: @*/
2019: PetscErrorCode  VecPlaceArray(Vec vec,const PetscScalar array[])
2020: {

2027:   if (vec->ops->placearray) {
2028:     (*vec->ops->placearray)(vec,array);
2029:   } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot place array in this type of vector");
2030:   PetscObjectStateIncrease((PetscObject)vec);
2031:   return(0);
2032: }

2034: /*@C
2035:    VecReplaceArray - Allows one to replace the array in a vector with an
2036:    array provided by the user. This is useful to avoid copying an array
2037:    into a vector.

2039:    Not Collective

2041:    Input Parameters:
2042: +  vec - the vector
2043: -  array - the array

2045:    Notes:
2046:    This permanently replaces the array and frees the memory associated
2047:    with the old array.

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

2052:    Not supported from Fortran

2054:    Level: developer

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

2058: @*/
2059: PetscErrorCode  VecReplaceArray(Vec vec,const PetscScalar array[])
2060: {

2066:   if (vec->ops->replacearray) {
2067:     (*vec->ops->replacearray)(vec,array);
2068:   } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot replace array in this type of vector");
2069:   PetscObjectStateIncrease((PetscObject)vec);
2070:   return(0);
2071: }


2074: /*@C
2075:    VecCUDAGetArray - Provides access to the CUDA buffer inside a vector.

2077:    This function has semantics similar to VecGetArray():  the pointer
2078:    returned by this function points to a consistent view of the vector
2079:    data.  This may involve a copy operation of data from the host to the
2080:    device if the data on the device is out of date.  If the device
2081:    memory hasn't been allocated previously it will be allocated as part
2082:    of this function call.  VecCUDAGetArray() assumes that
2083:    the user will modify the vector data.  This is similar to
2084:    intent(inout) in fortran.

2086:    The CUDA device pointer has to be released by calling
2087:    VecCUDARestoreArray().  Upon restoring the vector data
2088:    the data on the host will be marked as out of date.  A subsequent
2089:    access of the host data will thus incur a data transfer from the
2090:    device to the host.


2093:    Input Parameter:
2094: .  v - the vector

2096:    Output Parameter:
2097: .  a - the CUDA device pointer

2099:    Fortran note:
2100:    This function is not currently available from Fortran.

2102:    Level: intermediate

2104: .seealso: VecCUDARestoreArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2105: @*/
2106: PETSC_EXTERN PetscErrorCode VecCUDAGetArray(Vec v, PetscScalar **a)
2107: {
2108: #if defined(PETSC_HAVE_CUDA)
2110: #endif

2114: #if defined(PETSC_HAVE_CUDA)
2115:   *a   = 0;
2116:   VecCUDACopyToGPU(v);
2117:   *a   = ((Vec_CUDA*)v->spptr)->GPUarray;
2118: #endif
2119:   return(0);
2120: }

2122: /*@C
2123:    VecCUDARestoreArray - Restore a CUDA device pointer previously acquired with VecCUDAGetArray().

2125:    This marks the host data as out of date.  Subsequent access to the
2126:    vector data on the host side with for instance VecGetArray() incurs a
2127:    data transfer.

2129:    Input Parameter:
2130: +  v - the vector
2131: -  a - the CUDA device pointer.  This pointer is invalid after
2132:        VecCUDARestoreArray() returns.

2134:    Fortran note:
2135:    This function is not currently available from Fortran.

2137:    Level: intermediate

2139: .seealso: VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2140: @*/
2141: PETSC_EXTERN PetscErrorCode VecCUDARestoreArray(Vec v, PetscScalar **a)
2142: {

2147: #if defined(PETSC_HAVE_CUDA)
2148:   v->offloadmask = PETSC_OFFLOAD_GPU;
2149: #endif

2151:   PetscObjectStateIncrease((PetscObject)v);
2152:   return(0);
2153: }

2155: /*@C
2156:    VecCUDAGetArrayRead - Provides read access to the CUDA buffer inside a vector.

2158:    This function is analogous to VecGetArrayRead():  The pointer
2159:    returned by this function points to a consistent view of the vector
2160:    data.  This may involve a copy operation of data from the host to the
2161:    device if the data on the device is out of date.  If the device
2162:    memory hasn't been allocated previously it will be allocated as part
2163:    of this function call.  VecCUDAGetArrayRead() assumes that the
2164:    user will not modify the vector data.  This is analgogous to
2165:    intent(in) in Fortran.

2167:    The CUDA device pointer has to be released by calling
2168:    VecCUDARestoreArrayRead().  If the data on the host side was
2169:    previously up to date it will remain so, i.e. data on both the device
2170:    and the host is up to date.  Accessing data on the host side does not
2171:    incur a device to host data transfer.

2173:    Input Parameter:
2174: .  v - the vector

2176:    Output Parameter:
2177: .  a - the CUDA pointer.

2179:    Fortran note:
2180:    This function is not currently available from Fortran.

2182:    Level: intermediate

2184: .seealso: VecCUDARestoreArrayRead(), VecCUDAGetArray(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2185: @*/
2186: PETSC_EXTERN PetscErrorCode VecCUDAGetArrayRead(Vec v, const PetscScalar **a)
2187: {
2188: #if defined(PETSC_HAVE_CUDA)
2190: #endif

2194: #if defined(PETSC_HAVE_CUDA)
2195:   *a   = 0;
2196:   VecCUDACopyToGPU(v);
2197:   *a   = ((Vec_CUDA*)v->spptr)->GPUarray;
2198: #endif
2199:   return(0);
2200: }

2202: /*@C
2203:    VecCUDARestoreArrayRead - Restore a CUDA device pointer previously acquired with VecCUDAGetArrayRead().

2205:    If the data on the host side was previously up to date it will remain
2206:    so, i.e. data on both the device and the host is up to date.
2207:    Accessing data on the host side e.g. with VecGetArray() does not
2208:    incur a device to host data transfer.

2210:    Input Parameter:
2211: +  v - the vector
2212: -  a - the CUDA device pointer.  This pointer is invalid after
2213:        VecCUDARestoreArrayRead() returns.

2215:    Fortran note:
2216:    This function is not currently available from Fortran.

2218:    Level: intermediate

2220: .seealso: VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecCUDAGetArray(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2221: @*/
2222: PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayRead(Vec v, const PetscScalar **a)
2223: {
2226:   *a = NULL;
2227:   return(0);
2228: }

2230: /*@C
2231:    VecCUDAGetArrayWrite - Provides write access to the CUDA buffer inside a vector.

2233:    The data pointed to by the device pointer is uninitialized.  The user
2234:    may not read from this data.  Furthermore, the entire array needs to
2235:    be filled by the user to obtain well-defined behaviour.  The device
2236:    memory will be allocated by this function if it hasn't been allocated
2237:    previously.  This is analogous to intent(out) in Fortran.

2239:    The device pointer needs to be released with
2240:    VecCUDARestoreArrayWrite().  When the pointer is released the
2241:    host data of the vector is marked as out of data.  Subsequent access
2242:    of the host data with e.g. VecGetArray() incurs a device to host data
2243:    transfer.


2246:    Input Parameter:
2247: .  v - the vector

2249:    Output Parameter:
2250: .  a - the CUDA pointer

2252:    Fortran note:
2253:    This function is not currently available from Fortran.

2255:    Level: advanced

2257: .seealso: VecCUDARestoreArrayWrite(), VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2258: @*/
2259: PETSC_EXTERN PetscErrorCode VecCUDAGetArrayWrite(Vec v, PetscScalar **a)
2260: {
2261: #if defined(PETSC_HAVE_CUDA)
2263: #endif

2267: #if defined(PETSC_HAVE_CUDA)
2268:   *a   = 0;
2269:   VecCUDAAllocateCheck(v);
2270:   *a   = ((Vec_CUDA*)v->spptr)->GPUarray;
2271: #endif
2272:   return(0);
2273: }

2275: /*@C
2276:    VecCUDARestoreArrayWrite - Restore a CUDA device pointer previously acquired with VecCUDAGetArrayWrite().

2278:    Data on the host will be marked as out of date.  Subsequent access of
2279:    the data on the host side e.g. with VecGetArray() will incur a device
2280:    to host data transfer.

2282:    Input Parameter:
2283: +  v - the vector
2284: -  a - the CUDA device pointer.  This pointer is invalid after
2285:        VecCUDARestoreArrayWrite() returns.

2287:    Fortran note:
2288:    This function is not currently available from Fortran.

2290:    Level: intermediate

2292: .seealso: VecCUDAGetArrayWrite(), VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2293: @*/
2294: PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayWrite(Vec v, PetscScalar **a)
2295: {

2300: #if defined(PETSC_HAVE_CUDA)
2301:   v->offloadmask = PETSC_OFFLOAD_GPU;
2302: #endif

2304:   PetscObjectStateIncrease((PetscObject)v);
2305:   return(0);
2306: }

2308: /*@C
2309:    VecCUDAPlaceArray - Allows one to replace the GPU array in a vector with a
2310:    GPU array provided by the user. This is useful to avoid copying an
2311:    array into a vector.

2313:    Not Collective

2315:    Input Parameters:
2316: +  vec - the vector
2317: -  array - the GPU array

2319:    Notes:
2320:    You can return to the original GPU array with a call to VecCUDAResetArray()
2321:    It is not possible to use VecCUDAPlaceArray() and VecPlaceArray() at the
2322:    same time on the same vector.

2324:    Level: developer

2326: .seealso: VecPlaceArray(), VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray(), VecCUDAResetArray(), VecCUDAReplaceArray()

2328: @*/
2329: PetscErrorCode VecCUDAPlaceArray(Vec vin,PetscScalar *a)
2330: {

2335: #if defined(PETSC_HAVE_CUDA)
2336:   VecCUDACopyToGPU(vin);
2337:   if (((Vec_Seq*)vin->data)->unplacedarray) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"VecCUDAPlaceArray()/VecPlaceArray() was already called on this vector, without a call to VecCUDAResetArray()/VecResetArray()");
2338:   ((Vec_Seq*)vin->data)->unplacedarray  = (PetscScalar *) ((Vec_CUDA*)vin->spptr)->GPUarray; /* save previous GPU array so reset can bring it back */
2339:   ((Vec_CUDA*)vin->spptr)->GPUarray = a;
2340:   vin->offloadmask = PETSC_OFFLOAD_GPU;
2341: #endif
2342:   PetscObjectStateIncrease((PetscObject)vin);
2343:   return(0);
2344: }

2346: /*@C
2347:    VecCUDAReplaceArray - Allows one to replace the GPU array in a vector
2348:    with a GPU array provided by the user. This is useful to avoid copying
2349:    a GPU array into a vector.

2351:    Not Collective

2353:    Input Parameters:
2354: +  vec - the vector
2355: -  array - the GPU array

2357:    Notes:
2358:    This permanently replaces the GPU array and frees the memory associated
2359:    with the old GPU array.

2361:    The memory passed in CANNOT be freed by the user. It will be freed
2362:    when the vector is destroyed.

2364:    Not supported from Fortran

2366:    Level: developer

2368: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray(), VecCUDAResetArray(), VecCUDAPlaceArray(), VecReplaceArray()

2370: @*/
2371: PetscErrorCode VecCUDAReplaceArray(Vec vin,PetscScalar *a)
2372: {
2373: #if defined(PETSC_HAVE_CUDA)
2374:   cudaError_t err;
2375: #endif

2380: #if defined(PETSC_HAVE_CUDA)
2381:   err = cudaFree(((Vec_CUDA*)vin->spptr)->GPUarray);CHKERRCUDA(err);
2382:   ((Vec_CUDA*)vin->spptr)->GPUarray = a;
2383:   vin->offloadmask = PETSC_OFFLOAD_GPU;
2384: #endif
2385:   PetscObjectStateIncrease((PetscObject)vin);
2386:   return(0);
2387: }

2389: /*@C
2390:    VecCUDAResetArray - Resets a vector to use its default memory. Call this
2391:    after the use of VecCUDAPlaceArray().

2393:    Not Collective

2395:    Input Parameters:
2396: .  vec - the vector

2398:    Level: developer

2400: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecPlaceArray(), VecResetArray(), VecCUDAPlaceArray(), VecCUDAReplaceArray()

2402: @*/
2403: PetscErrorCode VecCUDAResetArray(Vec vin)
2404: {

2409: #if defined(PETSC_HAVE_CUDA)
2410:   VecCUDACopyToGPU(vin);
2411:   ((Vec_CUDA*)vin->spptr)->GPUarray = (PetscScalar *) ((Vec_Seq*)vin->data)->unplacedarray;
2412:   ((Vec_Seq*)vin->data)->unplacedarray = 0;
2413:   vin->offloadmask = PETSC_OFFLOAD_GPU;
2414: #endif
2415:   PetscObjectStateIncrease((PetscObject)vin);
2416:   return(0);
2417: }




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

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

2429:     Collective on Vec

2431:     Input Parameters:
2432: +   x - a vector to mimic
2433: -   n - the number of vectors to obtain

2435:     Output Parameters:
2436: +   y - Fortran90 pointer to the array of vectors
2437: -   ierr - error code

2439:     Example of Usage:
2440: .vb
2441: #include <petsc/finclude/petscvec.h>
2442:     use petscvec

2444:     Vec x
2445:     Vec, pointer :: y(:)
2446:     ....
2447:     call VecDuplicateVecsF90(x,2,y,ierr)
2448:     call VecSet(y(2),alpha,ierr)
2449:     call VecSet(y(2),alpha,ierr)
2450:     ....
2451:     call VecDestroyVecsF90(2,y,ierr)
2452: .ve

2454:     Notes:
2455:     Not yet supported for all F90 compilers

2457:     Use VecDestroyVecsF90() to free the space.

2459:     Level: beginner

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

2463: M*/

2465: /*MC
2466:     VecRestoreArrayF90 - Restores a vector to a usable state after a call to
2467:     VecGetArrayF90().

2469:     Synopsis:
2470:     VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

2472:     Logically Collective on Vec

2474:     Input Parameters:
2475: +   x - vector
2476: -   xx_v - the Fortran90 pointer to the array

2478:     Output Parameter:
2479: .   ierr - error code

2481:     Example of Usage:
2482: .vb
2483: #include <petsc/finclude/petscvec.h>
2484:     use petscvec

2486:     PetscScalar, pointer :: xx_v(:)
2487:     ....
2488:     call VecGetArrayF90(x,xx_v,ierr)
2489:     xx_v(3) = a
2490:     call VecRestoreArrayF90(x,xx_v,ierr)
2491: .ve

2493:     Level: beginner

2495: .seealso:  VecGetArrayF90(), VecGetArray(), VecRestoreArray(), UsingFortran, VecRestoreArrayReadF90()

2497: M*/

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

2502:     Synopsis:
2503:     VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)

2505:     Collective on Vec

2507:     Input Parameters:
2508: +   n - the number of vectors previously obtained
2509: -   x - pointer to array of vector pointers

2511:     Output Parameter:
2512: .   ierr - error code

2514:     Notes:
2515:     Not yet supported for all F90 compilers

2517:     Level: beginner

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

2521: M*/

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

2529:     Synopsis:
2530:     VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

2532:     Logically Collective on Vec

2534:     Input Parameter:
2535: .   x - vector

2537:     Output Parameters:
2538: +   xx_v - the Fortran90 pointer to the array
2539: -   ierr - error code

2541:     Example of Usage:
2542: .vb
2543: #include <petsc/finclude/petscvec.h>
2544:     use petscvec

2546:     PetscScalar, pointer :: xx_v(:)
2547:     ....
2548:     call VecGetArrayF90(x,xx_v,ierr)
2549:     xx_v(3) = a
2550:     call VecRestoreArrayF90(x,xx_v,ierr)
2551: .ve

2553:     If you ONLY intend to read entries from the array and not change any entries you should use VecGetArrayReadF90().

2555:     Level: beginner

2557: .seealso:  VecRestoreArrayF90(), VecGetArray(), VecRestoreArray(), VecGetArrayReadF90(), UsingFortran

2559: M*/

2561:  /*MC
2562:     VecGetArrayReadF90 - Accesses a read only array from Fortran90. For default PETSc
2563:     vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
2564:     this routine is implementation dependent. You MUST call VecRestoreArrayReadF90()
2565:     when you no longer need access to the array.

2567:     Synopsis:
2568:     VecGetArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

2570:     Logically Collective on Vec

2572:     Input Parameter:
2573: .   x - vector

2575:     Output Parameters:
2576: +   xx_v - the Fortran90 pointer to the array
2577: -   ierr - error code

2579:     Example of Usage:
2580: .vb
2581: #include <petsc/finclude/petscvec.h>
2582:     use petscvec

2584:     PetscScalar, pointer :: xx_v(:)
2585:     ....
2586:     call VecGetArrayReadF90(x,xx_v,ierr)
2587:     a = xx_v(3)
2588:     call VecRestoreArrayReadF90(x,xx_v,ierr)
2589: .ve

2591:     If you intend to write entries into the array you must use VecGetArrayF90().

2593:     Level: beginner

2595: .seealso:  VecRestoreArrayReadF90(), VecGetArray(), VecRestoreArray(), VecGetArrayRead(), VecRestoreArrayRead(), VecGetArrayF90(), UsingFortran

2597: M*/

2599: /*MC
2600:     VecRestoreArrayReadF90 - Restores a readonly vector to a usable state after a call to
2601:     VecGetArrayReadF90().

2603:     Synopsis:
2604:     VecRestoreArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

2606:     Logically Collective on Vec

2608:     Input Parameters:
2609: +   x - vector
2610: -   xx_v - the Fortran90 pointer to the array

2612:     Output Parameter:
2613: .   ierr - error code

2615:     Example of Usage:
2616: .vb
2617: #include <petsc/finclude/petscvec.h>
2618:     use petscvec

2620:     PetscScalar, pointer :: xx_v(:)
2621:     ....
2622:     call VecGetArrayReadF90(x,xx_v,ierr)
2623:     a = xx_v(3)
2624:     call VecRestoreArrayReadF90(x,xx_v,ierr)
2625: .ve

2627:     Level: beginner

2629: .seealso:  VecGetArrayReadF90(), VecGetArray(), VecRestoreArray(), VecGetArrayRead(), VecRestoreArrayRead(),UsingFortran, VecRestoreArrayF90()

2631: M*/

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

2638:    Logically Collective

2640:    Input Parameter:
2641: +  x - the vector
2642: .  m - first dimension of two dimensional array
2643: .  n - second dimension of two dimensional array
2644: .  mstart - first index you will use in first coordinate direction (often 0)
2645: -  nstart - first index in the second coordinate direction (often 0)

2647:    Output Parameter:
2648: .  a - location to put pointer to the array

2650:    Level: developer

2652:   Notes:
2653:    For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
2654:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2655:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
2656:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().

2658:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

2660: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2661:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2662:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2663: @*/
2664: PetscErrorCode  VecGetArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2665: {
2667:   PetscInt       i,N;
2668:   PetscScalar    *aa;

2674:   VecGetLocalSize(x,&N);
2675:   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);
2676:   VecGetArray(x,&aa);

2678:   PetscMalloc1(m,a);
2679:   for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
2680:   *a -= mstart;
2681:   return(0);
2682: }

2684: /*@C
2685:    VecGetArray2dWrite - Returns a pointer to a 2d contiguous array that will contain this
2686:    processor's portion of the vector data.  You MUST call VecRestoreArray2dWrite()
2687:    when you no longer need access to the array.

2689:    Logically Collective

2691:    Input Parameter:
2692: +  x - the vector
2693: .  m - first dimension of two dimensional array
2694: .  n - second dimension of two dimensional array
2695: .  mstart - first index you will use in first coordinate direction (often 0)
2696: -  nstart - first index in the second coordinate direction (often 0)

2698:    Output Parameter:
2699: .  a - location to put pointer to the array

2701:    Level: developer

2703:   Notes:
2704:    For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
2705:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2706:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
2707:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().

2709:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

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

2713: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2714:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2715:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2716: @*/
2717: PetscErrorCode  VecGetArray2dWrite(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2718: {
2720:   PetscInt       i,N;
2721:   PetscScalar    *aa;

2727:   VecGetLocalSize(x,&N);
2728:   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);
2729:   VecGetArrayWrite(x,&aa);

2731:   PetscMalloc1(m,a);
2732:   for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
2733:   *a -= mstart;
2734:   return(0);
2735: }

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

2740:    Logically Collective

2742:    Input Parameters:
2743: +  x - the vector
2744: .  m - first dimension of two dimensional array
2745: .  n - second dimension of the two dimensional array
2746: .  mstart - first index you will use in first coordinate direction (often 0)
2747: .  nstart - first index in the second coordinate direction (often 0)
2748: -  a - location of pointer to array obtained from VecGetArray2d()

2750:    Level: developer

2752:    Notes:
2753:    For regular PETSc vectors this routine does not involve any copies. For
2754:    any special vectors that do not store local vector data in a contiguous
2755:    array, this routine will copy the data back into the underlying
2756:    vector data structure from the array obtained with VecGetArray().

2758:    This routine actually zeros out the a pointer.

2760: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2761:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2762:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2763: @*/
2764: PetscErrorCode  VecRestoreArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2765: {
2767:   void           *dummy;

2773:   dummy = (void*)(*a + mstart);
2774:   PetscFree(dummy);
2775:   VecRestoreArray(x,NULL);
2776:   return(0);
2777: }

2779: /*@C
2780:    VecRestoreArray2dWrite - Restores a vector after VecGetArray2dWrite() has been called.

2782:    Logically Collective

2784:    Input Parameters:
2785: +  x - the vector
2786: .  m - first dimension of two dimensional array
2787: .  n - second dimension of the two dimensional array
2788: .  mstart - first index you will use in first coordinate direction (often 0)
2789: .  nstart - first index in the second coordinate direction (often 0)
2790: -  a - location of pointer to array obtained from VecGetArray2d()

2792:    Level: developer

2794:    Notes:
2795:    For regular PETSc vectors this routine does not involve any copies. For
2796:    any special vectors that do not store local vector data in a contiguous
2797:    array, this routine will copy the data back into the underlying
2798:    vector data structure from the array obtained with VecGetArray().

2800:    This routine actually zeros out the a pointer.

2802: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2803:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2804:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2805: @*/
2806: PetscErrorCode  VecRestoreArray2dWrite(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2807: {
2809:   void           *dummy;

2815:   dummy = (void*)(*a + mstart);
2816:   PetscFree(dummy);
2817:   VecRestoreArrayWrite(x,NULL);
2818:   return(0);
2819: }

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

2826:    Logically Collective

2828:    Input Parameter:
2829: +  x - the vector
2830: .  m - first dimension of two dimensional array
2831: -  mstart - first index you will use in first coordinate direction (often 0)

2833:    Output Parameter:
2834: .  a - location to put pointer to the array

2836:    Level: developer

2838:   Notes:
2839:    For a vector obtained from DMCreateLocalVector() mstart are likely
2840:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2841:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().

2843:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

2845: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2846:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2847:           VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2848: @*/
2849: PetscErrorCode  VecGetArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2850: {
2852:   PetscInt       N;

2858:   VecGetLocalSize(x,&N);
2859:   if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
2860:   VecGetArray(x,a);
2861:   *a  -= mstart;
2862:   return(0);
2863: }

2865:  /*@C
2866:    VecGetArray1dWrite - Returns a pointer to a 1d contiguous array that will contain this
2867:    processor's portion of the vector data.  You MUST call VecRestoreArray1dWrite()
2868:    when you no longer need access to the array.

2870:    Logically Collective

2872:    Input Parameter:
2873: +  x - the vector
2874: .  m - first dimension of two dimensional array
2875: -  mstart - first index you will use in first coordinate direction (often 0)

2877:    Output Parameter:
2878: .  a - location to put pointer to the array

2880:    Level: developer

2882:   Notes:
2883:    For a vector obtained from DMCreateLocalVector() mstart are likely
2884:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2885:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().

2887:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

2889: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2890:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2891:           VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2892: @*/
2893: PetscErrorCode  VecGetArray1dWrite(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2894: {
2896:   PetscInt       N;

2902:   VecGetLocalSize(x,&N);
2903:   if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
2904:   VecGetArrayWrite(x,a);
2905:   *a  -= mstart;
2906:   return(0);
2907: }

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

2912:    Logically Collective

2914:    Input Parameters:
2915: +  x - the vector
2916: .  m - first dimension of two dimensional array
2917: .  mstart - first index you will use in first coordinate direction (often 0)
2918: -  a - location of pointer to array obtained from VecGetArray21()

2920:    Level: developer

2922:    Notes:
2923:    For regular PETSc vectors this routine does not involve any copies. For
2924:    any special vectors that do not store local vector data in a contiguous
2925:    array, this routine will copy the data back into the underlying
2926:    vector data structure from the array obtained with VecGetArray1d().

2928:    This routine actually zeros out the a pointer.

2930: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2931:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2932:           VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
2933: @*/
2934: PetscErrorCode  VecRestoreArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2935: {

2941:   VecRestoreArray(x,NULL);
2942:   return(0);
2943: }

2945: /*@C
2946:    VecRestoreArray1dWrite - Restores a vector after VecGetArray1dWrite() has been called.

2948:    Logically Collective

2950:    Input Parameters:
2951: +  x - the vector
2952: .  m - first dimension of two dimensional array
2953: .  mstart - first index you will use in first coordinate direction (often 0)
2954: -  a - location of pointer to array obtained from VecGetArray21()

2956:    Level: developer

2958:    Notes:
2959:    For regular PETSc vectors this routine does not involve any copies. For
2960:    any special vectors that do not store local vector data in a contiguous
2961:    array, this routine will copy the data back into the underlying
2962:    vector data structure from the array obtained with VecGetArray1d().

2964:    This routine actually zeros out the a pointer.

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

2968: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2969:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2970:           VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
2971: @*/
2972: PetscErrorCode  VecRestoreArray1dWrite(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2973: {

2979:   VecRestoreArrayWrite(x,NULL);
2980:   return(0);
2981: }

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

2988:    Logically Collective

2990:    Input Parameter:
2991: +  x - the vector
2992: .  m - first dimension of three dimensional array
2993: .  n - second dimension of three dimensional array
2994: .  p - third dimension of three dimensional array
2995: .  mstart - first index you will use in first coordinate direction (often 0)
2996: .  nstart - first index in the second coordinate direction (often 0)
2997: -  pstart - first index in the third coordinate direction (often 0)

2999:    Output Parameter:
3000: .  a - location to put pointer to the array

3002:    Level: developer

3004:   Notes:
3005:    For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3006:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3007:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3008:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().

3010:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

3012: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3013:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3014:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3015: @*/
3016: PetscErrorCode  VecGetArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3017: {
3019:   PetscInt       i,N,j;
3020:   PetscScalar    *aa,**b;

3026:   VecGetLocalSize(x,&N);
3027:   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);
3028:   VecGetArray(x,&aa);

3030:   PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
3031:   b    = (PetscScalar**)((*a) + m);
3032:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3033:   for (i=0; i<m; i++)
3034:     for (j=0; j<n; j++)
3035:       b[i*n+j] = aa + i*n*p + j*p - pstart;

3037:   *a -= mstart;
3038:   return(0);
3039: }

3041: /*@C
3042:    VecGetArray3dWrite - Returns a pointer to a 3d contiguous array that will contain this
3043:    processor's portion of the vector data.  You MUST call VecRestoreArray3dWrite()
3044:    when you no longer need access to the array.

3046:    Logically Collective

3048:    Input Parameter:
3049: +  x - the vector
3050: .  m - first dimension of three dimensional array
3051: .  n - second dimension of three dimensional array
3052: .  p - third dimension of three dimensional array
3053: .  mstart - first index you will use in first coordinate direction (often 0)
3054: .  nstart - first index in the second coordinate direction (often 0)
3055: -  pstart - first index in the third coordinate direction (often 0)

3057:    Output Parameter:
3058: .  a - location to put pointer to the array

3060:    Level: developer

3062:   Notes:
3063:    For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3064:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3065:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3066:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().

3068:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

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

3072: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3073:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3074:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3075: @*/
3076: PetscErrorCode  VecGetArray3dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3077: {
3079:   PetscInt       i,N,j;
3080:   PetscScalar    *aa,**b;

3086:   VecGetLocalSize(x,&N);
3087:   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);
3088:   VecGetArrayWrite(x,&aa);

3090:   PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
3091:   b    = (PetscScalar**)((*a) + m);
3092:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3093:   for (i=0; i<m; i++)
3094:     for (j=0; j<n; j++)
3095:       b[i*n+j] = aa + i*n*p + j*p - pstart;

3097:   *a -= mstart;
3098:   return(0);
3099: }

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

3104:    Logically Collective

3106:    Input Parameters:
3107: +  x - the vector
3108: .  m - first dimension of three dimensional array
3109: .  n - second dimension of the three dimensional array
3110: .  p - third dimension of the three dimensional array
3111: .  mstart - first index you will use in first coordinate direction (often 0)
3112: .  nstart - first index in the second coordinate direction (often 0)
3113: .  pstart - first index in the third coordinate direction (often 0)
3114: -  a - location of pointer to array obtained from VecGetArray3d()

3116:    Level: developer

3118:    Notes:
3119:    For regular PETSc vectors this routine does not involve any copies. For
3120:    any special vectors that do not store local vector data in a contiguous
3121:    array, this routine will copy the data back into the underlying
3122:    vector data structure from the array obtained with VecGetArray().

3124:    This routine actually zeros out the a pointer.

3126: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3127:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3128:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3129: @*/
3130: PetscErrorCode  VecRestoreArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3131: {
3133:   void           *dummy;

3139:   dummy = (void*)(*a + mstart);
3140:   PetscFree(dummy);
3141:   VecRestoreArray(x,NULL);
3142:   return(0);
3143: }

3145: /*@C
3146:    VecRestoreArray3dWrite - Restores a vector after VecGetArray3dWrite() has been called.

3148:    Logically Collective

3150:    Input Parameters:
3151: +  x - the vector
3152: .  m - first dimension of three dimensional array
3153: .  n - second dimension of the three dimensional array
3154: .  p - third dimension of the three dimensional array
3155: .  mstart - first index you will use in first coordinate direction (often 0)
3156: .  nstart - first index in the second coordinate direction (often 0)
3157: .  pstart - first index in the third coordinate direction (often 0)
3158: -  a - location of pointer to array obtained from VecGetArray3d()

3160:    Level: developer

3162:    Notes:
3163:    For regular PETSc vectors this routine does not involve any copies. For
3164:    any special vectors that do not store local vector data in a contiguous
3165:    array, this routine will copy the data back into the underlying
3166:    vector data structure from the array obtained with VecGetArray().

3168:    This routine actually zeros out the a pointer.

3170: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3171:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3172:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3173: @*/
3174: PetscErrorCode  VecRestoreArray3dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3175: {
3177:   void           *dummy;

3183:   dummy = (void*)(*a + mstart);
3184:   PetscFree(dummy);
3185:   VecRestoreArrayWrite(x,NULL);
3186:   return(0);
3187: }

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

3194:    Logically Collective

3196:    Input Parameter:
3197: +  x - the vector
3198: .  m - first dimension of four dimensional array
3199: .  n - second dimension of four dimensional array
3200: .  p - third dimension of four dimensional array
3201: .  q - fourth dimension of four dimensional array
3202: .  mstart - first index you will use in first coordinate direction (often 0)
3203: .  nstart - first index in the second coordinate direction (often 0)
3204: .  pstart - first index in the third coordinate direction (often 0)
3205: -  qstart - first index in the fourth coordinate direction (often 0)

3207:    Output Parameter:
3208: .  a - location to put pointer to the array

3210:    Level: beginner

3212:   Notes:
3213:    For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3214:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3215:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3216:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().

3218:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

3220: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3221:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3222:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3223: @*/
3224: PetscErrorCode  VecGetArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3225: {
3227:   PetscInt       i,N,j,k;
3228:   PetscScalar    *aa,***b,**c;

3234:   VecGetLocalSize(x,&N);
3235:   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);
3236:   VecGetArray(x,&aa);

3238:   PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
3239:   b    = (PetscScalar***)((*a) + m);
3240:   c    = (PetscScalar**)(b + m*n);
3241:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3242:   for (i=0; i<m; i++)
3243:     for (j=0; j<n; j++)
3244:       b[i*n+j] = c + i*n*p + j*p - pstart;
3245:   for (i=0; i<m; i++)
3246:     for (j=0; j<n; j++)
3247:       for (k=0; k<p; k++)
3248:         c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
3249:   *a -= mstart;
3250:   return(0);
3251: }

3253: /*@C
3254:    VecGetArray4dWrite - Returns a pointer to a 4d contiguous array that will contain this
3255:    processor's portion of the vector data.  You MUST call VecRestoreArray4dWrite()
3256:    when you no longer need access to the array.

3258:    Logically Collective

3260:    Input Parameter:
3261: +  x - the vector
3262: .  m - first dimension of four dimensional array
3263: .  n - second dimension of four dimensional array
3264: .  p - third dimension of four dimensional array
3265: .  q - fourth dimension of four dimensional array
3266: .  mstart - first index you will use in first coordinate direction (often 0)
3267: .  nstart - first index in the second coordinate direction (often 0)
3268: .  pstart - first index in the third coordinate direction (often 0)
3269: -  qstart - first index in the fourth coordinate direction (often 0)

3271:    Output Parameter:
3272: .  a - location to put pointer to the array

3274:    Level: beginner

3276:   Notes:
3277:    For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3278:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3279:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3280:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().

3282:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

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

3286: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3287:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3288:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3289: @*/
3290: PetscErrorCode  VecGetArray4dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3291: {
3293:   PetscInt       i,N,j,k;
3294:   PetscScalar    *aa,***b,**c;

3300:   VecGetLocalSize(x,&N);
3301:   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);
3302:   VecGetArrayWrite(x,&aa);

3304:   PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
3305:   b    = (PetscScalar***)((*a) + m);
3306:   c    = (PetscScalar**)(b + m*n);
3307:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3308:   for (i=0; i<m; i++)
3309:     for (j=0; j<n; j++)
3310:       b[i*n+j] = c + i*n*p + j*p - pstart;
3311:   for (i=0; i<m; i++)
3312:     for (j=0; j<n; j++)
3313:       for (k=0; k<p; k++)
3314:         c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
3315:   *a -= mstart;
3316:   return(0);
3317: }

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

3322:    Logically Collective

3324:    Input Parameters:
3325: +  x - the vector
3326: .  m - first dimension of four dimensional array
3327: .  n - second dimension of the four dimensional array
3328: .  p - third dimension of the four dimensional array
3329: .  q - fourth dimension of the four dimensional array
3330: .  mstart - first index you will use in first coordinate direction (often 0)
3331: .  nstart - first index in the second coordinate direction (often 0)
3332: .  pstart - first index in the third coordinate direction (often 0)
3333: .  qstart - first index in the fourth coordinate direction (often 0)
3334: -  a - location of pointer to array obtained from VecGetArray4d()

3336:    Level: beginner

3338:    Notes:
3339:    For regular PETSc vectors this routine does not involve any copies. For
3340:    any special vectors that do not store local vector data in a contiguous
3341:    array, this routine will copy the data back into the underlying
3342:    vector data structure from the array obtained with VecGetArray().

3344:    This routine actually zeros out the a pointer.

3346: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3347:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3348:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3349: @*/
3350: PetscErrorCode  VecRestoreArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3351: {
3353:   void           *dummy;

3359:   dummy = (void*)(*a + mstart);
3360:   PetscFree(dummy);
3361:   VecRestoreArray(x,NULL);
3362:   return(0);
3363: }

3365: /*@C
3366:    VecRestoreArray4dWrite - Restores a vector after VecGetArray3dWrite() has been called.

3368:    Logically Collective

3370:    Input Parameters:
3371: +  x - the vector
3372: .  m - first dimension of four dimensional array
3373: .  n - second dimension of the four dimensional array
3374: .  p - third dimension of the four dimensional array
3375: .  q - fourth dimension of the four dimensional array
3376: .  mstart - first index you will use in first coordinate direction (often 0)
3377: .  nstart - first index in the second coordinate direction (often 0)
3378: .  pstart - first index in the third coordinate direction (often 0)
3379: .  qstart - first index in the fourth coordinate direction (often 0)
3380: -  a - location of pointer to array obtained from VecGetArray4d()

3382:    Level: beginner

3384:    Notes:
3385:    For regular PETSc vectors this routine does not involve any copies. For
3386:    any special vectors that do not store local vector data in a contiguous
3387:    array, this routine will copy the data back into the underlying
3388:    vector data structure from the array obtained with VecGetArray().

3390:    This routine actually zeros out the a pointer.

3392: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3393:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3394:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3395: @*/
3396: PetscErrorCode  VecRestoreArray4dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3397: {
3399:   void           *dummy;

3405:   dummy = (void*)(*a + mstart);
3406:   PetscFree(dummy);
3407:   VecRestoreArrayWrite(x,NULL);
3408:   return(0);
3409: }

3411: /*@C
3412:    VecGetArray2dRead - Returns a pointer to a 2d contiguous array that contains this
3413:    processor's portion of the vector data.  You MUST call VecRestoreArray2dRead()
3414:    when you no longer need access to the array.

3416:    Logically Collective

3418:    Input Parameter:
3419: +  x - the vector
3420: .  m - first dimension of two dimensional array
3421: .  n - second dimension of two dimensional array
3422: .  mstart - first index you will use in first coordinate direction (often 0)
3423: -  nstart - first index in the second coordinate direction (often 0)

3425:    Output Parameter:
3426: .  a - location to put pointer to the array

3428:    Level: developer

3430:   Notes:
3431:    For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
3432:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3433:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3434:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().

3436:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

3438: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3439:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3440:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3441: @*/
3442: PetscErrorCode  VecGetArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3443: {
3444:   PetscErrorCode    ierr;
3445:   PetscInt          i,N;
3446:   const PetscScalar *aa;

3452:   VecGetLocalSize(x,&N);
3453:   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);
3454:   VecGetArrayRead(x,&aa);

3456:   PetscMalloc1(m,a);
3457:   for (i=0; i<m; i++) (*a)[i] = (PetscScalar*) aa + i*n - nstart;
3458:   *a -= mstart;
3459:   return(0);
3460: }

3462: /*@C
3463:    VecRestoreArray2dRead - Restores a vector after VecGetArray2dRead() has been called.

3465:    Logically Collective

3467:    Input Parameters:
3468: +  x - the vector
3469: .  m - first dimension of two dimensional array
3470: .  n - second dimension of the two dimensional array
3471: .  mstart - first index you will use in first coordinate direction (often 0)
3472: .  nstart - first index in the second coordinate direction (often 0)
3473: -  a - location of pointer to array obtained from VecGetArray2d()

3475:    Level: developer

3477:    Notes:
3478:    For regular PETSc vectors this routine does not involve any copies. For
3479:    any special vectors that do not store local vector data in a contiguous
3480:    array, this routine will copy the data back into the underlying
3481:    vector data structure from the array obtained with VecGetArray().

3483:    This routine actually zeros out the a pointer.

3485: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3486:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3487:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3488: @*/
3489: PetscErrorCode  VecRestoreArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3490: {
3492:   void           *dummy;

3498:   dummy = (void*)(*a + mstart);
3499:   PetscFree(dummy);
3500:   VecRestoreArrayRead(x,NULL);
3501:   return(0);
3502: }

3504: /*@C
3505:    VecGetArray1dRead - Returns a pointer to a 1d contiguous array that contains this
3506:    processor's portion of the vector data.  You MUST call VecRestoreArray1dRead()
3507:    when you no longer need access to the array.

3509:    Logically Collective

3511:    Input Parameter:
3512: +  x - the vector
3513: .  m - first dimension of two dimensional array
3514: -  mstart - first index you will use in first coordinate direction (often 0)

3516:    Output Parameter:
3517: .  a - location to put pointer to the array

3519:    Level: developer

3521:   Notes:
3522:    For a vector obtained from DMCreateLocalVector() mstart are likely
3523:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3524:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().

3526:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

3528: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3529:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3530:           VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3531: @*/
3532: PetscErrorCode  VecGetArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3533: {
3535:   PetscInt       N;

3541:   VecGetLocalSize(x,&N);
3542:   if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
3543:   VecGetArrayRead(x,(const PetscScalar**)a);
3544:   *a  -= mstart;
3545:   return(0);
3546: }

3548: /*@C
3549:    VecRestoreArray1dRead - Restores a vector after VecGetArray1dRead() has been called.

3551:    Logically Collective

3553:    Input Parameters:
3554: +  x - the vector
3555: .  m - first dimension of two dimensional array
3556: .  mstart - first index you will use in first coordinate direction (often 0)
3557: -  a - location of pointer to array obtained from VecGetArray21()

3559:    Level: developer

3561:    Notes:
3562:    For regular PETSc vectors this routine does not involve any copies. For
3563:    any special vectors that do not store local vector data in a contiguous
3564:    array, this routine will copy the data back into the underlying
3565:    vector data structure from the array obtained with VecGetArray1dRead().

3567:    This routine actually zeros out the a pointer.

3569: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3570:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3571:           VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
3572: @*/
3573: PetscErrorCode  VecRestoreArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3574: {

3580:   VecRestoreArrayRead(x,NULL);
3581:   return(0);
3582: }


3585: /*@C
3586:    VecGetArray3dRead - Returns a pointer to a 3d contiguous array that contains this
3587:    processor's portion of the vector data.  You MUST call VecRestoreArray3dRead()
3588:    when you no longer need access to the array.

3590:    Logically Collective

3592:    Input Parameter:
3593: +  x - the vector
3594: .  m - first dimension of three dimensional array
3595: .  n - second dimension of three dimensional array
3596: .  p - third dimension of three dimensional array
3597: .  mstart - first index you will use in first coordinate direction (often 0)
3598: .  nstart - first index in the second coordinate direction (often 0)
3599: -  pstart - first index in the third coordinate direction (often 0)

3601:    Output Parameter:
3602: .  a - location to put pointer to the array

3604:    Level: developer

3606:   Notes:
3607:    For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3608:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3609:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3610:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3dRead().

3612:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

3614: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3615:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3616:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3617: @*/
3618: PetscErrorCode  VecGetArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3619: {
3620:   PetscErrorCode    ierr;
3621:   PetscInt          i,N,j;
3622:   const PetscScalar *aa;
3623:   PetscScalar       **b;

3629:   VecGetLocalSize(x,&N);
3630:   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);
3631:   VecGetArrayRead(x,&aa);

3633:   PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
3634:   b    = (PetscScalar**)((*a) + m);
3635:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3636:   for (i=0; i<m; i++)
3637:     for (j=0; j<n; j++)
3638:       b[i*n+j] = (PetscScalar *)aa + i*n*p + j*p - pstart;

3640:   *a -= mstart;
3641:   return(0);
3642: }

3644: /*@C
3645:    VecRestoreArray3dRead - Restores a vector after VecGetArray3dRead() has been called.

3647:    Logically Collective

3649:    Input Parameters:
3650: +  x - the vector
3651: .  m - first dimension of three dimensional array
3652: .  n - second dimension of the three dimensional array
3653: .  p - third dimension of the three dimensional array
3654: .  mstart - first index you will use in first coordinate direction (often 0)
3655: .  nstart - first index in the second coordinate direction (often 0)
3656: .  pstart - first index in the third coordinate direction (often 0)
3657: -  a - location of pointer to array obtained from VecGetArray3dRead()

3659:    Level: developer

3661:    Notes:
3662:    For regular PETSc vectors this routine does not involve any copies. For
3663:    any special vectors that do not store local vector data in a contiguous
3664:    array, this routine will copy the data back into the underlying
3665:    vector data structure from the array obtained with VecGetArray().

3667:    This routine actually zeros out the a pointer.

3669: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3670:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3671:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3672: @*/
3673: PetscErrorCode  VecRestoreArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3674: {
3676:   void           *dummy;

3682:   dummy = (void*)(*a + mstart);
3683:   PetscFree(dummy);
3684:   VecRestoreArrayRead(x,NULL);
3685:   return(0);
3686: }

3688: /*@C
3689:    VecGetArray4dRead - Returns a pointer to a 4d contiguous array that contains this
3690:    processor's portion of the vector data.  You MUST call VecRestoreArray4dRead()
3691:    when you no longer need access to the array.

3693:    Logically Collective

3695:    Input Parameter:
3696: +  x - the vector
3697: .  m - first dimension of four dimensional array
3698: .  n - second dimension of four dimensional array
3699: .  p - third dimension of four dimensional array
3700: .  q - fourth dimension of four dimensional array
3701: .  mstart - first index you will use in first coordinate direction (often 0)
3702: .  nstart - first index in the second coordinate direction (often 0)
3703: .  pstart - first index in the third coordinate direction (often 0)
3704: -  qstart - first index in the fourth coordinate direction (often 0)

3706:    Output Parameter:
3707: .  a - location to put pointer to the array

3709:    Level: beginner

3711:   Notes:
3712:    For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3713:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3714:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3715:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().

3717:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

3719: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3720:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3721:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3722: @*/
3723: PetscErrorCode  VecGetArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3724: {
3725:   PetscErrorCode    ierr;
3726:   PetscInt          i,N,j,k;
3727:   const PetscScalar *aa;
3728:   PetscScalar       ***b,**c;

3734:   VecGetLocalSize(x,&N);
3735:   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);
3736:   VecGetArrayRead(x,&aa);

3738:   PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
3739:   b    = (PetscScalar***)((*a) + m);
3740:   c    = (PetscScalar**)(b + m*n);
3741:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3742:   for (i=0; i<m; i++)
3743:     for (j=0; j<n; j++)
3744:       b[i*n+j] = c + i*n*p + j*p - pstart;
3745:   for (i=0; i<m; i++)
3746:     for (j=0; j<n; j++)
3747:       for (k=0; k<p; k++)
3748:         c[i*n*p+j*p+k] = (PetscScalar*) aa + i*n*p*q + j*p*q + k*q - qstart;
3749:   *a -= mstart;
3750:   return(0);
3751: }

3753: /*@C
3754:    VecRestoreArray4dRead - Restores a vector after VecGetArray3d() has been called.

3756:    Logically Collective

3758:    Input Parameters:
3759: +  x - the vector
3760: .  m - first dimension of four dimensional array
3761: .  n - second dimension of the four dimensional array
3762: .  p - third dimension of the four dimensional array
3763: .  q - fourth dimension of the four dimensional array
3764: .  mstart - first index you will use in first coordinate direction (often 0)
3765: .  nstart - first index in the second coordinate direction (often 0)
3766: .  pstart - first index in the third coordinate direction (often 0)
3767: .  qstart - first index in the fourth coordinate direction (often 0)
3768: -  a - location of pointer to array obtained from VecGetArray4dRead()

3770:    Level: beginner

3772:    Notes:
3773:    For regular PETSc vectors this routine does not involve any copies. For
3774:    any special vectors that do not store local vector data in a contiguous
3775:    array, this routine will copy the data back into the underlying
3776:    vector data structure from the array obtained with VecGetArray().

3778:    This routine actually zeros out the a pointer.

3780: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3781:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3782:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3783: @*/
3784: PetscErrorCode  VecRestoreArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3785: {
3787:   void           *dummy;

3793:   dummy = (void*)(*a + mstart);
3794:   PetscFree(dummy);
3795:   VecRestoreArrayRead(x,NULL);
3796:   return(0);
3797: }

3799: #if defined(PETSC_USE_DEBUG)

3801: /*@
3802:    VecLockGet  - Gets the current lock status of a vector

3804:    Logically Collective on Vec

3806:    Input Parameter:
3807: .  x - the vector

3809:    Output Parameter:
3810: .  state - greater than zero indicates the vector is locked for read; less then zero indicates the vector is
3811:            locked for write; equal to zero means the vector is unlocked, that is, it is free to read or write.

3813:    Level: beginner

3815: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockReadPop()
3816: @*/
3817: PetscErrorCode VecLockGet(Vec x,PetscInt *state)
3818: {
3821:   *state = x->lock;
3822:   return(0);
3823: }

3825: /*@
3826:    VecLockReadPush  - Pushes a read-only lock on a vector to prevent it from writing

3828:    Logically Collective on Vec

3830:    Input Parameter:
3831: .  x - the vector

3833:    Notes:
3834:     If this is set then calls to VecGetArray() or VecSetValues() or any other routines that change the vectors values will fail.

3836:     The call can be nested, i.e., called multiple times on the same vector, but each VecLockReadPush(x) has to have one matching
3837:     VecLockReadPop(x), which removes the latest read-only lock.

3839:    Level: beginner

3841: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPop(), VecLockGet()
3842: @*/
3843: PetscErrorCode VecLockReadPush(Vec x)
3844: {
3847:   if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is already locked for exclusive write access but you want to read it");
3848:   x->lock++;
3849:   return(0);
3850: }

3852: /*@
3853:    VecLockReadPop  - Pops a read-only lock from a vector

3855:    Logically Collective on Vec

3857:    Input Parameter:
3858: .  x - the vector

3860:    Level: beginner

3862: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockGet()
3863: @*/
3864: PetscErrorCode VecLockReadPop(Vec x)
3865: {
3868:   x->lock--;
3869:   if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector has been unlocked from read-only access too many times");
3870:   return(0);
3871: }

3873: /*@C
3874:    VecLockWriteSet_Private  - Lock or unlock a vector for exclusive read/write access

3876:    Logically Collective on Vec

3878:    Input Parameter:
3879: +  x   - the vector
3880: -  flg - PETSC_TRUE to lock the vector for writing; PETSC_FALSE to unlock it.

3882:    Notes:
3883:     The function is usefull in split-phase computations, which usually have a begin phase and an end phase.
3884:     One can call VecLockWriteSet_Private(x,PETSC_TRUE) in the begin phase to lock a vector for exclusive
3885:     access, and call VecLockWriteSet_Private(x,PETSC_FALSE) in the end phase to unlock the vector from exclusive
3886:     access. In this way, one is ensured no other operations can access the vector in between. The code may like


3889:        VecGetArray(x,&xdata); // begin phase
3890:        VecLockWriteSet_Private(v,PETSC_TRUE);

3892:        Other operations, which can not acceess x anymore (they can access xdata, of course)

3894:        VecRestoreArray(x,&vdata); // end phase
3895:        VecLockWriteSet_Private(v,PETSC_FALSE);

3897:     The call can not be nested on the same vector, in other words, one can not call VecLockWriteSet_Private(x,PETSC_TRUE)
3898:     again before calling VecLockWriteSet_Private(v,PETSC_FALSE).

3900:    Level: beginner

3902: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockReadPop(), VecLockGet()
3903: @*/
3904: PetscErrorCode VecLockWriteSet_Private(Vec x,PetscBool flg)
3905: {
3908:   if (flg) {
3909:     if (x->lock > 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is already locked for read-only access but you want to write it");
3910:     else if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is already locked for exclusive write access but you want to write it");
3911:     else x->lock = -1;
3912:   } else {
3913:     if (x->lock != -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is not locked for exclusive write access but you want to unlock it from that");
3914:     x->lock = 0;
3915:   }
3916:   return(0);
3917: }

3919: /*@
3920:    VecLockPush  - Pushes a read-only lock on a vector to prevent it from writing

3922:    Level: deprecated

3924: .seealso: VecLockReadPush()
3925: @*/
3926: PetscErrorCode VecLockPush(Vec x)
3927: {
3930:   VecLockReadPush(x);
3931:   return(0);
3932: }

3934: /*@
3935:    VecLockPop  - Pops a read-only lock from a vector

3937:    Level: deprecated

3939: .seealso: VecLockReadPop()
3940: @*/
3941: PetscErrorCode VecLockPop(Vec x)
3942: {
3945:   VecLockReadPop(x);
3946:   return(0);
3947: }

3949: #endif