Actual source code: rvector.c
petsc-3.13.6 2020-09-29
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 <petsc/private/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:     VecSetErrorIfLocked(x,1);
    472:     /* get current stashed norms */
    473:     for (i=0; i<4; i++) {
    474:       PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],norms[i],flgs[i]);
    475:     }
    476:     (*x->ops->scale)(x,alpha);
    477:     PetscObjectStateIncrease((PetscObject)x);
    478:     /* put the scaled stashed norms back into the Vec */
    479:     for (i=0; i<4; i++) {
    480:       if (flgs[i]) {
    481:         PetscObjectComposedDataSetReal((PetscObject)x,NormIds[i],PetscAbsScalar(alpha)*norms[i]);
    482:       }
    483:     }
    484:   }
    485:   PetscLogEventEnd(VEC_Scale,x,0,0,0);
    486:   return(0);
    487: }

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

    492:    Logically Collective on Vec

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

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

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

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

    511:    Level: beginner

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

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

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

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

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

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

    556:    Logically Collective on Vec

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

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

    565:    Level: intermediate

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

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

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

    591:   VecCheckSameSize(x,1,y,3);
    592:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
    594:   if (alpha == (PetscScalar)0.0) return(0);
    595:   VecSetErrorIfLocked(y,1);

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

    606: /*@
    607:    VecAXPBY - Computes y = alpha x + beta y.

    609:    Logically Collective on Vec

    611:    Input Parameters:
    612: +  alpha,beta - the scalars
    613: -  x, y  - the vectors

    615:    Output Parameter:
    616: .  y - output vector

    618:    Level: intermediate

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

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

    637:   VecCheckSameSize(y,1,x,4);
    638:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
    641:   if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)1.0) return(0);
    642:   VecSetErrorIfLocked(y,1);
    643:   PetscLogEventBegin(VEC_AXPY,x,y,0,0);
    644:   (*y->ops->axpby)(y,alpha,beta,x);
    645:   PetscLogEventEnd(VEC_AXPY,x,y,0,0);
    646:   PetscObjectStateIncrease((PetscObject)y);
    647:   return(0);
    648: }

    650: /*@
    651:    VecAXPBYPCZ - Computes z = alpha x + beta y + gamma z

    653:    Logically Collective on Vec

    655:    Input Parameters:
    656: +  alpha,beta, gamma - the scalars
    657: -  x, y, z  - the vectors

    659:    Output Parameter:
    660: .  z - output vector

    662:    Level: intermediate

    664:    Notes:
    665:     x, y and z must be different vectors
    666:     The implementation is optimized for alpha of 1.0 and gamma of 1.0 or 0.0

    669: .seealso:  VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBY()
    670: @*/
    671: PetscErrorCode  VecAXPBYPCZ(Vec z,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec x,Vec y)
    672: {

    684:   VecCheckSameSize(x,1,y,5);
    685:   VecCheckSameSize(x,1,z,6);
    686:   if (x == y || x == z) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
    687:   if (y == z) SETERRQ(PetscObjectComm((PetscObject)y),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
    691:   if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)0.0 && gamma == (PetscScalar)1.0) return(0);
    692:   VecSetErrorIfLocked(z,1);

    694:   PetscLogEventBegin(VEC_AXPBYPCZ,x,y,z,0);
    695:   (*y->ops->axpbypcz)(z,alpha,beta,gamma,x,y);
    696:   PetscLogEventEnd(VEC_AXPBYPCZ,x,y,z,0);
    697:   PetscObjectStateIncrease((PetscObject)z);
    698:   return(0);
    699: }

    701: /*@
    702:    VecAYPX - Computes y = x + beta y.

    704:    Logically Collective on Vec

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

    710:    Output Parameter:
    711: .  y - output vector

    713:    Level: intermediate

    715:    Notes:
    716:     x and y MUST be different vectors
    717:     The implementation is optimized for beta of -1.0, 0.0, and 1.0

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

    732:   VecCheckSameSize(x,1,y,3);
    733:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y must be different vectors");
    735:   VecSetErrorIfLocked(y,1);

    737:   PetscLogEventBegin(VEC_AYPX,x,y,0,0);
    738:    (*y->ops->aypx)(y,beta,x);
    739:   PetscLogEventEnd(VEC_AYPX,x,y,0,0);
    740:   PetscObjectStateIncrease((PetscObject)y);
    741:   return(0);
    742: }

    745: /*@
    746:    VecWAXPY - Computes w = alpha x + y.

    748:    Logically Collective on Vec

    750:    Input Parameters:
    751: +  alpha - the scalar
    752: -  x, y  - the vectors

    754:    Output Parameter:
    755: .  w - the result

    757:    Level: intermediate

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

    764: .seealso: VecAXPY(), VecAYPX(), VecAXPBY(), VecMAXPY(), VecAXPBYPCZ()
    765: @*/
    766: PetscErrorCode  VecWAXPY(Vec w,PetscScalar alpha,Vec x,Vec y)
    767: {

    779:   VecCheckSameSize(x,3,y,4);
    780:   VecCheckSameSize(x,3,w,1);
    781:   if (w == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector y, suggest VecAXPY()");
    782:   if (w == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector x, suggest VecAYPX()");
    784:   VecSetErrorIfLocked(w,1);

    786:   PetscLogEventBegin(VEC_WAXPY,x,y,w,0);
    787:    (*w->ops->waxpy)(w,alpha,x,y);
    788:   PetscLogEventEnd(VEC_WAXPY,x,y,w,0);
    789:   PetscObjectStateIncrease((PetscObject)w);
    790:   return(0);
    791: }

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

    797:    Not Collective

    799:    Input Parameters:
    800: +  x - vector to insert in
    801: .  ni - number of elements to add
    802: .  ix - indices where to add
    803: .  y - array of values
    804: -  iora - either INSERT_VALUES or ADD_VALUES, where
    805:    ADD_VALUES adds values to any existing entries, and
    806:    INSERT_VALUES replaces existing entries with new values

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

    811:    Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
    812:    options cannot be mixed without intervening calls to the assembly
    813:    routines.

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

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

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

    826:    Level: beginner

    828: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesLocal(),
    829:            VecSetValue(), VecSetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecGetValues()
    830: @*/
    831: PetscErrorCode  VecSetValues(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
    832: {

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

    842:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
    843:   (*x->ops->setvalues)(x,ni,ix,y,iora);
    844:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
    845:   PetscObjectStateIncrease((PetscObject)x);
    846:   return(0);
    847: }

    849: /*@C
    850:    VecGetValues - Gets values from certain locations of a vector. Currently
    851:           can only get values on the same processor

    853:     Not Collective

    855:    Input Parameters:
    856: +  x - vector to get values from
    857: .  ni - number of elements to get
    858: -  ix - indices where to get them from (in global 1d numbering)

    860:    Output Parameter:
    861: .   y - array of values

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

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

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

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

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

    876:    Level: beginner

    878: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues()
    879: @*/
    880: PetscErrorCode  VecGetValues(Vec x,PetscInt ni,const PetscInt ix[],PetscScalar y[])
    881: {

    886:   if (!ni) return(0);
    890:   (*x->ops->getvalues)(x,ni,ix,y);
    891:   return(0);
    892: }

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

    897:    Not Collective

    899:    Input Parameters:
    900: +  x - vector to insert in
    901: .  ni - number of blocks to add
    902: .  ix - indices where to add in block count, rather than element count
    903: .  y - array of values
    904: -  iora - either INSERT_VALUES or ADD_VALUES, where
    905:    ADD_VALUES adds values to any existing entries, and
    906:    INSERT_VALUES replaces existing entries with new values

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

    912:    Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
    913:    options cannot be mixed without intervening calls to the assembly
    914:    routines.

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

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

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

    926:    Level: intermediate

    928: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesBlockedLocal(),
    929:            VecSetValues()
    930: @*/
    931: PetscErrorCode  VecSetValuesBlocked(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
    932: {

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

    942:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
    943:   (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);
    944:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
    945:   PetscObjectStateIncrease((PetscObject)x);
    946:   return(0);
    947: }

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

    954:    Not Collective

    956:    Input Parameters:
    957: +  x - vector to insert in
    958: .  ni - number of elements to add
    959: .  ix - indices where to add
    960: .  y - array of values
    961: -  iora - either INSERT_VALUES or ADD_VALUES, where
    962:    ADD_VALUES adds values to any existing entries, and
    963:    INSERT_VALUES replaces existing entries with new values

    965:    Level: intermediate

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

    970:    Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
    971:    options cannot be mixed without intervening calls to the assembly
    972:    routines.

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

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

    979: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetLocalToGlobalMapping(),
    980:            VecSetValuesBlockedLocal()
    981: @*/
    982: PetscErrorCode  VecSetValuesLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
    983: {
    985:   PetscInt       lixp[128],*lix = lixp;

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

    994:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
    995:   if (!x->ops->setvalueslocal) {
    996:     if (!x->map->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMapping()");
    997:     if (ni > 128) {
    998:       PetscMalloc1(ni,&lix);
    999:     }
    1000:     ISLocalToGlobalMappingApply(x->map->mapping,ni,(PetscInt*)ix,lix);
    1001:     (*x->ops->setvalues)(x,ni,lix,y,iora);
    1002:     if (ni > 128) {
    1003:       PetscFree(lix);
    1004:     }
    1005:   } else {
    1006:     (*x->ops->setvalueslocal)(x,ni,ix,y,iora);
    1007:   }
    1008:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
    1009:   PetscObjectStateIncrease((PetscObject)x);
    1010:   return(0);
    1011: }

    1013: /*@
    1014:    VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
    1015:    using a local ordering of the nodes.

    1017:    Not Collective

    1019:    Input Parameters:
    1020: +  x - vector to insert in
    1021: .  ni - number of blocks to add
    1022: .  ix - indices where to add in block count, not element count
    1023: .  y - array of values
    1024: -  iora - either INSERT_VALUES or ADD_VALUES, where
    1025:    ADD_VALUES adds values to any existing entries, and
    1026:    INSERT_VALUES replaces existing entries with new values

    1028:    Level: intermediate

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

    1034:    Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
    1035:    options cannot be mixed without intervening calls to the assembly
    1036:    routines.

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

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

    1044: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesBlocked(),
    1045:            VecSetLocalToGlobalMapping()
    1046: @*/
    1047: PetscErrorCode  VecSetValuesBlockedLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
    1048: {
    1050:   PetscInt       lixp[128],*lix = lixp;

    1054:   if (!ni) return(0);
    1058:   if (ni > 128) {
    1059:     PetscMalloc1(ni,&lix);
    1060:   }

    1062:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
    1063:   ISLocalToGlobalMappingApplyBlock(x->map->mapping,ni,(PetscInt*)ix,lix);
    1064:   (*x->ops->setvaluesblocked)(x,ni,lix,y,iora);
    1065:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
    1066:   if (ni > 128) {
    1067:     PetscFree(lix);
    1068:   }
    1069:   PetscObjectStateIncrease((PetscObject)x);
    1070:   return(0);
    1071: }

    1073: /*@
    1074:    VecMTDot - Computes indefinite vector multiple dot products.
    1075:    That is, it does NOT use the complex conjugate.

    1077:    Collective on Vec

    1079:    Input Parameters:
    1080: +  x - one vector
    1081: .  nv - number of vectors
    1082: -  y - array of vectors.  Note that vectors are pointers

    1084:    Output Parameter:
    1085: .  val - array of the dot products

    1087:    Notes for Users of Complex Numbers:
    1088:    For complex vectors, VecMTDot() computes the indefinite form
    1089: $      val = (x,y) = y^T x,
    1090:    where y^T denotes the transpose of y.

    1092:    Use VecMDot() for the inner product
    1093: $      val = (x,y) = y^H x,
    1094:    where y^H denotes the conjugate transpose of y.

    1096:    Level: intermediate

    1099: .seealso: VecMDot(), VecTDot()
    1100: @*/
    1101: PetscErrorCode  VecMTDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
    1102: {

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

    1117:   PetscLogEventBegin(VEC_MTDot,x,*y,0,0);
    1118:   (*x->ops->mtdot)(x,nv,y,val);
    1119:   PetscLogEventEnd(VEC_MTDot,x,*y,0,0);
    1120:   return(0);
    1121: }

    1123: /*@
    1124:    VecMDot - Computes vector multiple dot products.

    1126:    Collective on Vec

    1128:    Input Parameters:
    1129: +  x - one vector
    1130: .  nv - number of vectors
    1131: -  y - array of vectors.

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

    1136:    Notes for Users of Complex Numbers:
    1137:    For complex vectors, VecMDot() computes
    1138: $     val = (x,y) = y^H x,
    1139:    where y^H denotes the conjugate transpose of y.

    1141:    Use VecMTDot() for the indefinite form
    1142: $     val = (x,y) = y^T x,
    1143:    where y^T denotes the transpose of y.

    1145:    Level: intermediate

    1148: .seealso: VecMTDot(), VecDot()
    1149: @*/
    1150: PetscErrorCode  VecMDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
    1151: {

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

    1167:   PetscLogEventBegin(VEC_MDot,x,*y,0,0);
    1168:   (*x->ops->mdot)(x,nv,y,val);
    1169:   PetscLogEventEnd(VEC_MDot,x,*y,0,0);
    1170:   return(0);
    1171: }

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

    1176:    Logically Collective on Vec

    1178:    Input Parameters:
    1179: +  nv - number of scalars and x-vectors
    1180: .  alpha - array of scalars
    1181: .  y - one vector
    1182: -  x - array of vectors

    1184:    Level: intermediate

    1186:    Notes:
    1187:     y cannot be any of the x vectors

    1189: .seealso:  VecAYPX(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ(), VecAXPBY()
    1190: @*/
    1191: PetscErrorCode  VecMAXPY(Vec y,PetscInt nv,const PetscScalar alpha[],Vec x[])
    1192: {
    1194:   PetscInt       i;
    1195:   PetscBool      nonzero;

    1200:   if (!nv) return(0);
    1201:   if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
    1208:   VecCheckSameSize(y,1,*x,4);
    1210:   for (i=0, nonzero = PETSC_FALSE; i<nv && !nonzero; i++) nonzero = (PetscBool)(nonzero || alpha[i] != (PetscScalar)0.0);
    1211:   if (!nonzero) return(0);
    1212:   VecSetErrorIfLocked(y,1);
    1213:   PetscLogEventBegin(VEC_MAXPY,*x,y,0,0);
    1214:   (*y->ops->maxpy)(y,nv,alpha,x);
    1215:   PetscLogEventEnd(VEC_MAXPY,*x,y,0,0);
    1216:   PetscObjectStateIncrease((PetscObject)y);
    1217:   return(0);
    1218: }

    1220: /*@
    1221:    VecGetSubVector - Gets a vector representing part of another vector

    1223:    Collective on IS

    1225:    Input Arguments:
    1226: + X - vector from which to extract a subvector
    1227: - is - index set representing portion of X to extract

    1229:    Output Arguments:
    1230: . Y - subvector corresponding to is

    1232:    Level: advanced

    1234:    Notes:
    1235:    The subvector Y should be returned with VecRestoreSubVector().

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

    1240: .seealso: MatCreateSubMatrix()
    1241: @*/
    1242: PetscErrorCode  VecGetSubVector(Vec X,IS is,Vec *Y)
    1243: {
    1244:   PetscErrorCode   ierr;
    1245:   Vec              Z;

    1251:   if (X->ops->getsubvector) {
    1252:     (*X->ops->getsubvector)(X,is,&Z);
    1253:   } else { /* Default implementation currently does no caching */
    1254:     PetscInt  gstart,gend,start;
    1255:     PetscBool contiguous,gcontiguous;
    1256:     VecGetOwnershipRange(X,&gstart,&gend);
    1257:     ISContiguousLocal(is,gstart,gend,&start,&contiguous);
    1258:     MPIU_Allreduce(&contiguous,&gcontiguous,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));
    1259:     if (gcontiguous) { /* We can do a no-copy implementation */
    1260:       PetscInt n,N,bs;
    1261:       PetscInt state;

    1263:       ISGetSize(is,&N);
    1264:       ISGetLocalSize(is,&n);
    1265:       VecGetBlockSize(X,&bs);

    1267:       if (n%bs || bs == 1) bs = -1; /* Do not decide block size if we do not have to */
    1268:       VecLockGet(X,&state);
    1269:       if (state) {
    1270:         const PetscScalar *x;
    1271:         VecGetArrayRead(X,&x);
    1272:         VecCreate(PetscObjectComm((PetscObject)X),&Z);
    1273:         VecSetType(Z,((PetscObject)X)->type_name);
    1274:         VecSetSizes(Z,n,N);
    1275:         VecSetBlockSize(Z,bs);
    1276:         VecPlaceArray(Z,(PetscScalar*)x+start);
    1277:         VecLockReadPush(Z);
    1278:         VecRestoreArrayRead(X,&x);
    1279:       } else {
    1280:         PetscScalar *x;
    1281:         VecGetArray(X,&x);
    1282:         VecCreate(PetscObjectComm((PetscObject)X),&Z);
    1283:         VecSetType(Z,((PetscObject)X)->type_name);
    1284:         VecSetSizes(Z,n,N);
    1285:         VecSetBlockSize(Z,bs);
    1286:         VecPlaceArray(Z,(PetscScalar*)x+start);
    1287:         VecRestoreArray(X,&x);
    1288:       }
    1289:       Z->ops->placearray = NULL;
    1290:       Z->ops->replacearray = NULL;
    1291:     } else { /* Have to create a scatter and do a copy */
    1292:       VecScatter scatter;
    1293:       PetscInt   n,N;
    1294:       ISGetLocalSize(is,&n);
    1295:       ISGetSize(is,&N);
    1296:       VecCreate(PetscObjectComm((PetscObject)is),&Z);
    1297:       VecSetSizes(Z,n,N);
    1298:       VecSetType(Z,((PetscObject)X)->type_name);
    1299:       VecScatterCreate(X,is,Z,NULL,&scatter);
    1300:       VecScatterBegin(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
    1301:       VecScatterEnd(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
    1302:       PetscObjectCompose((PetscObject)Z,"VecGetSubVector_Scatter",(PetscObject)scatter);
    1303:       VecScatterDestroy(&scatter);
    1304:     }
    1305:   }
    1306:   /* Record the state when the subvector was gotten so we know whether its values need to be put back */
    1307:   if (VecGetSubVectorSavedStateId < 0) {PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId);}
    1308:   PetscObjectComposedDataSetInt((PetscObject)Z,VecGetSubVectorSavedStateId,1);
    1309:   *Y   = Z;
    1310:   return(0);
    1311: }

    1313: /*@
    1314:    VecRestoreSubVector - Restores a subvector extracted using VecGetSubVector()

    1316:    Collective on IS

    1318:    Input Arguments:
    1319: + X - vector from which subvector was obtained
    1320: . is - index set representing the subset of X
    1321: - Y - subvector being restored

    1323:    Level: advanced

    1325: .seealso: VecGetSubVector()
    1326: @*/
    1327: PetscErrorCode  VecRestoreSubVector(Vec X,IS is,Vec *Y)
    1328: {

    1336:   if (X->ops->restoresubvector) {
    1337:     (*X->ops->restoresubvector)(X,is,Y);
    1338:   } else {
    1339:     PETSC_UNUSED PetscObjectState dummystate = 0;
    1340:     PetscBool valid;
    1341:     PetscObjectComposedDataGetInt((PetscObject)*Y,VecGetSubVectorSavedStateId,dummystate,valid);
    1342:     if (!valid) {
    1343:       VecScatter scatter;

    1345:       PetscObjectQuery((PetscObject)*Y,"VecGetSubVector_Scatter",(PetscObject*)&scatter);
    1346:       if (scatter) {
    1347:         VecScatterBegin(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);
    1348:         VecScatterEnd(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);
    1349:       }
    1350:     }
    1351:     VecDestroy(Y);
    1352:   }
    1353:   return(0);
    1354: }

    1356: /*@
    1357:    VecGetLocalVectorRead - Maps the local portion of a vector into a
    1358:    vector.  You must call VecRestoreLocalVectorRead() when the local
    1359:    vector is no longer needed.

    1361:    Not collective.

    1363:    Input parameter:
    1364: .  v - The vector for which the local vector is desired.

    1366:    Output parameter:
    1367: .  w - Upon exit this contains the local vector.

    1369:    Level: beginner

    1371:    Notes:
    1372:    This function is similar to VecGetArrayRead() which maps the local
    1373:    portion into a raw pointer.  VecGetLocalVectorRead() is usually
    1374:    almost as efficient as VecGetArrayRead() but in certain circumstances
    1375:    VecGetLocalVectorRead() can be much more efficient than
    1376:    VecGetArrayRead().  This is because the construction of a contiguous
    1377:    array representing the vector data required by VecGetArrayRead() can
    1378:    be an expensive operation for certain vector types.  For example, for
    1379:    GPU vectors VecGetArrayRead() requires that the data between device
    1380:    and host is synchronized.

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

    1385: .seealso: VecRestoreLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
    1386: @*/
    1387: PetscErrorCode VecGetLocalVectorRead(Vec v,Vec w)
    1388: {
    1390:   PetscScalar    *a;

    1395:   VecCheckSameLocalSize(v,1,w,2);
    1396:   if (v->ops->getlocalvectorread) {
    1397:     (*v->ops->getlocalvectorread)(v,w);
    1398:   } else {
    1399:     VecGetArrayRead(v,(const PetscScalar**)&a);
    1400:     VecPlaceArray(w,a);
    1401:   }
    1402:   return(0);
    1403: }

    1405: /*@
    1406:    VecRestoreLocalVectorRead - Unmaps the local portion of a vector
    1407:    previously mapped into a vector using VecGetLocalVectorRead().

    1409:    Not collective.

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

    1415:    Level: beginner

    1417: .seealso: VecGetLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
    1418: @*/
    1419: PetscErrorCode VecRestoreLocalVectorRead(Vec v,Vec w)
    1420: {
    1422:   PetscScalar    *a;

    1427:   if (v->ops->restorelocalvectorread) {
    1428:     (*v->ops->restorelocalvectorread)(v,w);
    1429:   } else {
    1430:     VecGetArrayRead(w,(const PetscScalar**)&a);
    1431:     VecRestoreArrayRead(v,(const PetscScalar**)&a);
    1432:     VecResetArray(w);
    1433:   }
    1434:   return(0);
    1435: }

    1437: /*@
    1438:    VecGetLocalVector - Maps the local portion of a vector into a
    1439:    vector.

    1441:    Collective on v, not collective on w.

    1443:    Input parameter:
    1444: .  v - The vector for which the local vector is desired.

    1446:    Output parameter:
    1447: .  w - Upon exit this contains the local vector.

    1449:    Level: beginner

    1451:    Notes:
    1452:    This function is similar to VecGetArray() which maps the local
    1453:    portion into a raw pointer.  VecGetLocalVector() is usually about as
    1454:    efficient as VecGetArray() but in certain circumstances
    1455:    VecGetLocalVector() can be much more efficient than VecGetArray().
    1456:    This is because the construction of a contiguous array representing
    1457:    the vector data required by VecGetArray() can be an expensive
    1458:    operation for certain vector types.  For example, for GPU vectors
    1459:    VecGetArray() requires that the data between device and host is
    1460:    synchronized.

    1462: .seealso: VecRestoreLocalVector(), VecGetLocalVectorRead(), VecGetArrayRead(), VecGetArray()
    1463: @*/
    1464: PetscErrorCode VecGetLocalVector(Vec v,Vec w)
    1465: {
    1467:   PetscScalar    *a;

    1472:   VecCheckSameLocalSize(v,1,w,2);
    1473:   if (v->ops->getlocalvector) {
    1474:     (*v->ops->getlocalvector)(v,w);
    1475:   } else {
    1476:     VecGetArray(v,&a);
    1477:     VecPlaceArray(w,a);
    1478:   }
    1479:   return(0);
    1480: }

    1482: /*@
    1483:    VecRestoreLocalVector - Unmaps the local portion of a vector
    1484:    previously mapped into a vector using VecGetLocalVector().

    1486:    Logically collective.

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

    1492:    Level: beginner

    1494: .seealso: VecGetLocalVector(), VecGetLocalVectorRead(), VecRestoreLocalVectorRead(), LocalVectorRead(), VecGetArrayRead(), VecGetArray()
    1495: @*/
    1496: PetscErrorCode VecRestoreLocalVector(Vec v,Vec w)
    1497: {
    1499:   PetscScalar    *a;

    1504:   if (v->ops->restorelocalvector) {
    1505:     (*v->ops->restorelocalvector)(v,w);
    1506:   } else {
    1507:     VecGetArray(w,&a);
    1508:     VecRestoreArray(v,&a);
    1509:     VecResetArray(w);
    1510:   }
    1511:   return(0);
    1512: }

    1514: /*@C
    1515:    VecGetArray - Returns a pointer to a contiguous array that contains this
    1516:    processor's portion of the vector data. For the standard PETSc
    1517:    vectors, VecGetArray() returns a pointer to the local data array and
    1518:    does not use any copies. If the underlying vector data is not stored
    1519:    in a contiguous array this routine will copy the data to a contiguous
    1520:    array and return a pointer to that. You MUST call VecRestoreArray()
    1521:    when you no longer need access to the array.

    1523:    Logically Collective on Vec

    1525:    Input Parameter:
    1526: .  x - the vector

    1528:    Output Parameter:
    1529: .  a - location to put pointer to the array

    1531:    Fortran Note:
    1532:    This routine is used differently from Fortran 77
    1533: $    Vec         x
    1534: $    PetscScalar x_array(1)
    1535: $    PetscOffset i_x
    1536: $    PetscErrorCode ierr
    1537: $       call VecGetArray(x,x_array,i_x,ierr)
    1538: $
    1539: $   Access first local entry in vector with
    1540: $      value = x_array(i_x + 1)
    1541: $
    1542: $      ...... other code
    1543: $       call VecRestoreArray(x,x_array,i_x,ierr)
    1544:    For Fortran 90 see VecGetArrayF90()

    1546:    See the Fortran chapter of the users manual and
    1547:    petsc/src/snes/tutorials/ex5f.F for details.

    1549:    Level: beginner

    1551: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
    1552:           VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite(), VecRestoreArrayWrite()
    1553: @*/
    1554: PetscErrorCode VecGetArray(Vec x,PetscScalar **a)
    1555: {
    1557: #if defined(PETSC_HAVE_VIENNACL)
    1558:   PetscBool      is_viennacltype = PETSC_FALSE;
    1559: #endif

    1563:   VecSetErrorIfLocked(x,1);
    1564:   if (x->petscnative) {
    1565: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
    1566:     if (x->offloadmask == PETSC_OFFLOAD_GPU) {
    1567: #if defined(PETSC_HAVE_VIENNACL)
    1568:       PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
    1569:       if (is_viennacltype) {
    1570:         VecViennaCLCopyFromGPU(x);
    1571:       } else
    1572: #endif
    1573:       {
    1574: #if defined(PETSC_HAVE_CUDA)
    1575:         VecCUDACopyFromGPU(x);
    1576: #endif
    1577:       }
    1578:     } else if (x->offloadmask == PETSC_OFFLOAD_UNALLOCATED) {
    1579: #if defined(PETSC_HAVE_VIENNACL)
    1580:       PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
    1581:       if (is_viennacltype) {
    1582:         VecViennaCLAllocateCheckHost(x);
    1583:       } else
    1584: #endif
    1585:       {
    1586: #if defined(PETSC_HAVE_CUDA)
    1587:         VecCUDAAllocateCheckHost(x);
    1588: #endif
    1589:       }
    1590:     }
    1591: #endif
    1592:     *a = *((PetscScalar**)x->data);
    1593:   } else {
    1594:     if (x->ops->getarray) {
    1595:       (*x->ops->getarray)(x,a);
    1596:     } else SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot get array for vector type \"%s\"",((PetscObject)x)->type_name);
    1597:   }
    1598:   return(0);
    1599: }

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

    1606:    Logically Collective on Vec

    1608:    Input Parameter:
    1609: .  x - the vector

    1611:    Output Parameter:
    1612: .  a - location to put pointer to the array

    1614:    Level: beginner

    1616: .seealso: VecRestoreArrayInPlace(), VecRestoreArrayInPlace(), VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(),
    1617:           VecPlaceArray(), VecGetArray2d(), VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite(), VecRestoreArrayWrite()
    1618: @*/
    1619: PetscErrorCode VecGetArrayInPlace(Vec x,PetscScalar **a)
    1620: {

    1625:   VecSetErrorIfLocked(x,1);

    1627: #if defined(PETSC_HAVE_CUDA)
    1628:   if (x->petscnative && (x->offloadmask & PETSC_OFFLOAD_GPU)) { /* Prefer working on GPU when offloadmask is PETSC_OFFLOAD_BOTH */
    1629:     PetscBool is_cudatype = PETSC_FALSE;
    1630:     PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");
    1631:     if (is_cudatype) {
    1632:       VecCUDAGetArray(x,a);
    1633:       x->offloadmask = PETSC_OFFLOAD_GPU; /* Change the mask once GPU gets write access, don't wait until restore array */
    1634:       return(0);
    1635:     }
    1636:   }
    1637: #endif
    1638:   VecGetArray(x,a);
    1639:   return(0);
    1640: }

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

    1647:    Logically Collective on Vec

    1649:    Input Parameter:
    1650: .  x - the vector

    1652:    Output Parameter:
    1653: .  a - location to put pointer to the array

    1655:    Level: intermediate

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

    1660:    Concepts: vector^accessing local values

    1662: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
    1663:           VecGetArrayPair(), VecRestoreArrayPair(), VecGetArray(), VecRestoreArrayWrite()
    1664: @*/
    1665: PetscErrorCode VecGetArrayWrite(Vec x,PetscScalar **a)
    1666: {

    1671:   VecSetErrorIfLocked(x,1);
    1672:   if (!x->ops->getarraywrite) {
    1673:     VecGetArray(x,a);
    1674:   } else {
    1675:     (*x->ops->getarraywrite)(x,a);
    1676:   }
    1677:   return(0);
    1678: }

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

    1683:    Not Collective

    1685:    Input Parameters:
    1686: .  x - the vector

    1688:    Output Parameter:
    1689: .  a - the array

    1691:    Level: beginner

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

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

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

    1702: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
    1703: @*/
    1704: PetscErrorCode VecGetArrayRead(Vec x,const PetscScalar **a)
    1705: {
    1707: #if defined(PETSC_HAVE_VIENNACL)
    1708:   PetscBool      is_viennacltype = PETSC_FALSE;
    1709: #endif

    1713:   if (x->petscnative) {
    1714: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
    1715:     if (x->offloadmask == PETSC_OFFLOAD_GPU) {
    1716: #if defined(PETSC_HAVE_VIENNACL)
    1717:       PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
    1718:       if (is_viennacltype) {
    1719:         VecViennaCLCopyFromGPU(x);
    1720:       } else
    1721: #endif
    1722:       {
    1723: #if defined(PETSC_HAVE_CUDA)
    1724:         VecCUDACopyFromGPU(x);
    1725: #endif
    1726:       }
    1727:     }
    1728: #endif
    1729:     *a = *((PetscScalar **)x->data);
    1730:   } else if (x->ops->getarrayread) {
    1731:     (*x->ops->getarrayread)(x,a);
    1732:   } else {
    1733:     (*x->ops->getarray)(x,(PetscScalar**)a);
    1734:   }
    1735:   return(0);
    1736: }

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

    1743:    Not Collective

    1745:    Input Parameters:
    1746: .  x - the vector

    1748:    Output Parameter:
    1749: .  a - the array

    1751:    Level: beginner

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

    1757: .seealso: VecRestoreArrayReadInPlace(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayInPlace()
    1758: @*/
    1759: PetscErrorCode VecGetArrayReadInPlace(Vec x,const PetscScalar **a)
    1760: {

    1765: #if defined(PETSC_HAVE_CUDA)
    1766:   if (x->petscnative && x->offloadmask & PETSC_OFFLOAD_GPU) {
    1767:     PetscBool is_cudatype = PETSC_FALSE;
    1768:     PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");
    1769:     if (is_cudatype) {
    1770:       VecCUDAGetArrayRead(x,a);
    1771:       return(0);
    1772:     }
    1773:   }
    1774: #endif
    1775:   VecGetArrayRead(x,a);
    1776:   return(0);
    1777: }

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

    1784:    Logically Collective on Vec

    1786:    Input Parameter:
    1787: +  x - the vectors
    1788: -  n - the number of vectors

    1790:    Output Parameter:
    1791: .  a - location to put pointer to the array

    1793:    Fortran Note:
    1794:    This routine is not supported in Fortran.

    1796:    Level: intermediate

    1798: .seealso: VecGetArray(), VecRestoreArrays()
    1799: @*/
    1800: PetscErrorCode  VecGetArrays(const Vec x[],PetscInt n,PetscScalar **a[])
    1801: {
    1803:   PetscInt       i;
    1804:   PetscScalar    **q;

    1810:   if (n <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must get at least one array n = %D",n);
    1811:   PetscMalloc1(n,&q);
    1812:   for (i=0; i<n; ++i) {
    1813:     VecGetArray(x[i],&q[i]);
    1814:   }
    1815:   *a = q;
    1816:   return(0);
    1817: }

    1819: /*@C
    1820:    VecRestoreArrays - Restores a group of vectors after VecGetArrays()
    1821:    has been called.

    1823:    Logically Collective on Vec

    1825:    Input Parameters:
    1826: +  x - the vector
    1827: .  n - the number of vectors
    1828: -  a - location of pointer to arrays obtained from VecGetArrays()

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

    1836:    Fortran Note:
    1837:    This routine is not supported in Fortran.

    1839:    Level: intermediate

    1841: .seealso: VecGetArrays(), VecRestoreArray()
    1842: @*/
    1843: PetscErrorCode  VecRestoreArrays(const Vec x[],PetscInt n,PetscScalar **a[])
    1844: {
    1846:   PetscInt       i;
    1847:   PetscScalar    **q = *a;

    1854:   for (i=0; i<n; ++i) {
    1855:     VecRestoreArray(x[i],&q[i]);
    1856:   }
    1857:   PetscFree(q);
    1858:   return(0);
    1859: }

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

    1864:    Logically Collective on Vec

    1866:    Input Parameters:
    1867: +  x - the vector
    1868: -  a - location of pointer to array obtained from VecGetArray()

    1870:    Level: beginner

    1872: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
    1873:           VecGetArrayPair(), VecRestoreArrayPair()
    1874: @*/
    1875: PetscErrorCode VecRestoreArray(Vec x,PetscScalar **a)
    1876: {

    1881:   if (x->petscnative) {
    1882: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
    1883:     x->offloadmask = PETSC_OFFLOAD_CPU;
    1884: #endif
    1885:   } else {
    1886:     (*x->ops->restorearray)(x,a);
    1887:   }
    1888:   if (a) *a = NULL;
    1889:   PetscObjectStateIncrease((PetscObject)x);
    1890:   return(0);
    1891: }

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

    1896:    Logically Collective on Vec

    1898:    Input Parameters:
    1899: +  x - the vector
    1900: -  a - location of pointer to array obtained from VecGetArrayInPlace()

    1902:    Level: beginner

    1904: .seealso: VecGetArrayInPlace(), VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(),
    1905:           VecPlaceArray(), VecRestoreArray2d(), VecGetArrayPair(), VecRestoreArrayPair()
    1906: @*/
    1907: PetscErrorCode VecRestoreArrayInPlace(Vec x,PetscScalar **a)
    1908: {

    1913: #if defined(PETSC_HAVE_CUDA)
    1914:   if (x->petscnative && x->offloadmask == PETSC_OFFLOAD_GPU) {
    1915:     PetscBool is_cudatype = PETSC_FALSE;
    1916:     PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");
    1917:     if (is_cudatype) {
    1918:       VecCUDARestoreArray(x,a);
    1919:       return(0);
    1920:     }
    1921:   }
    1922: #endif
    1923:   VecRestoreArray(x,a);
    1924:   return(0);
    1925: }

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

    1931:    Logically Collective on Vec

    1933:    Input Parameters:
    1934: +  x - the vector
    1935: -  a - location of pointer to array obtained from VecGetArray()

    1937:    Level: beginner

    1939: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
    1940:           VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite()
    1941: @*/
    1942: PetscErrorCode VecRestoreArrayWrite(Vec x,PetscScalar **a)
    1943: {

    1948:   if (x->petscnative) {
    1949: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
    1950:     x->offloadmask = PETSC_OFFLOAD_CPU;
    1951: #endif
    1952:   } else {
    1953:     if (x->ops->restorearraywrite) {
    1954:       (*x->ops->restorearraywrite)(x,a);
    1955:     } else {
    1956:       (*x->ops->restorearray)(x,a);
    1957:     }
    1958:   }
    1959:   if (a) *a = NULL;
    1960:   PetscObjectStateIncrease((PetscObject)x);
    1961:   return(0);
    1962: }

    1964: /*@C
    1965:    VecRestoreArrayRead - Restore array obtained with VecGetArrayRead()

    1967:    Not Collective

    1969:    Input Parameters:
    1970: +  vec - the vector
    1971: -  array - the array

    1973:    Level: beginner

    1975: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
    1976: @*/
    1977: PetscErrorCode VecRestoreArrayRead(Vec x,const PetscScalar **a)
    1978: {

    1983:   if (x->petscnative) {
    1984:     /* nothing */
    1985:   } else if (x->ops->restorearrayread) {
    1986:     (*x->ops->restorearrayread)(x,a);
    1987:   } else {
    1988:     (*x->ops->restorearray)(x,(PetscScalar**)a);
    1989:   }
    1990:   if (a) *a = NULL;
    1991:   return(0);
    1992: }

    1994: /*@C
    1995:    VecRestoreArrayReadInPlace - Restore array obtained with VecGetArrayReadInPlace()

    1997:    Not Collective

    1999:    Input Parameters:
    2000: +  vec - the vector
    2001: -  array - the array

    2003:    Level: beginner

    2005: .seealso: VecGetArrayReadInPlace(), VecRestoreArrayInPlace(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
    2006: @*/
    2007: PetscErrorCode VecRestoreArrayReadInPlace(Vec x,const PetscScalar **a)
    2008: {

    2012:   VecRestoreArrayRead(x,a);
    2013:   return(0);
    2014: }

    2016: /*@
    2017:    VecPlaceArray - Allows one to replace the array in a vector with an
    2018:    array provided by the user. This is useful to avoid copying an array
    2019:    into a vector.

    2021:    Not Collective

    2023:    Input Parameters:
    2024: +  vec - the vector
    2025: -  array - the array

    2027:    Notes:
    2028:    You can return to the original array with a call to VecResetArray()

    2030:    Level: developer

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

    2034: @*/
    2035: PetscErrorCode  VecPlaceArray(Vec vec,const PetscScalar array[])
    2036: {

    2043:   if (vec->ops->placearray) {
    2044:     (*vec->ops->placearray)(vec,array);
    2045:   } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot place array in this type of vector");
    2046:   PetscObjectStateIncrease((PetscObject)vec);
    2047:   return(0);
    2048: }

    2050: /*@C
    2051:    VecReplaceArray - Allows one to replace the array in a vector with an
    2052:    array provided by the user. This is useful to avoid copying an array
    2053:    into a vector.

    2055:    Not Collective

    2057:    Input Parameters:
    2058: +  vec - the vector
    2059: -  array - the array

    2061:    Notes:
    2062:    This permanently replaces the array and frees the memory associated
    2063:    with the old array.

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

    2068:    Not supported from Fortran

    2070:    Level: developer

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

    2074: @*/
    2075: PetscErrorCode  VecReplaceArray(Vec vec,const PetscScalar array[])
    2076: {

    2082:   if (vec->ops->replacearray) {
    2083:     (*vec->ops->replacearray)(vec,array);
    2084:   } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot replace array in this type of vector");
    2085:   PetscObjectStateIncrease((PetscObject)vec);
    2086:   return(0);
    2087: }

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

    2093:    This function has semantics similar to VecGetArray():  the pointer
    2094:    returned by this function points to a consistent view of the vector
    2095:    data.  This may involve a copy operation of data from the host to the
    2096:    device if the data on the device is out of date.  If the device
    2097:    memory hasn't been allocated previously it will be allocated as part
    2098:    of this function call.  VecCUDAGetArray() assumes that
    2099:    the user will modify the vector data.  This is similar to
    2100:    intent(inout) in fortran.

    2102:    The CUDA device pointer has to be released by calling
    2103:    VecCUDARestoreArray().  Upon restoring the vector data
    2104:    the data on the host will be marked as out of date.  A subsequent
    2105:    access of the host data will thus incur a data transfer from the
    2106:    device to the host.

    2109:    Input Parameter:
    2110: .  v - the vector

    2112:    Output Parameter:
    2113: .  a - the CUDA device pointer

    2115:    Fortran note:
    2116:    This function is not currently available from Fortran.

    2118:    Level: intermediate

    2120: .seealso: VecCUDARestoreArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
    2121: @*/
    2122: PETSC_EXTERN PetscErrorCode VecCUDAGetArray(Vec v, PetscScalar **a)
    2123: {
    2124: #if defined(PETSC_HAVE_CUDA)
    2126: #endif

    2130: #if defined(PETSC_HAVE_CUDA)
    2131:   *a   = 0;
    2132:   VecCUDACopyToGPU(v);
    2133:   *a   = ((Vec_CUDA*)v->spptr)->GPUarray;
    2134: #endif
    2135:   return(0);
    2136: }

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

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

    2145:    Input Parameter:
    2146: +  v - the vector
    2147: -  a - the CUDA device pointer.  This pointer is invalid after
    2148:        VecCUDARestoreArray() returns.

    2150:    Fortran note:
    2151:    This function is not currently available from Fortran.

    2153:    Level: intermediate

    2155: .seealso: VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
    2156: @*/
    2157: PETSC_EXTERN PetscErrorCode VecCUDARestoreArray(Vec v, PetscScalar **a)
    2158: {

    2163: #if defined(PETSC_HAVE_CUDA)
    2164:   v->offloadmask = PETSC_OFFLOAD_GPU;
    2165: #endif

    2167:   PetscObjectStateIncrease((PetscObject)v);
    2168:   return(0);
    2169: }

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

    2174:    This function is analogous to VecGetArrayRead():  The pointer
    2175:    returned by this function points to a consistent view of the vector
    2176:    data.  This may involve a copy operation of data from the host to the
    2177:    device if the data on the device is out of date.  If the device
    2178:    memory hasn't been allocated previously it will be allocated as part
    2179:    of this function call.  VecCUDAGetArrayRead() assumes that the
    2180:    user will not modify the vector data.  This is analgogous to
    2181:    intent(in) in Fortran.

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

    2189:    Input Parameter:
    2190: .  v - the vector

    2192:    Output Parameter:
    2193: .  a - the CUDA pointer.

    2195:    Fortran note:
    2196:    This function is not currently available from Fortran.

    2198:    Level: intermediate

    2200: .seealso: VecCUDARestoreArrayRead(), VecCUDAGetArray(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
    2201: @*/
    2202: PETSC_EXTERN PetscErrorCode VecCUDAGetArrayRead(Vec v, const PetscScalar **a)
    2203: {
    2204: #if defined(PETSC_HAVE_CUDA)
    2206: #endif

    2210: #if defined(PETSC_HAVE_CUDA)
    2211:   *a   = 0;
    2212:   VecCUDACopyToGPU(v);
    2213:   *a   = ((Vec_CUDA*)v->spptr)->GPUarray;
    2214: #endif
    2215:   return(0);
    2216: }

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

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

    2226:    Input Parameter:
    2227: +  v - the vector
    2228: -  a - the CUDA device pointer.  This pointer is invalid after
    2229:        VecCUDARestoreArrayRead() returns.

    2231:    Fortran note:
    2232:    This function is not currently available from Fortran.

    2234:    Level: intermediate

    2236: .seealso: VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecCUDAGetArray(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
    2237: @*/
    2238: PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayRead(Vec v, const PetscScalar **a)
    2239: {
    2242:   *a = NULL;
    2243:   return(0);
    2244: }

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

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

    2255:    The device pointer needs to be released with
    2256:    VecCUDARestoreArrayWrite().  When the pointer is released the
    2257:    host data of the vector is marked as out of data.  Subsequent access
    2258:    of the host data with e.g. VecGetArray() incurs a device to host data
    2259:    transfer.

    2262:    Input Parameter:
    2263: .  v - the vector

    2265:    Output Parameter:
    2266: .  a - the CUDA pointer

    2268:    Fortran note:
    2269:    This function is not currently available from Fortran.

    2271:    Level: advanced

    2273: .seealso: VecCUDARestoreArrayWrite(), VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
    2274: @*/
    2275: PETSC_EXTERN PetscErrorCode VecCUDAGetArrayWrite(Vec v, PetscScalar **a)
    2276: {
    2277: #if defined(PETSC_HAVE_CUDA)
    2279: #endif

    2283: #if defined(PETSC_HAVE_CUDA)
    2284:   *a   = 0;
    2285:   VecCUDAAllocateCheck(v);
    2286:   *a   = ((Vec_CUDA*)v->spptr)->GPUarray;
    2287: #endif
    2288:   return(0);
    2289: }

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

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

    2298:    Input Parameter:
    2299: +  v - the vector
    2300: -  a - the CUDA device pointer.  This pointer is invalid after
    2301:        VecCUDARestoreArrayWrite() returns.

    2303:    Fortran note:
    2304:    This function is not currently available from Fortran.

    2306:    Level: intermediate

    2308: .seealso: VecCUDAGetArrayWrite(), VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
    2309: @*/
    2310: PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayWrite(Vec v, PetscScalar **a)
    2311: {

    2316: #if defined(PETSC_HAVE_CUDA)
    2317:   v->offloadmask = PETSC_OFFLOAD_GPU;
    2318: #endif

    2320:   PetscObjectStateIncrease((PetscObject)v);
    2321:   return(0);
    2322: }

    2324: /*@C
    2325:    VecCUDAPlaceArray - Allows one to replace the GPU array in a vector with a
    2326:    GPU array provided by the user. This is useful to avoid copying an
    2327:    array into a vector.

    2329:    Not Collective

    2331:    Input Parameters:
    2332: +  vec - the vector
    2333: -  array - the GPU array

    2335:    Notes:
    2336:    You can return to the original GPU array with a call to VecCUDAResetArray()
    2337:    It is not possible to use VecCUDAPlaceArray() and VecPlaceArray() at the
    2338:    same time on the same vector.

    2340:    Level: developer

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

    2344: @*/
    2345: PetscErrorCode VecCUDAPlaceArray(Vec vin,PetscScalar *a)
    2346: {

    2351: #if defined(PETSC_HAVE_CUDA)
    2352:   VecCUDACopyToGPU(vin);
    2353:   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()");
    2354:   ((Vec_Seq*)vin->data)->unplacedarray  = (PetscScalar *) ((Vec_CUDA*)vin->spptr)->GPUarray; /* save previous GPU array so reset can bring it back */
    2355:   ((Vec_CUDA*)vin->spptr)->GPUarray = a;
    2356:   vin->offloadmask = PETSC_OFFLOAD_GPU;
    2357: #endif
    2358:   PetscObjectStateIncrease((PetscObject)vin);
    2359:   return(0);
    2360: }

    2362: /*@C
    2363:    VecCUDAReplaceArray - Allows one to replace the GPU array in a vector
    2364:    with a GPU array provided by the user. This is useful to avoid copying
    2365:    a GPU array into a vector.

    2367:    Not Collective

    2369:    Input Parameters:
    2370: +  vec - the vector
    2371: -  array - the GPU array

    2373:    Notes:
    2374:    This permanently replaces the GPU array and frees the memory associated
    2375:    with the old GPU array.

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

    2380:    Not supported from Fortran

    2382:    Level: developer

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

    2386: @*/
    2387: PetscErrorCode VecCUDAReplaceArray(Vec vin,PetscScalar *a)
    2388: {
    2389: #if defined(PETSC_HAVE_CUDA)
    2390:   cudaError_t err;
    2391: #endif

    2396: #if defined(PETSC_HAVE_CUDA)
    2397:   err = cudaFree(((Vec_CUDA*)vin->spptr)->GPUarray);CHKERRCUDA(err);
    2398:   ((Vec_CUDA*)vin->spptr)->GPUarray = a;
    2399:   vin->offloadmask = PETSC_OFFLOAD_GPU;
    2400: #endif
    2401:   PetscObjectStateIncrease((PetscObject)vin);
    2402:   return(0);
    2403: }

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

    2409:    Not Collective

    2411:    Input Parameters:
    2412: .  vec - the vector

    2414:    Level: developer

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

    2418: @*/
    2419: PetscErrorCode VecCUDAResetArray(Vec vin)
    2420: {

    2425: #if defined(PETSC_HAVE_CUDA)
    2426:   VecCUDACopyToGPU(vin);
    2427:   ((Vec_CUDA*)vin->spptr)->GPUarray = (PetscScalar *) ((Vec_Seq*)vin->data)->unplacedarray;
    2428:   ((Vec_Seq*)vin->data)->unplacedarray = 0;
    2429:   vin->offloadmask = PETSC_OFFLOAD_GPU;
    2430: #endif
    2431:   PetscObjectStateIncrease((PetscObject)vin);
    2432:   return(0);
    2433: }

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

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

    2442:     Collective on Vec

    2444:     Input Parameters:
    2445: +   x - a vector to mimic
    2446: -   n - the number of vectors to obtain

    2448:     Output Parameters:
    2449: +   y - Fortran90 pointer to the array of vectors
    2450: -   ierr - error code

    2452:     Example of Usage:
    2453: .vb
    2454:  #include <petsc/finclude/petscvec.h>
    2455:     use petscvec

    2457:     Vec x
    2458:     Vec, pointer :: y(:)
    2459:     ....
    2460:     call VecDuplicateVecsF90(x,2,y,ierr)
    2461:     call VecSet(y(2),alpha,ierr)
    2462:     call VecSet(y(2),alpha,ierr)
    2463:     ....
    2464:     call VecDestroyVecsF90(2,y,ierr)
    2465: .ve

    2467:     Notes:
    2468:     Not yet supported for all F90 compilers

    2470:     Use VecDestroyVecsF90() to free the space.

    2472:     Level: beginner

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

    2476: M*/

    2478: /*MC
    2479:     VecRestoreArrayF90 - Restores a vector to a usable state after a call to
    2480:     VecGetArrayF90().

    2482:     Synopsis:
    2483:     VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

    2485:     Logically Collective on Vec

    2487:     Input Parameters:
    2488: +   x - vector
    2489: -   xx_v - the Fortran90 pointer to the array

    2491:     Output Parameter:
    2492: .   ierr - error code

    2494:     Example of Usage:
    2495: .vb
    2496:  #include <petsc/finclude/petscvec.h>
    2497:     use petscvec

    2499:     PetscScalar, pointer :: xx_v(:)
    2500:     ....
    2501:     call VecGetArrayF90(x,xx_v,ierr)
    2502:     xx_v(3) = a
    2503:     call VecRestoreArrayF90(x,xx_v,ierr)
    2504: .ve

    2506:     Level: beginner

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

    2510: M*/

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

    2515:     Synopsis:
    2516:     VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)

    2518:     Collective on Vec

    2520:     Input Parameters:
    2521: +   n - the number of vectors previously obtained
    2522: -   x - pointer to array of vector pointers

    2524:     Output Parameter:
    2525: .   ierr - error code

    2527:     Notes:
    2528:     Not yet supported for all F90 compilers

    2530:     Level: beginner

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

    2534: M*/

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

    2542:     Synopsis:
    2543:     VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

    2545:     Logically Collective on Vec

    2547:     Input Parameter:
    2548: .   x - vector

    2550:     Output Parameters:
    2551: +   xx_v - the Fortran90 pointer to the array
    2552: -   ierr - error code

    2554:     Example of Usage:
    2555: .vb
    2556:  #include <petsc/finclude/petscvec.h>
    2557:     use petscvec

    2559:     PetscScalar, pointer :: xx_v(:)
    2560:     ....
    2561:     call VecGetArrayF90(x,xx_v,ierr)
    2562:     xx_v(3) = a
    2563:     call VecRestoreArrayF90(x,xx_v,ierr)
    2564: .ve

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

    2568:     Level: beginner

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

    2572: M*/

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

    2580:     Synopsis:
    2581:     VecGetArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

    2583:     Logically Collective on Vec

    2585:     Input Parameter:
    2586: .   x - vector

    2588:     Output Parameters:
    2589: +   xx_v - the Fortran90 pointer to the array
    2590: -   ierr - error code

    2592:     Example of Usage:
    2593: .vb
    2594:  #include <petsc/finclude/petscvec.h>
    2595:     use petscvec

    2597:     PetscScalar, pointer :: xx_v(:)
    2598:     ....
    2599:     call VecGetArrayReadF90(x,xx_v,ierr)
    2600:     a = xx_v(3)
    2601:     call VecRestoreArrayReadF90(x,xx_v,ierr)
    2602: .ve

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

    2606:     Level: beginner

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

    2610: M*/

    2612: /*MC
    2613:     VecRestoreArrayReadF90 - Restores a readonly vector to a usable state after a call to
    2614:     VecGetArrayReadF90().

    2616:     Synopsis:
    2617:     VecRestoreArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

    2619:     Logically Collective on Vec

    2621:     Input Parameters:
    2622: +   x - vector
    2623: -   xx_v - the Fortran90 pointer to the array

    2625:     Output Parameter:
    2626: .   ierr - error code

    2628:     Example of Usage:
    2629: .vb
    2630:  #include <petsc/finclude/petscvec.h>
    2631:     use petscvec

    2633:     PetscScalar, pointer :: xx_v(:)
    2634:     ....
    2635:     call VecGetArrayReadF90(x,xx_v,ierr)
    2636:     a = xx_v(3)
    2637:     call VecRestoreArrayReadF90(x,xx_v,ierr)
    2638: .ve

    2640:     Level: beginner

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

    2644: M*/

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

    2651:    Logically Collective

    2653:    Input Parameter:
    2654: +  x - the vector
    2655: .  m - first dimension of two dimensional array
    2656: .  n - second dimension of two dimensional array
    2657: .  mstart - first index you will use in first coordinate direction (often 0)
    2658: -  nstart - first index in the second coordinate direction (often 0)

    2660:    Output Parameter:
    2661: .  a - location to put pointer to the array

    2663:    Level: developer

    2665:   Notes:
    2666:    For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
    2667:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
    2668:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
    2669:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().

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

    2673: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    2674:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    2675:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2676: @*/
    2677: PetscErrorCode  VecGetArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
    2678: {
    2680:   PetscInt       i,N;
    2681:   PetscScalar    *aa;

    2687:   VecGetLocalSize(x,&N);
    2688:   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);
    2689:   VecGetArray(x,&aa);

    2691:   PetscMalloc1(m,a);
    2692:   for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
    2693:   *a -= mstart;
    2694:   return(0);
    2695: }

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

    2702:    Logically Collective

    2704:    Input Parameter:
    2705: +  x - the vector
    2706: .  m - first dimension of two dimensional array
    2707: .  n - second dimension of two dimensional array
    2708: .  mstart - first index you will use in first coordinate direction (often 0)
    2709: -  nstart - first index in the second coordinate direction (often 0)

    2711:    Output Parameter:
    2712: .  a - location to put pointer to the array

    2714:    Level: developer

    2716:   Notes:
    2717:    For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
    2718:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
    2719:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
    2720:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().

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

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

    2726: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    2727:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    2728:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2729: @*/
    2730: PetscErrorCode  VecGetArray2dWrite(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
    2731: {
    2733:   PetscInt       i,N;
    2734:   PetscScalar    *aa;

    2740:   VecGetLocalSize(x,&N);
    2741:   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);
    2742:   VecGetArrayWrite(x,&aa);

    2744:   PetscMalloc1(m,a);
    2745:   for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
    2746:   *a -= mstart;
    2747:   return(0);
    2748: }

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

    2753:    Logically Collective

    2755:    Input Parameters:
    2756: +  x - the vector
    2757: .  m - first dimension of two dimensional array
    2758: .  n - second dimension of the two dimensional array
    2759: .  mstart - first index you will use in first coordinate direction (often 0)
    2760: .  nstart - first index in the second coordinate direction (often 0)
    2761: -  a - location of pointer to array obtained from VecGetArray2d()

    2763:    Level: developer

    2765:    Notes:
    2766:    For regular PETSc vectors this routine does not involve any copies. For
    2767:    any special vectors that do not store local vector data in a contiguous
    2768:    array, this routine will copy the data back into the underlying
    2769:    vector data structure from the array obtained with VecGetArray().

    2771:    This routine actually zeros out the a pointer.

    2773: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    2774:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    2775:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2776: @*/
    2777: PetscErrorCode  VecRestoreArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
    2778: {
    2780:   void           *dummy;

    2786:   dummy = (void*)(*a + mstart);
    2787:   PetscFree(dummy);
    2788:   VecRestoreArray(x,NULL);
    2789:   return(0);
    2790: }

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

    2795:    Logically Collective

    2797:    Input Parameters:
    2798: +  x - the vector
    2799: .  m - first dimension of two dimensional array
    2800: .  n - second dimension of the two dimensional array
    2801: .  mstart - first index you will use in first coordinate direction (often 0)
    2802: .  nstart - first index in the second coordinate direction (often 0)
    2803: -  a - location of pointer to array obtained from VecGetArray2d()

    2805:    Level: developer

    2807:    Notes:
    2808:    For regular PETSc vectors this routine does not involve any copies. For
    2809:    any special vectors that do not store local vector data in a contiguous
    2810:    array, this routine will copy the data back into the underlying
    2811:    vector data structure from the array obtained with VecGetArray().

    2813:    This routine actually zeros out the a pointer.

    2815: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    2816:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    2817:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2818: @*/
    2819: PetscErrorCode  VecRestoreArray2dWrite(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
    2820: {
    2822:   void           *dummy;

    2828:   dummy = (void*)(*a + mstart);
    2829:   PetscFree(dummy);
    2830:   VecRestoreArrayWrite(x,NULL);
    2831:   return(0);
    2832: }

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

    2839:    Logically Collective

    2841:    Input Parameter:
    2842: +  x - the vector
    2843: .  m - first dimension of two dimensional array
    2844: -  mstart - first index you will use in first coordinate direction (often 0)

    2846:    Output Parameter:
    2847: .  a - location to put pointer to the array

    2849:    Level: developer

    2851:   Notes:
    2852:    For a vector obtained from DMCreateLocalVector() mstart are likely
    2853:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
    2854:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().

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

    2858: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    2859:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    2860:           VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2861: @*/
    2862: PetscErrorCode  VecGetArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
    2863: {
    2865:   PetscInt       N;

    2871:   VecGetLocalSize(x,&N);
    2872:   if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
    2873:   VecGetArray(x,a);
    2874:   *a  -= mstart;
    2875:   return(0);
    2876: }

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

    2883:    Logically Collective

    2885:    Input Parameter:
    2886: +  x - the vector
    2887: .  m - first dimension of two dimensional array
    2888: -  mstart - first index you will use in first coordinate direction (often 0)

    2890:    Output Parameter:
    2891: .  a - location to put pointer to the array

    2893:    Level: developer

    2895:   Notes:
    2896:    For a vector obtained from DMCreateLocalVector() mstart are likely
    2897:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
    2898:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().

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

    2902: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    2903:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    2904:           VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2905: @*/
    2906: PetscErrorCode  VecGetArray1dWrite(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
    2907: {
    2909:   PetscInt       N;

    2915:   VecGetLocalSize(x,&N);
    2916:   if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
    2917:   VecGetArrayWrite(x,a);
    2918:   *a  -= mstart;
    2919:   return(0);
    2920: }

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

    2925:    Logically Collective

    2927:    Input Parameters:
    2928: +  x - the vector
    2929: .  m - first dimension of two dimensional array
    2930: .  mstart - first index you will use in first coordinate direction (often 0)
    2931: -  a - location of pointer to array obtained from VecGetArray21()

    2933:    Level: developer

    2935:    Notes:
    2936:    For regular PETSc vectors this routine does not involve any copies. For
    2937:    any special vectors that do not store local vector data in a contiguous
    2938:    array, this routine will copy the data back into the underlying
    2939:    vector data structure from the array obtained with VecGetArray1d().

    2941:    This routine actually zeros out the a pointer.

    2943: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    2944:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    2945:           VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
    2946: @*/
    2947: PetscErrorCode  VecRestoreArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
    2948: {

    2954:   VecRestoreArray(x,NULL);
    2955:   return(0);
    2956: }

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

    2961:    Logically Collective

    2963:    Input Parameters:
    2964: +  x - the vector
    2965: .  m - first dimension of two dimensional array
    2966: .  mstart - first index you will use in first coordinate direction (often 0)
    2967: -  a - location of pointer to array obtained from VecGetArray21()

    2969:    Level: developer

    2971:    Notes:
    2972:    For regular PETSc vectors this routine does not involve any copies. For
    2973:    any special vectors that do not store local vector data in a contiguous
    2974:    array, this routine will copy the data back into the underlying
    2975:    vector data structure from the array obtained with VecGetArray1d().

    2977:    This routine actually zeros out the a pointer.

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

    2981: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    2982:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    2983:           VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
    2984: @*/
    2985: PetscErrorCode  VecRestoreArray1dWrite(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
    2986: {

    2992:   VecRestoreArrayWrite(x,NULL);
    2993:   return(0);
    2994: }

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

    3001:    Logically Collective

    3003:    Input Parameter:
    3004: +  x - the vector
    3005: .  m - first dimension of three dimensional array
    3006: .  n - second dimension of three dimensional array
    3007: .  p - third dimension of three dimensional array
    3008: .  mstart - first index you will use in first coordinate direction (often 0)
    3009: .  nstart - first index in the second coordinate direction (often 0)
    3010: -  pstart - first index in the third coordinate direction (often 0)

    3012:    Output Parameter:
    3013: .  a - location to put pointer to the array

    3015:    Level: developer

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

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

    3025: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    3026:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    3027:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    3028: @*/
    3029: PetscErrorCode  VecGetArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
    3030: {
    3032:   PetscInt       i,N,j;
    3033:   PetscScalar    *aa,**b;

    3039:   VecGetLocalSize(x,&N);
    3040:   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);
    3041:   VecGetArray(x,&aa);

    3043:   PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
    3044:   b    = (PetscScalar**)((*a) + m);
    3045:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
    3046:   for (i=0; i<m; i++)
    3047:     for (j=0; j<n; j++)
    3048:       b[i*n+j] = aa + i*n*p + j*p - pstart;

    3050:   *a -= mstart;
    3051:   return(0);
    3052: }

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

    3059:    Logically Collective

    3061:    Input Parameter:
    3062: +  x - the vector
    3063: .  m - first dimension of three dimensional array
    3064: .  n - second dimension of three dimensional array
    3065: .  p - third dimension of three dimensional array
    3066: .  mstart - first index you will use in first coordinate direction (often 0)
    3067: .  nstart - first index in the second coordinate direction (often 0)
    3068: -  pstart - first index in the third coordinate direction (often 0)

    3070:    Output Parameter:
    3071: .  a - location to put pointer to the array

    3073:    Level: developer

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

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

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

    3085: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    3086:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    3087:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    3088: @*/
    3089: PetscErrorCode  VecGetArray3dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
    3090: {
    3092:   PetscInt       i,N,j;
    3093:   PetscScalar    *aa,**b;

    3099:   VecGetLocalSize(x,&N);
    3100:   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);
    3101:   VecGetArrayWrite(x,&aa);

    3103:   PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
    3104:   b    = (PetscScalar**)((*a) + m);
    3105:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
    3106:   for (i=0; i<m; i++)
    3107:     for (j=0; j<n; j++)
    3108:       b[i*n+j] = aa + i*n*p + j*p - pstart;

    3110:   *a -= mstart;
    3111:   return(0);
    3112: }

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

    3117:    Logically Collective

    3119:    Input Parameters:
    3120: +  x - the vector
    3121: .  m - first dimension of three dimensional array
    3122: .  n - second dimension of the three dimensional array
    3123: .  p - third dimension of the three dimensional array
    3124: .  mstart - first index you will use in first coordinate direction (often 0)
    3125: .  nstart - first index in the second coordinate direction (often 0)
    3126: .  pstart - first index in the third coordinate direction (often 0)
    3127: -  a - location of pointer to array obtained from VecGetArray3d()

    3129:    Level: developer

    3131:    Notes:
    3132:    For regular PETSc vectors this routine does not involve any copies. For
    3133:    any special vectors that do not store local vector data in a contiguous
    3134:    array, this routine will copy the data back into the underlying
    3135:    vector data structure from the array obtained with VecGetArray().

    3137:    This routine actually zeros out the a pointer.

    3139: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    3140:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    3141:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
    3142: @*/
    3143: PetscErrorCode  VecRestoreArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
    3144: {
    3146:   void           *dummy;

    3152:   dummy = (void*)(*a + mstart);
    3153:   PetscFree(dummy);
    3154:   VecRestoreArray(x,NULL);
    3155:   return(0);
    3156: }

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

    3161:    Logically Collective

    3163:    Input Parameters:
    3164: +  x - the vector
    3165: .  m - first dimension of three dimensional array
    3166: .  n - second dimension of the three dimensional array
    3167: .  p - third dimension of the three dimensional array
    3168: .  mstart - first index you will use in first coordinate direction (often 0)
    3169: .  nstart - first index in the second coordinate direction (often 0)
    3170: .  pstart - first index in the third coordinate direction (often 0)
    3171: -  a - location of pointer to array obtained from VecGetArray3d()

    3173:    Level: developer

    3175:    Notes:
    3176:    For regular PETSc vectors this routine does not involve any copies. For
    3177:    any special vectors that do not store local vector data in a contiguous
    3178:    array, this routine will copy the data back into the underlying
    3179:    vector data structure from the array obtained with VecGetArray().

    3181:    This routine actually zeros out the a pointer.

    3183: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    3184:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    3185:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
    3186: @*/
    3187: PetscErrorCode  VecRestoreArray3dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
    3188: {
    3190:   void           *dummy;

    3196:   dummy = (void*)(*a + mstart);
    3197:   PetscFree(dummy);
    3198:   VecRestoreArrayWrite(x,NULL);
    3199:   return(0);
    3200: }

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

    3207:    Logically Collective

    3209:    Input Parameter:
    3210: +  x - the vector
    3211: .  m - first dimension of four dimensional array
    3212: .  n - second dimension of four dimensional array
    3213: .  p - third dimension of four dimensional array
    3214: .  q - fourth dimension of four dimensional array
    3215: .  mstart - first index you will use in first coordinate direction (often 0)
    3216: .  nstart - first index in the second coordinate direction (often 0)
    3217: .  pstart - first index in the third coordinate direction (often 0)
    3218: -  qstart - first index in the fourth coordinate direction (often 0)

    3220:    Output Parameter:
    3221: .  a - location to put pointer to the array

    3223:    Level: beginner

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

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

    3233: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    3234:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    3235:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    3236: @*/
    3237: PetscErrorCode  VecGetArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
    3238: {
    3240:   PetscInt       i,N,j,k;
    3241:   PetscScalar    *aa,***b,**c;

    3247:   VecGetLocalSize(x,&N);
    3248:   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);
    3249:   VecGetArray(x,&aa);

    3251:   PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
    3252:   b    = (PetscScalar***)((*a) + m);
    3253:   c    = (PetscScalar**)(b + m*n);
    3254:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
    3255:   for (i=0; i<m; i++)
    3256:     for (j=0; j<n; j++)
    3257:       b[i*n+j] = c + i*n*p + j*p - pstart;
    3258:   for (i=0; i<m; i++)
    3259:     for (j=0; j<n; j++)
    3260:       for (k=0; k<p; k++)
    3261:         c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
    3262:   *a -= mstart;
    3263:   return(0);
    3264: }

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

    3271:    Logically Collective

    3273:    Input Parameter:
    3274: +  x - the vector
    3275: .  m - first dimension of four dimensional array
    3276: .  n - second dimension of four dimensional array
    3277: .  p - third dimension of four dimensional array
    3278: .  q - fourth dimension of four dimensional array
    3279: .  mstart - first index you will use in first coordinate direction (often 0)
    3280: .  nstart - first index in the second coordinate direction (often 0)
    3281: .  pstart - first index in the third coordinate direction (often 0)
    3282: -  qstart - first index in the fourth coordinate direction (often 0)

    3284:    Output Parameter:
    3285: .  a - location to put pointer to the array

    3287:    Level: beginner

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

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

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

    3299: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    3300:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    3301:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    3302: @*/
    3303: PetscErrorCode  VecGetArray4dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
    3304: {
    3306:   PetscInt       i,N,j,k;
    3307:   PetscScalar    *aa,***b,**c;

    3313:   VecGetLocalSize(x,&N);
    3314:   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);
    3315:   VecGetArrayWrite(x,&aa);

    3317:   PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
    3318:   b    = (PetscScalar***)((*a) + m);
    3319:   c    = (PetscScalar**)(b + m*n);
    3320:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
    3321:   for (i=0; i<m; i++)
    3322:     for (j=0; j<n; j++)
    3323:       b[i*n+j] = c + i*n*p + j*p - pstart;
    3324:   for (i=0; i<m; i++)
    3325:     for (j=0; j<n; j++)
    3326:       for (k=0; k<p; k++)
    3327:         c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
    3328:   *a -= mstart;
    3329:   return(0);
    3330: }

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

    3335:    Logically Collective

    3337:    Input Parameters:
    3338: +  x - the vector
    3339: .  m - first dimension of four dimensional array
    3340: .  n - second dimension of the four dimensional array
    3341: .  p - third dimension of the four dimensional array
    3342: .  q - fourth dimension of the four dimensional array
    3343: .  mstart - first index you will use in first coordinate direction (often 0)
    3344: .  nstart - first index in the second coordinate direction (often 0)
    3345: .  pstart - first index in the third coordinate direction (often 0)
    3346: .  qstart - first index in the fourth coordinate direction (often 0)
    3347: -  a - location of pointer to array obtained from VecGetArray4d()

    3349:    Level: beginner

    3351:    Notes:
    3352:    For regular PETSc vectors this routine does not involve any copies. For
    3353:    any special vectors that do not store local vector data in a contiguous
    3354:    array, this routine will copy the data back into the underlying
    3355:    vector data structure from the array obtained with VecGetArray().

    3357:    This routine actually zeros out the a pointer.

    3359: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    3360:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    3361:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
    3362: @*/
    3363: PetscErrorCode  VecRestoreArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
    3364: {
    3366:   void           *dummy;

    3372:   dummy = (void*)(*a + mstart);
    3373:   PetscFree(dummy);
    3374:   VecRestoreArray(x,NULL);
    3375:   return(0);
    3376: }

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

    3381:    Logically Collective

    3383:    Input Parameters:
    3384: +  x - the vector
    3385: .  m - first dimension of four dimensional array
    3386: .  n - second dimension of the four dimensional array
    3387: .  p - third dimension of the four dimensional array
    3388: .  q - fourth dimension of the four dimensional array
    3389: .  mstart - first index you will use in first coordinate direction (often 0)
    3390: .  nstart - first index in the second coordinate direction (often 0)
    3391: .  pstart - first index in the third coordinate direction (often 0)
    3392: .  qstart - first index in the fourth coordinate direction (often 0)
    3393: -  a - location of pointer to array obtained from VecGetArray4d()

    3395:    Level: beginner

    3397:    Notes:
    3398:    For regular PETSc vectors this routine does not involve any copies. For
    3399:    any special vectors that do not store local vector data in a contiguous
    3400:    array, this routine will copy the data back into the underlying
    3401:    vector data structure from the array obtained with VecGetArray().

    3403:    This routine actually zeros out the a pointer.

    3405: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    3406:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    3407:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
    3408: @*/
    3409: PetscErrorCode  VecRestoreArray4dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
    3410: {
    3412:   void           *dummy;

    3418:   dummy = (void*)(*a + mstart);
    3419:   PetscFree(dummy);
    3420:   VecRestoreArrayWrite(x,NULL);
    3421:   return(0);
    3422: }

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

    3429:    Logically Collective

    3431:    Input Parameter:
    3432: +  x - the vector
    3433: .  m - first dimension of two dimensional array
    3434: .  n - second dimension of two dimensional array
    3435: .  mstart - first index you will use in first coordinate direction (often 0)
    3436: -  nstart - first index in the second coordinate direction (often 0)

    3438:    Output Parameter:
    3439: .  a - location to put pointer to the array

    3441:    Level: developer

    3443:   Notes:
    3444:    For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
    3445:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
    3446:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
    3447:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().

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

    3451: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    3452:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    3453:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    3454: @*/
    3455: PetscErrorCode  VecGetArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
    3456: {
    3457:   PetscErrorCode    ierr;
    3458:   PetscInt          i,N;
    3459:   const PetscScalar *aa;

    3465:   VecGetLocalSize(x,&N);
    3466:   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);
    3467:   VecGetArrayRead(x,&aa);

    3469:   PetscMalloc1(m,a);
    3470:   for (i=0; i<m; i++) (*a)[i] = (PetscScalar*) aa + i*n - nstart;
    3471:   *a -= mstart;
    3472:   return(0);
    3473: }

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

    3478:    Logically Collective

    3480:    Input Parameters:
    3481: +  x - the vector
    3482: .  m - first dimension of two dimensional array
    3483: .  n - second dimension of the two dimensional array
    3484: .  mstart - first index you will use in first coordinate direction (often 0)
    3485: .  nstart - first index in the second coordinate direction (often 0)
    3486: -  a - location of pointer to array obtained from VecGetArray2d()

    3488:    Level: developer

    3490:    Notes:
    3491:    For regular PETSc vectors this routine does not involve any copies. For
    3492:    any special vectors that do not store local vector data in a contiguous
    3493:    array, this routine will copy the data back into the underlying
    3494:    vector data structure from the array obtained with VecGetArray().

    3496:    This routine actually zeros out the a pointer.

    3498: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    3499:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    3500:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    3501: @*/
    3502: PetscErrorCode  VecRestoreArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
    3503: {
    3505:   void           *dummy;

    3511:   dummy = (void*)(*a + mstart);
    3512:   PetscFree(dummy);
    3513:   VecRestoreArrayRead(x,NULL);
    3514:   return(0);
    3515: }

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

    3522:    Logically Collective

    3524:    Input Parameter:
    3525: +  x - the vector
    3526: .  m - first dimension of two dimensional array
    3527: -  mstart - first index you will use in first coordinate direction (often 0)

    3529:    Output Parameter:
    3530: .  a - location to put pointer to the array

    3532:    Level: developer

    3534:   Notes:
    3535:    For a vector obtained from DMCreateLocalVector() mstart are likely
    3536:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
    3537:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().

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

    3541: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    3542:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    3543:           VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    3544: @*/
    3545: PetscErrorCode  VecGetArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
    3546: {
    3548:   PetscInt       N;

    3554:   VecGetLocalSize(x,&N);
    3555:   if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
    3556:   VecGetArrayRead(x,(const PetscScalar**)a);
    3557:   *a  -= mstart;
    3558:   return(0);
    3559: }

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

    3564:    Logically Collective

    3566:    Input Parameters:
    3567: +  x - the vector
    3568: .  m - first dimension of two dimensional array
    3569: .  mstart - first index you will use in first coordinate direction (often 0)
    3570: -  a - location of pointer to array obtained from VecGetArray21()

    3572:    Level: developer

    3574:    Notes:
    3575:    For regular PETSc vectors this routine does not involve any copies. For
    3576:    any special vectors that do not store local vector data in a contiguous
    3577:    array, this routine will copy the data back into the underlying
    3578:    vector data structure from the array obtained with VecGetArray1dRead().

    3580:    This routine actually zeros out the a pointer.

    3582: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    3583:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    3584:           VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
    3585: @*/
    3586: PetscErrorCode  VecRestoreArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
    3587: {

    3593:   VecRestoreArrayRead(x,NULL);
    3594:   return(0);
    3595: }

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

    3603:    Logically Collective

    3605:    Input Parameter:
    3606: +  x - the vector
    3607: .  m - first dimension of three dimensional array
    3608: .  n - second dimension of three dimensional array
    3609: .  p - third dimension of three dimensional array
    3610: .  mstart - first index you will use in first coordinate direction (often 0)
    3611: .  nstart - first index in the second coordinate direction (often 0)
    3612: -  pstart - first index in the third coordinate direction (often 0)

    3614:    Output Parameter:
    3615: .  a - location to put pointer to the array

    3617:    Level: developer

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

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

    3627: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    3628:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    3629:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    3630: @*/
    3631: PetscErrorCode  VecGetArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
    3632: {
    3633:   PetscErrorCode    ierr;
    3634:   PetscInt          i,N,j;
    3635:   const PetscScalar *aa;
    3636:   PetscScalar       **b;

    3642:   VecGetLocalSize(x,&N);
    3643:   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);
    3644:   VecGetArrayRead(x,&aa);

    3646:   PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
    3647:   b    = (PetscScalar**)((*a) + m);
    3648:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
    3649:   for (i=0; i<m; i++)
    3650:     for (j=0; j<n; j++)
    3651:       b[i*n+j] = (PetscScalar *)aa + i*n*p + j*p - pstart;

    3653:   *a -= mstart;
    3654:   return(0);
    3655: }

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

    3660:    Logically Collective

    3662:    Input Parameters:
    3663: +  x - the vector
    3664: .  m - first dimension of three dimensional array
    3665: .  n - second dimension of the three dimensional array
    3666: .  p - third dimension of the three dimensional array
    3667: .  mstart - first index you will use in first coordinate direction (often 0)
    3668: .  nstart - first index in the second coordinate direction (often 0)
    3669: .  pstart - first index in the third coordinate direction (often 0)
    3670: -  a - location of pointer to array obtained from VecGetArray3dRead()

    3672:    Level: developer

    3674:    Notes:
    3675:    For regular PETSc vectors this routine does not involve any copies. For
    3676:    any special vectors that do not store local vector data in a contiguous
    3677:    array, this routine will copy the data back into the underlying
    3678:    vector data structure from the array obtained with VecGetArray().

    3680:    This routine actually zeros out the a pointer.

    3682: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    3683:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    3684:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
    3685: @*/
    3686: PetscErrorCode  VecRestoreArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
    3687: {
    3689:   void           *dummy;

    3695:   dummy = (void*)(*a + mstart);
    3696:   PetscFree(dummy);
    3697:   VecRestoreArrayRead(x,NULL);
    3698:   return(0);
    3699: }

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

    3706:    Logically Collective

    3708:    Input Parameter:
    3709: +  x - the vector
    3710: .  m - first dimension of four dimensional array
    3711: .  n - second dimension of four dimensional array
    3712: .  p - third dimension of four dimensional array
    3713: .  q - fourth dimension of four dimensional array
    3714: .  mstart - first index you will use in first coordinate direction (often 0)
    3715: .  nstart - first index in the second coordinate direction (often 0)
    3716: .  pstart - first index in the third coordinate direction (often 0)
    3717: -  qstart - first index in the fourth coordinate direction (often 0)

    3719:    Output Parameter:
    3720: .  a - location to put pointer to the array

    3722:    Level: beginner

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

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

    3732: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    3733:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    3734:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    3735: @*/
    3736: PetscErrorCode  VecGetArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
    3737: {
    3738:   PetscErrorCode    ierr;
    3739:   PetscInt          i,N,j,k;
    3740:   const PetscScalar *aa;
    3741:   PetscScalar       ***b,**c;

    3747:   VecGetLocalSize(x,&N);
    3748:   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);
    3749:   VecGetArrayRead(x,&aa);

    3751:   PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
    3752:   b    = (PetscScalar***)((*a) + m);
    3753:   c    = (PetscScalar**)(b + m*n);
    3754:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
    3755:   for (i=0; i<m; i++)
    3756:     for (j=0; j<n; j++)
    3757:       b[i*n+j] = c + i*n*p + j*p - pstart;
    3758:   for (i=0; i<m; i++)
    3759:     for (j=0; j<n; j++)
    3760:       for (k=0; k<p; k++)
    3761:         c[i*n*p+j*p+k] = (PetscScalar*) aa + i*n*p*q + j*p*q + k*q - qstart;
    3762:   *a -= mstart;
    3763:   return(0);
    3764: }

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

    3769:    Logically Collective

    3771:    Input Parameters:
    3772: +  x - the vector
    3773: .  m - first dimension of four dimensional array
    3774: .  n - second dimension of the four dimensional array
    3775: .  p - third dimension of the four dimensional array
    3776: .  q - fourth dimension of the four dimensional array
    3777: .  mstart - first index you will use in first coordinate direction (often 0)
    3778: .  nstart - first index in the second coordinate direction (often 0)
    3779: .  pstart - first index in the third coordinate direction (often 0)
    3780: .  qstart - first index in the fourth coordinate direction (often 0)
    3781: -  a - location of pointer to array obtained from VecGetArray4dRead()

    3783:    Level: beginner

    3785:    Notes:
    3786:    For regular PETSc vectors this routine does not involve any copies. For
    3787:    any special vectors that do not store local vector data in a contiguous
    3788:    array, this routine will copy the data back into the underlying
    3789:    vector data structure from the array obtained with VecGetArray().

    3791:    This routine actually zeros out the a pointer.

    3793: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    3794:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    3795:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
    3796: @*/
    3797: PetscErrorCode  VecRestoreArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
    3798: {
    3800:   void           *dummy;

    3806:   dummy = (void*)(*a + mstart);
    3807:   PetscFree(dummy);
    3808:   VecRestoreArrayRead(x,NULL);
    3809:   return(0);
    3810: }

    3812: #if defined(PETSC_USE_DEBUG)

    3814: /*@
    3815:    VecLockGet  - Gets the current lock status of a vector

    3817:    Logically Collective on Vec

    3819:    Input Parameter:
    3820: .  x - the vector

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

    3826:    Level: beginner

    3828: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockReadPop()
    3829: @*/
    3830: PetscErrorCode VecLockGet(Vec x,PetscInt *state)
    3831: {
    3834:   *state = x->lock;
    3835:   return(0);
    3836: }

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

    3841:    Logically Collective on Vec

    3843:    Input Parameter:
    3844: .  x - the vector

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

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

    3852:    Level: beginner

    3854: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPop(), VecLockGet()
    3855: @*/
    3856: PetscErrorCode VecLockReadPush(Vec x)
    3857: {
    3860:   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");
    3861:   x->lock++;
    3862:   return(0);
    3863: }

    3865: /*@
    3866:    VecLockReadPop  - Pops a read-only lock from a vector

    3868:    Logically Collective on Vec

    3870:    Input Parameter:
    3871: .  x - the vector

    3873:    Level: beginner

    3875: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockGet()
    3876: @*/
    3877: PetscErrorCode VecLockReadPop(Vec x)
    3878: {
    3881:   x->lock--;
    3882:   if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector has been unlocked from read-only access too many times");
    3883:   return(0);
    3884: }

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

    3889:    Logically Collective on Vec

    3891:    Input Parameter:
    3892: +  x   - the vector
    3893: -  flg - PETSC_TRUE to lock the vector for writing; PETSC_FALSE to unlock it.

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

    3902:        VecGetArray(x,&xdata); // begin phase
    3903:        VecLockWriteSet_Private(v,PETSC_TRUE);

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

    3907:        VecRestoreArray(x,&vdata); // end phase
    3908:        VecLockWriteSet_Private(v,PETSC_FALSE);

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

    3913:    Level: beginner

    3915: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockReadPop(), VecLockGet()
    3916: @*/
    3917: PetscErrorCode VecLockWriteSet_Private(Vec x,PetscBool flg)
    3918: {
    3921:   if (flg) {
    3922:     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");
    3923:     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");
    3924:     else x->lock = -1;
    3925:   } else {
    3926:     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");
    3927:     x->lock = 0;
    3928:   }
    3929:   return(0);
    3930: }

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

    3935:    Level: deprecated

    3937: .seealso: VecLockReadPush()
    3938: @*/
    3939: PetscErrorCode VecLockPush(Vec x)
    3940: {
    3943:   VecLockReadPush(x);
    3944:   return(0);
    3945: }

    3947: /*@
    3948:    VecLockPop  - Pops a read-only lock from a vector

    3950:    Level: deprecated

    3952: .seealso: VecLockReadPop()
    3953: @*/
    3954: PetscErrorCode VecLockPop(Vec x)
    3955: {
    3958:   VecLockReadPop(x);
    3959:   return(0);
    3960: }

    3962: #endif