Actual source code: rvector.c
petsc-3.10.5 2019-03-28
Report Typos and Errors

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

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

     17: #if defined(PETSC_HAVE_VECCUDA) || defined(PETSC_HAVE_VIENNACL)
     18:   if ((vec->petscnative || vec->ops->getarray) && (vec->valid_GPU_array == PETSC_OFFLOAD_CPU || vec->valid_GPU_array == PETSC_OFFLOAD_BOTH)) {
     19: #else
     20:   if (vec->petscnative || vec->ops->getarray) {
     21: #endif
     22:     VecGetLocalSize(vec,&n);
     23:     VecGetArrayRead(vec,&x);
     24:     for (i=0; i<n; i++) {
     25:       if (begin) {
     26:         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);
     27:       } else {
     28:         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);
     29:       }
     30:     }
     31:     VecRestoreArrayRead(vec,&x);
     32:   }
     33:   return(0);
     34: #else
     35:   return 0;
     36: #endif
     37: }

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

     42:    Logically Collective on Vec

     44:    Input Parameters:
     45: .  x, y  - the vectors

     47:    Output Parameter:
     48: .  max - the result

     50:    Level: advanced

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

     56: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs()
     57: @*/
     58: PetscErrorCode  VecMaxPointwiseDivide(Vec x,Vec y,PetscReal *max)
     59: {

     69:   VecCheckSameSize(x,1,y,2);
     70:   (*x->ops->maxpointwisedivide)(x,y,max);
     71:   return(0);
     72: }

     74: /*@
     75:    VecDot - Computes the vector dot product.

     77:    Collective on Vec

     79:    Input Parameters:
     80: .  x, y - the vectors

     82:    Output Parameter:
     83: .  val - the dot product

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

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

     97:    Use VecTDot() for the indefinite form
     98: $     val = (x,y) = y^T x,
     99:    where y^T denotes the transpose of y.

    101:    Level: intermediate

    103:    Concepts: inner product
    104:    Concepts: vector^inner product

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

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

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

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

    130:    Collective on Vec

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

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

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

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

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

    148:      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
    149:      the space R^{2n} (that is a vector of 2n components with the real or imaginary part of the complex numbers for components)

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

    153:    Level: intermediate

    155:    Concepts: inner product
    156:    Concepts: vector^inner product

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

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

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

    174:    Collective on Vec

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

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

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

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

    195:    Level: intermediate

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

    202:    Concepts: norm
    203:    Concepts: vector^norm

    205: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNormAvailable(),
    206:           VecNormBegin(), VecNormEnd()

    208: @*/
    209: PetscErrorCode  VecNorm(Vec x,NormType type,PetscReal *val)
    210: {
    211:   PetscBool      flg;

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

    230:   if (type!=NORM_1_AND_2) {
    231:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[type],*val);
    232:   }
    233:   return(0);
    234: }

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

    239:    Not Collective

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

    247:    Output Parameter:
    248: +  available - PETSC_TRUE if the val returned is valid
    249: -  val - the norm

    251:    Notes:
    252: $     NORM_1 denotes sum_i |x_i|
    253: $     NORM_2 denotes sqrt(sum_i (x_i)^2)
    254: $     NORM_INFINITY denotes max_i |x_i|

    256:    Level: intermediate

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

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

    268:    Concepts: norm
    269:    Concepts: vector^norm

    271: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNorm()
    272:           VecNormBegin(), VecNormEnd()

    274: @*/
    275: PetscErrorCode  VecNormAvailable(Vec x,NormType type,PetscBool  *available,PetscReal *val)
    276: {

    284:   *available = PETSC_FALSE;
    285:   if (type!=NORM_1_AND_2) {
    286:     PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,*available);
    287:   }
    288:   return(0);
    289: }

    291: /*@
    292:    VecNormalize - Normalizes a vector by 2-norm.

    294:    Collective on Vec

    296:    Input Parameters:
    297: +  x - the vector

    299:    Output Parameter:
    300: .  x - the normalized vector
    301: -  val - the vector norm before normalization

    303:    Level: intermediate

    305:    Concepts: vector^normalizing
    306:    Concepts: normalizing^vector

    308: @*/
    309: PetscErrorCode  VecNormalize(Vec x,PetscReal *val)
    310: {
    312:   PetscReal      norm;

    317:   PetscLogEventBegin(VEC_Normalize,x,0,0,0);
    318:   VecNorm(x,NORM_2,&norm);
    319:   if (norm == 0.0) {
    320:     PetscInfo(x,"Vector of zero norm can not be normalized; Returning only the zero norm\n");
    321:   } else if (norm != 1.0) {
    322:     PetscScalar tmp = 1.0/norm;
    323:     VecScale(x,tmp);
    324:   }
    325:   if (val) *val = norm;
    326:   PetscLogEventEnd(VEC_Normalize,x,0,0,0);
    327:   return(0);
    328: }

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

    333:    Collective on Vec

    335:    Input Parameter:
    336: .  x - the vector

    338:    Output Parameters:
    339: +  p - the location of val (pass NULL if you don't want this)
    340: -  val - the maximum component

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

    345:    Returns the smallest index with the maximum value
    346:    Level: intermediate

    348:    Concepts: maximum^of vector
    349:    Concepts: vector^maximum value

    351: .seealso: VecNorm(), VecMin()
    352: @*/
    353: PetscErrorCode  VecMax(Vec x,PetscInt *p,PetscReal *val)
    354: {

    361:   PetscLogEventBegin(VEC_Max,x,0,0,0);
    362:   (*x->ops->max)(x,p,val);
    363:   PetscLogEventEnd(VEC_Max,x,0,0,0);
    364:   return(0);
    365: }

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

    370:    Collective on Vec

    372:    Input Parameters:
    373: .  x - the vector

    375:    Output Parameter:
    376: +  p - the location of val (pass NULL if you don't want this location)
    377: -  val - the minimum component

    379:    Level: intermediate

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

    384:    This returns the smallest index with the minumum value

    386:    Concepts: minimum^of vector
    387:    Concepts: vector^minimum entry

    389: .seealso: VecMax()
    390: @*/
    391: PetscErrorCode  VecMin(Vec x,PetscInt *p,PetscReal *val)
    392: {

    399:   PetscLogEventBegin(VEC_Min,x,0,0,0);
    400:   (*x->ops->min)(x,p,val);
    401:   PetscLogEventEnd(VEC_Min,x,0,0,0);
    402:   return(0);
    403: }

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

    409:    Collective on Vec

    411:    Input Parameters:
    412: .  x, y - the vectors

    414:    Output Parameter:
    415: .  val - the dot product

    417:    Notes for Users of Complex Numbers:
    418:    For complex vectors, VecTDot() computes the indefinite form
    419: $     val = (x,y) = y^T x,
    420:    where y^T denotes the transpose of y.

    422:    Use VecDot() for the inner product
    423: $     val = (x,y) = y^H x,
    424:    where y^H denotes the conjugate transpose of y.

    426:    Level: intermediate

    428:    Concepts: inner product^non-Hermitian
    429:    Concepts: vector^inner product
    430:    Concepts: non-Hermitian inner product

    432: .seealso: VecDot(), VecMTDot()
    433: @*/
    434: PetscErrorCode  VecTDot(Vec x,Vec y,PetscScalar *val)
    435: {

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

    447:   PetscLogEventBegin(VEC_TDot,x,y,0,0);
    448:   (*x->ops->tdot)(x,y,val);
    449:   PetscLogEventEnd(VEC_TDot,x,y,0,0);
    450:   return(0);
    451: }

    453: /*@
    454:    VecScale - Scales a vector.

    456:    Not collective on Vec

    458:    Input Parameters:
    459: +  x - the vector
    460: -  alpha - the scalar

    462:    Output Parameter:
    463: .  x - the scaled vector

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

    469:    Level: intermediate

    471:    Concepts: vector^scaling
    472:    Concepts: scaling^vector

    474: @*/
    475: PetscErrorCode  VecScale(Vec x, PetscScalar alpha)
    476: {
    477:   PetscReal      norms[4] = {0.0,0.0,0.0, 0.0};
    478:   PetscBool      flgs[4];
    480:   PetscInt       i;

    485:   if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
    486:   PetscLogEventBegin(VEC_Scale,x,0,0,0);
    487:   if (alpha != (PetscScalar)1.0) {
    488:     /* get current stashed norms */
    489:     for (i=0; i<4; i++) {
    490:       PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],norms[i],flgs[i]);
    491:     }
    492:     (*x->ops->scale)(x,alpha);
    493:     PetscObjectStateIncrease((PetscObject)x);
    494:     /* put the scaled stashed norms back into the Vec */
    495:     for (i=0; i<4; i++) {
    496:       if (flgs[i]) {
    497:         PetscObjectComposedDataSetReal((PetscObject)x,NormIds[i],PetscAbsScalar(alpha)*norms[i]);
    498:       }
    499:     }
    500:   }
    501:   PetscLogEventEnd(VEC_Scale,x,0,0,0);
    502:   return(0);
    503: }

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

    508:    Logically Collective on Vec

    510:    Input Parameters:
    511: +  x  - the vector
    512: -  alpha - the scalar

    514:    Output Parameter:
    515: .  x  - the vector

    517:    Note:
    518:    For a vector of dimension n, VecSet() computes
    519: $     x[i] = alpha, for i=1,...,n,
    520:    so that all vector entries then equal the identical
    521:    scalar value, alpha.  Use the more general routine
    522:    VecSetValues() to set different vector entries.

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

    527:    Level: beginner

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

    531:    Concepts: vector^setting to constant

    533: @*/
    534: PetscErrorCode  VecSet(Vec x,PetscScalar alpha)
    535: {
    536:   PetscReal      val;

    542:   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()");
    544:   VecLocked(x,1);

    546:   PetscLogEventBegin(VEC_Set,x,0,0,0);
    547:   (*x->ops->set)(x,alpha);
    548:   PetscLogEventEnd(VEC_Set,x,0,0,0);
    549:   PetscObjectStateIncrease((PetscObject)x);

    551:   /*  norms can be simply set (if |alpha|*N not too large) */
    552:   val  = PetscAbsScalar(alpha);
    553:   if (x->map->N == 0) {
    554:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],0.0l);
    555:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],0.0);
    556:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],0.0);
    557:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],0.0);
    558:   } else if (val > PETSC_MAX_REAL/x->map->N) {
    559:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
    560:   } else {
    561:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],x->map->N * val);
    562:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
    563:     val  = PetscSqrtReal((PetscReal)x->map->N) * val;
    564:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],val);
    565:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],val);
    566:   }
    567:   return(0);
    568: }

    571: /*@
    572:    VecAXPY - Computes y = alpha x + y.

    574:    Logically Collective on Vec

    576:    Input Parameters:
    577: +  alpha - the scalar
    578: -  x, y  - the vectors

    580:    Output Parameter:
    581: .  y - output vector

    583:    Level: intermediate

    585:    Notes:
    586:     x and y MUST be different vectors

    588:    Concepts: vector^BLAS
    589:    Concepts: BLAS

    591: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY()
    592: @*/
    593: PetscErrorCode  VecAXPY(Vec y,PetscScalar alpha,Vec x)
    594: {

    603:   VecCheckSameSize(x,1,y,3);
    604:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
    606:   VecLocked(y,1);

    608:   VecLockPush(x);
    609:   PetscLogEventBegin(VEC_AXPY,x,y,0,0);
    610:   (*y->ops->axpy)(y,alpha,x);
    611:   PetscLogEventEnd(VEC_AXPY,x,y,0,0);
    612:   VecLockPop(x);
    613:   PetscObjectStateIncrease((PetscObject)y);
    614:   return(0);
    615: }

    617: /*@
    618:    VecAXPBY - Computes y = alpha x + beta y.

    620:    Logically Collective on Vec

    622:    Input Parameters:
    623: +  alpha,beta - the scalars
    624: -  x, y  - the vectors

    626:    Output Parameter:
    627: .  y - output vector

    629:    Level: intermediate

    631:    Notes:
    632:     x and y MUST be different vectors

    634:    Concepts: BLAS
    635:    Concepts: vector^BLAS

    637: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY()
    638: @*/
    639: PetscErrorCode  VecAXPBY(Vec y,PetscScalar alpha,PetscScalar beta,Vec x)
    640: {

    649:   VecCheckSameSize(x,1,y,4);
    650:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");

    654:   PetscLogEventBegin(VEC_AXPY,x,y,0,0);
    655:   (*y->ops->axpby)(y,alpha,beta,x);
    656:   PetscLogEventEnd(VEC_AXPY,x,y,0,0);
    657:   PetscObjectStateIncrease((PetscObject)y);
    658:   return(0);
    659: }

    661: /*@
    662:    VecAXPBYPCZ - Computes z = alpha x + beta y + gamma z

    664:    Logically Collective on Vec

    666:    Input Parameters:
    667: +  alpha,beta, gamma - the scalars
    668: -  x, y, z  - the vectors

    670:    Output Parameter:
    671: .  z - output vector

    673:    Level: intermediate

    675:    Notes:
    676:     x, y and z must be different vectors

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

    680:    Concepts: BLAS
    681:    Concepts: vector^BLAS

    683: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY()
    684: @*/
    685: PetscErrorCode  VecAXPBYPCZ(Vec z,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec x,Vec y)
    686: {

    698:   VecCheckSameSize(x,1,y,5);
    699:   VecCheckSameSize(x,1,z,6);
    700:   if (x == y || x == z) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
    701:   if (y == z) SETERRQ(PetscObjectComm((PetscObject)y),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");

    706:   PetscLogEventBegin(VEC_AXPBYPCZ,x,y,z,0);
    707:   (*y->ops->axpbypcz)(z,alpha,beta,gamma,x,y);
    708:   PetscLogEventEnd(VEC_AXPBYPCZ,x,y,z,0);
    709:   PetscObjectStateIncrease((PetscObject)z);
    710:   return(0);
    711: }

    713: /*@
    714:    VecAYPX - Computes y = x + alpha y.

    716:    Logically Collective on Vec

    718:    Input Parameters:
    719: +  alpha - the scalar
    720: -  x, y  - the vectors

    722:    Output Parameter:
    723: .  y - output vector

    725:    Level: intermediate

    727:    Notes:
    728:     x and y MUST be different vectors

    730:    Concepts: vector^BLAS
    731:    Concepts: BLAS

    733: .seealso: VecAXPY(), VecWAXPY()
    734: @*/
    735: PetscErrorCode  VecAYPX(Vec y,PetscScalar alpha,Vec x)
    736: {

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

    749:   PetscLogEventBegin(VEC_AYPX,x,y,0,0);
    750:    (*y->ops->aypx)(y,alpha,x);
    751:   PetscLogEventEnd(VEC_AYPX,x,y,0,0);
    752:   PetscObjectStateIncrease((PetscObject)y);
    753:   return(0);
    754: }

    757: /*@
    758:    VecWAXPY - Computes w = alpha x + y.

    760:    Logically Collective on Vec

    762:    Input Parameters:
    763: +  alpha - the scalar
    764: -  x, y  - the vectors

    766:    Output Parameter:
    767: .  w - the result

    769:    Level: intermediate

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

    774:    Concepts: vector^BLAS
    775:    Concepts: BLAS

    777: .seealso: VecAXPY(), VecAYPX(), VecAXPBY()
    778: @*/
    779: PetscErrorCode  VecWAXPY(Vec w,PetscScalar alpha,Vec x,Vec y)
    780: {

    792:   VecCheckSameSize(x,3,y,4);
    793:   VecCheckSameSize(x,3,w,1);
    794:   if (w == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector y, suggest VecAXPY()");
    795:   if (w == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector x, suggest VecAYPX()");

    798:   PetscLogEventBegin(VEC_WAXPY,x,y,w,0);
    799:    (*w->ops->waxpy)(w,alpha,x,y);
    800:   PetscLogEventEnd(VEC_WAXPY,x,y,w,0);
    801:   PetscObjectStateIncrease((PetscObject)w);
    802:   return(0);
    803: }

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

    809:    Not Collective

    811:    Input Parameters:
    812: +  x - vector to insert in
    813: .  ni - number of elements to add
    814: .  ix - indices where to add
    815: .  y - array of values
    816: -  iora - either INSERT_VALUES or ADD_VALUES, where
    817:    ADD_VALUES adds values to any existing entries, and
    818:    INSERT_VALUES replaces existing entries with new values

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

    823:    Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
    824:    options cannot be mixed without intervening calls to the assembly
    825:    routines.

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

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

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

    838:    Level: beginner

    840:    Concepts: vector^setting values

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

    851:   if (!ni) return(0);
    855:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
    856:   (*x->ops->setvalues)(x,ni,ix,y,iora);
    857:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
    858:   PetscObjectStateIncrease((PetscObject)x);
    859:   return(0);
    860: }

    862: /*@
    863:    VecGetValues - Gets values from certain locations of a vector. Currently
    864:           can only get values on the same processor

    866:     Not Collective

    868:    Input Parameters:
    869: +  x - vector to get values from
    870: .  ni - number of elements to get
    871: -  ix - indices where to get them from (in global 1d numbering)

    873:    Output Parameter:
    874: .   y - array of values

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

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

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

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

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

    889:    Level: beginner

    891:    Concepts: vector^getting values

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

    901:   if (!ni) return(0);
    905:   (*x->ops->getvalues)(x,ni,ix,y);
    906:   return(0);
    907: }

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

    912:    Not Collective

    914:    Input Parameters:
    915: +  x - vector to insert in
    916: .  ni - number of blocks to add
    917: .  ix - indices where to add in block count, rather than element count
    918: .  y - array of values
    919: -  iora - either INSERT_VALUES or ADD_VALUES, where
    920:    ADD_VALUES adds values to any existing entries, and
    921:    INSERT_VALUES replaces existing entries with new values

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

    927:    Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
    928:    options cannot be mixed without intervening calls to the assembly
    929:    routines.

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

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

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

    941:    Level: intermediate

    943:    Concepts: vector^setting values blocked

    945: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesBlockedLocal(),
    946:            VecSetValues()
    947: @*/
    948: PetscErrorCode  VecSetValuesBlocked(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
    949: {

    957:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
    958:   (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);
    959:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
    960:   PetscObjectStateIncrease((PetscObject)x);
    961:   return(0);
    962: }

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

    969:    Not Collective

    971:    Input Parameters:
    972: +  x - vector to insert in
    973: .  ni - number of elements to add
    974: .  ix - indices where to add
    975: .  y - array of values
    976: -  iora - either INSERT_VALUES or ADD_VALUES, where
    977:    ADD_VALUES adds values to any existing entries, and
    978:    INSERT_VALUES replaces existing entries with new values

    980:    Level: intermediate

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

    985:    Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
    986:    options cannot be mixed without intervening calls to the assembly
    987:    routines.

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

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

    994:    Concepts: vector^setting values with local numbering

    996: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetLocalToGlobalMapping(),
    997:            VecSetValuesBlockedLocal()
    998: @*/
    999: PetscErrorCode  VecSetValuesLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
    1000: {
    1002:   PetscInt       lixp[128],*lix = lixp;

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

    1011:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
    1012:   if (!x->ops->setvalueslocal) {
    1013:     if (!x->map->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMapping()");
    1014:     if (ni > 128) {
    1015:       PetscMalloc1(ni,&lix);
    1016:     }
    1017:     ISLocalToGlobalMappingApply(x->map->mapping,ni,(PetscInt*)ix,lix);
    1018:     (*x->ops->setvalues)(x,ni,lix,y,iora);
    1019:     if (ni > 128) {
    1020:       PetscFree(lix);
    1021:     }
    1022:   } else {
    1023:     (*x->ops->setvalueslocal)(x,ni,ix,y,iora);
    1024:   }
    1025:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
    1026:   PetscObjectStateIncrease((PetscObject)x);
    1027:   return(0);
    1028: }

    1030: /*@
    1031:    VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
    1032:    using a local ordering of the nodes.

    1034:    Not Collective

    1036:    Input Parameters:
    1037: +  x - vector to insert in
    1038: .  ni - number of blocks to add
    1039: .  ix - indices where to add in block count, not element count
    1040: .  y - array of values
    1041: -  iora - either INSERT_VALUES or ADD_VALUES, where
    1042:    ADD_VALUES adds values to any existing entries, and
    1043:    INSERT_VALUES replaces existing entries with new values

    1045:    Level: intermediate

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

    1051:    Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
    1052:    options cannot be mixed without intervening calls to the assembly
    1053:    routines.

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

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

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

    1063: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesBlocked(),
    1064:            VecSetLocalToGlobalMapping()
    1065: @*/
    1066: PetscErrorCode  VecSetValuesBlockedLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
    1067: {
    1069:   PetscInt       lixp[128],*lix = lixp;

    1076:   if (ni > 128) {
    1077:     PetscMalloc1(ni,&lix);
    1078:   }

    1080:   PetscLogEventBegin(VEC_SetValues,x,0,0,0);
    1081:   ISLocalToGlobalMappingApplyBlock(x->map->mapping,ni,(PetscInt*)ix,lix);
    1082:   (*x->ops->setvaluesblocked)(x,ni,lix,y,iora);
    1083:   PetscLogEventEnd(VEC_SetValues,x,0,0,0);
    1084:   if (ni > 128) {
    1085:     PetscFree(lix);
    1086:   }
    1087:   PetscObjectStateIncrease((PetscObject)x);
    1088:   return(0);
    1089: }

    1091: /*@
    1092:    VecMTDot - Computes indefinite vector multiple dot products.
    1093:    That is, it does NOT use the complex conjugate.

    1095:    Collective on Vec

    1097:    Input Parameters:
    1098: +  x - one vector
    1099: .  nv - number of vectors
    1100: -  y - array of vectors.  Note that vectors are pointers

    1102:    Output Parameter:
    1103: .  val - array of the dot products

    1105:    Notes for Users of Complex Numbers:
    1106:    For complex vectors, VecMTDot() computes the indefinite form
    1107: $      val = (x,y) = y^T x,
    1108:    where y^T denotes the transpose of y.

    1110:    Use VecMDot() for the inner product
    1111: $      val = (x,y) = y^H x,
    1112:    where y^H denotes the conjugate transpose of y.

    1114:    Level: intermediate

    1116:    Concepts: inner product^multiple
    1117:    Concepts: vector^multiple inner products

    1119: .seealso: VecMDot(), VecTDot()
    1120: @*/
    1121: PetscErrorCode  VecMTDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
    1122: {

    1133:   VecCheckSameSize(x,1,*y,3);

    1135:   PetscLogEventBegin(VEC_MTDot,x,*y,0,0);
    1136:   (*x->ops->mtdot)(x,nv,y,val);
    1137:   PetscLogEventEnd(VEC_MTDot,x,*y,0,0);
    1138:   return(0);
    1139: }

    1141: /*@
    1142:    VecMDot - Computes vector multiple dot products.

    1144:    Collective on Vec

    1146:    Input Parameters:
    1147: +  x - one vector
    1148: .  nv - number of vectors
    1149: -  y - array of vectors.

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

    1154:    Notes for Users of Complex Numbers:
    1155:    For complex vectors, VecMDot() computes
    1156: $     val = (x,y) = y^H x,
    1157:    where y^H denotes the conjugate transpose of y.

    1159:    Use VecMTDot() for the indefinite form
    1160: $     val = (x,y) = y^T x,
    1161:    where y^T denotes the transpose of y.

    1163:    Level: intermediate

    1165:    Concepts: inner product^multiple
    1166:    Concepts: vector^multiple inner products

    1168: .seealso: VecMTDot(), VecDot()
    1169: @*/
    1170: PetscErrorCode  VecMDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
    1171: {

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

    1186:   PetscLogEventBegin(VEC_MDot,x,*y,0,0);
    1187:   (*x->ops->mdot)(x,nv,y,val);
    1188:   PetscLogEventEnd(VEC_MDot,x,*y,0,0);
    1189:   return(0);
    1190: }

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

    1195:    Logically Collective on Vec

    1197:    Input Parameters:
    1198: +  nv - number of scalars and x-vectors
    1199: .  alpha - array of scalars
    1200: .  y - one vector
    1201: -  x - array of vectors

    1203:    Level: intermediate

    1205:    Notes:
    1206:     y cannot be any of the x vectors

    1208:    Concepts: BLAS

    1210: .seealso: VecAXPY(), VecWAXPY(), VecAYPX()
    1211: @*/
    1212: PetscErrorCode  VecMAXPY(Vec y,PetscInt nv,const PetscScalar alpha[],Vec x[])
    1213: {
    1215:   PetscInt       i;

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

    1230:   PetscLogEventBegin(VEC_MAXPY,*x,y,0,0);
    1231:   (*y->ops->maxpy)(y,nv,alpha,x);
    1232:   PetscLogEventEnd(VEC_MAXPY,*x,y,0,0);
    1233:   PetscObjectStateIncrease((PetscObject)y);
    1234:   return(0);
    1235: }

    1237: /*@
    1238:    VecGetSubVector - Gets a vector representing part of another vector

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

    1242:    Input Arguments:
    1243: + X - vector from which to extract a subvector
    1244: - is - index set representing portion of X to extract

    1246:    Output Arguments:
    1247: . Y - subvector corresponding to is

    1249:    Level: advanced

    1251:    Notes:
    1252:    The subvector Y should be returned with VecRestoreSubVector().

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

    1257: .seealso: MatCreateSubMatrix()
    1258: @*/
    1259: PetscErrorCode  VecGetSubVector(Vec X,IS is,Vec *Y)
    1260: {
    1261:   PetscErrorCode   ierr;
    1262:   Vec              Z;

    1268:   if (X->ops->getsubvector) {
    1269:     (*X->ops->getsubvector)(X,is,&Z);
    1270:   } else { /* Default implementation currently does no caching */
    1271:     PetscInt  gstart,gend,start;
    1272:     PetscBool contiguous,gcontiguous;
    1273:     VecGetOwnershipRange(X,&gstart,&gend);
    1274:     ISContiguousLocal(is,gstart,gend,&start,&contiguous);
    1275:     MPIU_Allreduce(&contiguous,&gcontiguous,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));
    1276:     if (gcontiguous) { /* We can do a no-copy implementation */
    1277:       PetscInt n,N,bs;
    1278:       PetscInt state;

    1280:       ISGetSize(is,&N);
    1281:       ISGetLocalSize(is,&n);
    1282:       VecGetBlockSize(X,&bs);
    1283:       if (n%bs || bs == 1 || !n) bs = -1; /* Do not decide block size if we do not have to */
    1284:       VecLockGet(X,&state);
    1285:       if (state) {
    1286:         const PetscScalar *x;
    1287:         VecGetArrayRead(X,&x);
    1288:         VecCreate(PetscObjectComm((PetscObject)X),&Z);
    1289:         VecSetType(Z,((PetscObject)X)->type_name);
    1290:         VecSetSizes(Z,n,N);
    1291:         VecSetBlockSize(Z,bs);
    1292:         VecPlaceArray(Z,(PetscScalar*)x+start);
    1293:         VecLockPush(Z);
    1294:         VecRestoreArrayRead(X,&x);
    1295:       } else {
    1296:         PetscScalar *x;
    1297:         VecGetArray(X,&x);
    1298:         VecCreate(PetscObjectComm((PetscObject)X),&Z);
    1299:         VecSetType(Z,((PetscObject)X)->type_name);
    1300:         VecSetSizes(Z,n,N);
    1301:         VecSetBlockSize(Z,bs);
    1302:         VecPlaceArray(Z,(PetscScalar*)x+start);
    1303:         VecRestoreArray(X,&x);
    1304:       }
    1305:     } else { /* Have to create a scatter and do a copy */
    1306:       VecScatter scatter;
    1307:       PetscInt   n,N;
    1308:       ISGetLocalSize(is,&n);
    1309:       ISGetSize(is,&N);
    1310:       VecCreate(PetscObjectComm((PetscObject)is),&Z);
    1311:       VecSetSizes(Z,n,N);
    1312:       VecSetType(Z,((PetscObject)X)->type_name);
    1313:       VecScatterCreate(X,is,Z,NULL,&scatter);
    1314:       VecScatterBegin(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
    1315:       VecScatterEnd(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
    1316:       PetscObjectCompose((PetscObject)Z,"VecGetSubVector_Scatter",(PetscObject)scatter);
    1317:       VecScatterDestroy(&scatter);
    1318:     }
    1319:   }
    1320:   /* Record the state when the subvector was gotten so we know whether its values need to be put back */
    1321:   if (VecGetSubVectorSavedStateId < 0) {PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId);}
    1322:   PetscObjectComposedDataSetInt((PetscObject)Z,VecGetSubVectorSavedStateId,1);
    1323:   *Y   = Z;
    1324:   return(0);
    1325: }

    1327: /*@
    1328:    VecRestoreSubVector - Restores a subvector extracted using VecGetSubVector()

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

    1332:    Input Arguments:
    1333: + X - vector from which subvector was obtained
    1334: . is - index set representing the subset of X
    1335: - Y - subvector being restored

    1337:    Level: advanced

    1339: .seealso: VecGetSubVector()
    1340: @*/
    1341: PetscErrorCode  VecRestoreSubVector(Vec X,IS is,Vec *Y)
    1342: {

    1350:   if (X->ops->restoresubvector) {
    1351:     (*X->ops->restoresubvector)(X,is,Y);
    1352:   } else {
    1353:     PETSC_UNUSED PetscObjectState dummystate = 0;
    1354:     PetscBool valid;
    1355:     PetscObjectComposedDataGetInt((PetscObject)*Y,VecGetSubVectorSavedStateId,dummystate,valid);
    1356:     if (!valid) {
    1357:       VecScatter scatter;

    1359:       PetscObjectQuery((PetscObject)*Y,"VecGetSubVector_Scatter",(PetscObject*)&scatter);
    1360:       if (scatter) {
    1361:         VecScatterBegin(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);
    1362:         VecScatterEnd(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);
    1363:       }
    1364:     }
    1365:     VecDestroy(Y);
    1366:   }
    1367:   return(0);
    1368: }

    1370: /*@
    1371:    VecGetLocalVectorRead - Maps the local portion of a vector into a
    1372:    vector.  You must call VecRestoreLocalVectorRead() when the local
    1373:    vector is no longer needed.

    1375:    Not collective.

    1377:    Input parameter:
    1378: .  v - The vector for which the local vector is desired.

    1380:    Output parameter:
    1381: .  w - Upon exit this contains the local vector.

    1383:    Level: beginner

    1385:    Notes:
    1386:    This function is similar to VecGetArrayRead() which maps the local
    1387:    portion into a raw pointer.  VecGetLocalVectorRead() is usually
    1388:    almost as efficient as VecGetArrayRead() but in certain circumstances
    1389:    VecGetLocalVectorRead() can be much more efficient than
    1390:    VecGetArrayRead().  This is because the construction of a contiguous
    1391:    array representing the vector data required by VecGetArrayRead() can
    1392:    be an expensive operation for certain vector types.  For example, for
    1393:    GPU vectors VecGetArrayRead() requires that the data between device
    1394:    and host is synchronized.

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

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

    1409:   VecCheckSameLocalSize(v,1,w,2);
    1410:   if (v->ops->getlocalvectorread) {
    1411:     (*v->ops->getlocalvectorread)(v,w);
    1412:   } else {
    1413:     VecGetArrayRead(v,(const PetscScalar**)&a);
    1414:     VecPlaceArray(w,a);
    1415:   }
    1416:   return(0);
    1417: }

    1419: /*@
    1420:    VecRestoreLocalVectorRead - Unmaps the local portion of a vector
    1421:    previously mapped into a vector using VecGetLocalVectorRead().

    1423:    Not collective.

    1425:    Input parameter:
    1426: .  v - The local portion of this vector was previously mapped into w using VecGetLocalVectorRead().
    1427: .  w - The vector into which the local portion of v was mapped.

    1429:    Level: beginner

    1431: .seealso: VecGetLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
    1432: @*/
    1433: PetscErrorCode VecRestoreLocalVectorRead(Vec v,Vec w)
    1434: {
    1436:   PetscScalar    *a;

    1441:   if (v->ops->restorelocalvectorread) {
    1442:     (*v->ops->restorelocalvectorread)(v,w);
    1443:   } else {
    1444:     VecGetArrayRead(w,(const PetscScalar**)&a);
    1445:     VecRestoreArrayRead(v,(const PetscScalar**)&a);
    1446:     VecResetArray(w);
    1447:   }
    1448:   return(0);
    1449: }

    1451: /*@
    1452:    VecGetLocalVector - Maps the local portion of a vector into a
    1453:    vector.

    1455:    Collective on v, not collective on w.

    1457:    Input parameter:
    1458: .  v - The vector for which the local vector is desired.

    1460:    Output parameter:
    1461: .  w - Upon exit this contains the local vector.

    1463:    Level: beginner

    1465:    Notes:
    1466:    This function is similar to VecGetArray() which maps the local
    1467:    portion into a raw pointer.  VecGetLocalVector() is usually about as
    1468:    efficient as VecGetArray() but in certain circumstances
    1469:    VecGetLocalVector() can be much more efficient than VecGetArray().
    1470:    This is because the construction of a contiguous array representing
    1471:    the vector data required by VecGetArray() can be an expensive
    1472:    operation for certain vector types.  For example, for GPU vectors
    1473:    VecGetArray() requires that the data between device and host is
    1474:    synchronized.

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

    1486:   VecCheckSameLocalSize(v,1,w,2);
    1487:   if (v->ops->getlocalvector) {
    1488:     (*v->ops->getlocalvector)(v,w);
    1489:   } else {
    1490:     VecGetArray(v,&a);
    1491:     VecPlaceArray(w,a);
    1492:   }
    1493:   return(0);
    1494: }

    1496: /*@
    1497:    VecRestoreLocalVector - Unmaps the local portion of a vector
    1498:    previously mapped into a vector using VecGetLocalVector().

    1500:    Logically collective.

    1502:    Input parameter:
    1503: .  v - The local portion of this vector was previously mapped into w using VecGetLocalVector().
    1504: .  w - The vector into which the local portion of v was mapped.

    1506:    Level: beginner

    1508: .seealso: VecGetLocalVector(), VecGetLocalVectorRead(), VecRestoreLocalVectorRead(), LocalVectorRead(), VecGetArrayRead(), VecGetArray()
    1509: @*/
    1510: PetscErrorCode VecRestoreLocalVector(Vec v,Vec w)
    1511: {
    1513:   PetscScalar    *a;

    1518:   if (v->ops->restorelocalvector) {
    1519:     (*v->ops->restorelocalvector)(v,w);
    1520:   } else {
    1521:     VecGetArray(w,&a);
    1522:     VecRestoreArray(v,&a);
    1523:     VecResetArray(w);
    1524:   }
    1525:   return(0);
    1526: }

    1528: /*@C
    1529:    VecGetArray - Returns a pointer to a contiguous array that contains this
    1530:    processor's portion of the vector data. For the standard PETSc
    1531:    vectors, VecGetArray() returns a pointer to the local data array and
    1532:    does not use any copies. If the underlying vector data is not stored
    1533:    in a contiguous array this routine will copy the data to a contiguous
    1534:    array and return a pointer to that. You MUST call VecRestoreArray()
    1535:    when you no longer need access to the array.

    1537:    Logically Collective on Vec

    1539:    Input Parameter:
    1540: .  x - the vector

    1542:    Output Parameter:
    1543: .  a - location to put pointer to the array

    1545:    Fortran Note:
    1546:    This routine is used differently from Fortran 77
    1547: $    Vec         x
    1548: $    PetscScalar x_array(1)
    1549: $    PetscOffset i_x
    1550: $    PetscErrorCode ierr
    1551: $       call VecGetArray(x,x_array,i_x,ierr)
    1552: $
    1553: $   Access first local entry in vector with
    1554: $      value = x_array(i_x + 1)
    1555: $
    1556: $      ...... other code
    1557: $       call VecRestoreArray(x,x_array,i_x,ierr)
    1558:    For Fortran 90 see VecGetArrayF90()

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

    1563:    Level: beginner

    1565:    Concepts: vector^accessing local values

    1567: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
    1568:           VecGetArrayPair(), VecRestoreArrayPair()
    1569: @*/
    1570: PetscErrorCode VecGetArray(Vec x,PetscScalar **a)
    1571: {
    1573: #if defined(PETSC_HAVE_VIENNACL)
    1574:   PetscBool      is_viennacltype = PETSC_FALSE;
    1575: #endif

    1579:   VecLocked(x,1);
    1580:   if (x->petscnative) {
    1581: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
    1582:     if (x->valid_GPU_array == PETSC_OFFLOAD_GPU) {
    1583: #if defined(PETSC_HAVE_VIENNACL)
    1584:       PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
    1585:       if (is_viennacltype) {
    1586:         VecViennaCLCopyFromGPU(x);
    1587:       } else
    1588: #endif
    1589:       {
    1590: #if defined(PETSC_HAVE_VECCUDA)
    1591:         VecCUDACopyFromGPU(x);
    1592: #endif
    1593:       }
    1594:     } else if (x->valid_GPU_array == PETSC_OFFLOAD_UNALLOCATED) {
    1595: #if defined(PETSC_HAVE_VIENNACL)
    1596:       PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
    1597:       if (is_viennacltype) {
    1598:         VecViennaCLAllocateCheckHost(x);
    1599:       } else
    1600: #endif
    1601:       {
    1602: #if defined(PETSC_HAVE_VECCUDA)
    1603:         VecCUDAAllocateCheckHost(x);
    1604: #endif
    1605:       }
    1606:     }
    1607: #endif
    1608:     *a = *((PetscScalar**)x->data);
    1609:   } else {
    1610:     if (x->ops->getarray) {
    1611:       (*x->ops->getarray)(x,a);
    1612:     } else SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot get array for vector type \"%s\"",((PetscObject)x)->type_name);
    1613:   }
    1614:   return(0);
    1615: }

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

    1620:    Not Collective

    1622:    Input Parameters:
    1623: .  x - the vector

    1625:    Output Parameter:
    1626: .  a - the array

    1628:    Level: beginner

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

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

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

    1639: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
    1640: @*/
    1641: PetscErrorCode VecGetArrayRead(Vec x,const PetscScalar **a)
    1642: {
    1644: #if defined(PETSC_HAVE_VIENNACL)
    1645:   PetscBool      is_viennacltype = PETSC_FALSE;
    1646: #endif

    1650:   if (x->petscnative) {
    1651: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
    1652:     if (x->valid_GPU_array == PETSC_OFFLOAD_GPU) {
    1653: #if defined(PETSC_HAVE_VIENNACL)
    1654:       PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
    1655:       if (is_viennacltype) {
    1656:         VecViennaCLCopyFromGPU(x);
    1657:       } else
    1658: #endif
    1659:       {
    1660: #if defined(PETSC_HAVE_VECCUDA)
    1661:         VecCUDACopyFromGPU(x);
    1662: #endif
    1663:       }
    1664:     }
    1665: #endif
    1666:     *a = *((PetscScalar **)x->data);
    1667:   } else if (x->ops->getarrayread) {
    1668:     (*x->ops->getarrayread)(x,a);
    1669:   } else {
    1670:     (*x->ops->getarray)(x,(PetscScalar**)a);
    1671:   }
    1672:   return(0);
    1673: }

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

    1680:    Logically Collective on Vec

    1682:    Input Parameter:
    1683: +  x - the vectors
    1684: -  n - the number of vectors

    1686:    Output Parameter:
    1687: .  a - location to put pointer to the array

    1689:    Fortran Note:
    1690:    This routine is not supported in Fortran.

    1692:    Level: intermediate

    1694: .seealso: VecGetArray(), VecRestoreArrays()
    1695: @*/
    1696: PetscErrorCode  VecGetArrays(const Vec x[],PetscInt n,PetscScalar **a[])
    1697: {
    1699:   PetscInt       i;
    1700:   PetscScalar    **q;

    1706:   if (n <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must get at least one array n = %D",n);
    1707:   PetscMalloc1(n,&q);
    1708:   for (i=0; i<n; ++i) {
    1709:     VecGetArray(x[i],&q[i]);
    1710:   }
    1711:   *a = q;
    1712:   return(0);
    1713: }

    1715: /*@C
    1716:    VecRestoreArrays - Restores a group of vectors after VecGetArrays()
    1717:    has been called.

    1719:    Logically Collective on Vec

    1721:    Input Parameters:
    1722: +  x - the vector
    1723: .  n - the number of vectors
    1724: -  a - location of pointer to arrays obtained from VecGetArrays()

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

    1732:    Fortran Note:
    1733:    This routine is not supported in Fortran.

    1735:    Level: intermediate

    1737: .seealso: VecGetArrays(), VecRestoreArray()
    1738: @*/
    1739: PetscErrorCode  VecRestoreArrays(const Vec x[],PetscInt n,PetscScalar **a[])
    1740: {
    1742:   PetscInt       i;
    1743:   PetscScalar    **q = *a;

    1750:   for (i=0; i<n; ++i) {
    1751:     VecRestoreArray(x[i],&q[i]);
    1752:   }
    1753:   PetscFree(q);
    1754:   return(0);
    1755: }

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

    1760:    Logically Collective on Vec

    1762:    Input Parameters:
    1763: +  x - the vector
    1764: -  a - location of pointer to array obtained from VecGetArray()

    1766:    Level: beginner

    1768:    Notes:
    1769:    For regular PETSc vectors this routine does not involve any copies. For
    1770:    any special vectors that do not store local vector data in a contiguous
    1771:    array, this routine will copy the data back into the underlying
    1772:    vector data structure from the array obtained with VecGetArray().

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

    1778:    Fortran Note:
    1779:    This routine is used differently from Fortran 77
    1780: $    Vec         x
    1781: $    PetscScalar x_array(1)
    1782: $    PetscOffset i_x
    1783: $    PetscErrorCode ierr
    1784: $       call VecGetArray(x,x_array,i_x,ierr)
    1785: $
    1786: $   Access first local entry in vector with
    1787: $      value = x_array(i_x + 1)
    1788: $
    1789: $      ...... other code
    1790: $       call VecRestoreArray(x,x_array,i_x,ierr)

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

    1796: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
    1797:           VecGetArrayPair(), VecRestoreArrayPair()
    1798: @*/
    1799: PetscErrorCode VecRestoreArray(Vec x,PetscScalar **a)
    1800: {

    1805:   if (x->petscnative) {
    1806: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_VECCUDA)
    1807:     x->valid_GPU_array = PETSC_OFFLOAD_CPU;
    1808: #endif
    1809:   } else {
    1810:     (*x->ops->restorearray)(x,a);
    1811:   }
    1812:   if (a) *a = NULL;
    1813:   PetscObjectStateIncrease((PetscObject)x);
    1814:   return(0);
    1815: }

    1817: /*@C
    1818:    VecRestoreArrayRead - Restore array obtained with VecGetArrayRead()

    1820:    Not Collective

    1822:    Input Parameters:
    1823: +  vec - the vector
    1824: -  array - the array

    1826:    Level: beginner

    1828: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
    1829: @*/
    1830: PetscErrorCode VecRestoreArrayRead(Vec x,const PetscScalar **a)
    1831: {

    1836:   if (x->petscnative) {
    1837:     /* nothing */
    1838:   } else if (x->ops->restorearrayread) {
    1839:     (*x->ops->restorearrayread)(x,a);
    1840:   } else {
    1841:     (*x->ops->restorearray)(x,(PetscScalar**)a);
    1842:   }
    1843:   if (a) *a = NULL;
    1844:   return(0);
    1845: }

    1847: /*@
    1848:    VecPlaceArray - Allows one to replace the array in a vector with an
    1849:    array provided by the user. This is useful to avoid copying an array
    1850:    into a vector.

    1852:    Not Collective

    1854:    Input Parameters:
    1855: +  vec - the vector
    1856: -  array - the array

    1858:    Notes:
    1859:    You can return to the original array with a call to VecResetArray()

    1861:    Level: developer

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

    1865: @*/
    1866: PetscErrorCode  VecPlaceArray(Vec vec,const PetscScalar array[])
    1867: {

    1874:   if (vec->ops->placearray) {
    1875:     (*vec->ops->placearray)(vec,array);
    1876:   } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot place array in this type of vector");
    1877:   PetscObjectStateIncrease((PetscObject)vec);
    1878:   return(0);
    1879: }

    1881: /*@C
    1882:    VecReplaceArray - Allows one to replace the array in a vector with an
    1883:    array provided by the user. This is useful to avoid copying an array
    1884:    into a vector.

    1886:    Not Collective

    1888:    Input Parameters:
    1889: +  vec - the vector
    1890: -  array - the array

    1892:    Notes:
    1893:    This permanently replaces the array and frees the memory associated
    1894:    with the old array.

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

    1899:    Not supported from Fortran

    1901:    Level: developer

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

    1905: @*/
    1906: PetscErrorCode  VecReplaceArray(Vec vec,const PetscScalar array[])
    1907: {

    1913:   if (vec->ops->replacearray) {
    1914:     (*vec->ops->replacearray)(vec,array);
    1915:   } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot replace array in this type of vector");
    1916:   PetscObjectStateIncrease((PetscObject)vec);
    1917:   return(0);
    1918: }

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

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

    1927:     Collective on Vec

    1929:     Input Parameters:
    1930: +   x - a vector to mimic
    1931: -   n - the number of vectors to obtain

    1933:     Output Parameters:
    1934: +   y - Fortran90 pointer to the array of vectors
    1935: -   ierr - error code

    1937:     Example of Usage:
    1938: .vb
    1939: #include <petsc/finclude/petscvec.h>
    1940:     use petscvec

    1942:     Vec x
    1943:     Vec, pointer :: y(:)
    1944:     ....
    1945:     call VecDuplicateVecsF90(x,2,y,ierr)
    1946:     call VecSet(y(2),alpha,ierr)
    1947:     call VecSet(y(2),alpha,ierr)
    1948:     ....
    1949:     call VecDestroyVecsF90(2,y,ierr)
    1950: .ve

    1952:     Notes:
    1953:     Not yet supported for all F90 compilers

    1955:     Use VecDestroyVecsF90() to free the space.

    1957:     Level: beginner

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

    1961: M*/

    1963: /*MC
    1964:     VecRestoreArrayF90 - Restores a vector to a usable state after a call to
    1965:     VecGetArrayF90().

    1967:     Synopsis:
    1968:     VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

    1970:     Logically Collective on Vec

    1972:     Input Parameters:
    1973: +   x - vector
    1974: -   xx_v - the Fortran90 pointer to the array

    1976:     Output Parameter:
    1977: .   ierr - error code

    1979:     Example of Usage:
    1980: .vb
    1981: #include <petsc/finclude/petscvec.h>
    1982:     use petscvec

    1984:     PetscScalar, pointer :: xx_v(:)
    1985:     ....
    1986:     call VecGetArrayF90(x,xx_v,ierr)
    1987:     xx_v(3) = a
    1988:     call VecRestoreArrayF90(x,xx_v,ierr)
    1989: .ve

    1991:     Level: beginner

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

    1995: M*/

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

    2000:     Synopsis:
    2001:     VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)

    2003:     Collective on Vec

    2005:     Input Parameters:
    2006: +   n - the number of vectors previously obtained
    2007: -   x - pointer to array of vector pointers

    2009:     Output Parameter:
    2010: .   ierr - error code

    2012:     Notes:
    2013:     Not yet supported for all F90 compilers

    2015:     Level: beginner

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

    2019: M*/

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

    2027:     Synopsis:
    2028:     VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

    2030:     Logically Collective on Vec

    2032:     Input Parameter:
    2033: .   x - vector

    2035:     Output Parameters:
    2036: +   xx_v - the Fortran90 pointer to the array
    2037: -   ierr - error code

    2039:     Example of Usage:
    2040: .vb
    2041: #include <petsc/finclude/petscvec.h>
    2042:     use petscvec

    2044:     PetscScalar, pointer :: xx_v(:)
    2045:     ....
    2046:     call VecGetArrayF90(x,xx_v,ierr)
    2047:     xx_v(3) = a
    2048:     call VecRestoreArrayF90(x,xx_v,ierr)
    2049: .ve

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

    2053:     Level: beginner

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

    2057: M*/

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

    2065:     Synopsis:
    2066:     VecGetArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

    2068:     Logically Collective on Vec

    2070:     Input Parameter:
    2071: .   x - vector

    2073:     Output Parameters:
    2074: +   xx_v - the Fortran90 pointer to the array
    2075: -   ierr - error code

    2077:     Example of Usage:
    2078: .vb
    2079: #include <petsc/finclude/petscvec.h>
    2080:     use petscvec

    2082:     PetscScalar, pointer :: xx_v(:)
    2083:     ....
    2084:     call VecGetArrayReadF90(x,xx_v,ierr)
    2085:     a = xx_v(3)
    2086:     call VecRestoreArrayReadF90(x,xx_v,ierr)
    2087: .ve

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

    2091:     Level: beginner

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

    2095: M*/

    2097: /*MC
    2098:     VecRestoreArrayReadF90 - Restores a readonly vector to a usable state after a call to
    2099:     VecGetArrayReadF90().

    2101:     Synopsis:
    2102:     VecRestoreArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

    2104:     Logically Collective on Vec

    2106:     Input Parameters:
    2107: +   x - vector
    2108: -   xx_v - the Fortran90 pointer to the array

    2110:     Output Parameter:
    2111: .   ierr - error code

    2113:     Example of Usage:
    2114: .vb
    2115: #include <petsc/finclude/petscvec.h>
    2116:     use petscvec

    2118:     PetscScalar, pointer :: xx_v(:)
    2119:     ....
    2120:     call VecGetArrayReadF90(x,xx_v,ierr)
    2121:     a = xx_v(3)
    2122:     call VecRestoreArrayReadF90(x,xx_v,ierr)
    2123: .ve

    2125:     Level: beginner

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

    2129: M*/

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

    2136:    Logically Collective

    2138:    Input Parameter:
    2139: +  x - the vector
    2140: .  m - first dimension of two dimensional array
    2141: .  n - second dimension of two dimensional array
    2142: .  mstart - first index you will use in first coordinate direction (often 0)
    2143: -  nstart - first index in the second coordinate direction (often 0)

    2145:    Output Parameter:
    2146: .  a - location to put pointer to the array

    2148:    Level: developer

    2150:   Notes:
    2151:    For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
    2152:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
    2153:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
    2154:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().

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

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

    2160: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    2161:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    2162:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2163: @*/
    2164: PetscErrorCode  VecGetArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
    2165: {
    2167:   PetscInt       i,N;
    2168:   PetscScalar    *aa;

    2174:   VecGetLocalSize(x,&N);
    2175:   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);
    2176:   VecGetArray(x,&aa);

    2178:   PetscMalloc1(m,a);
    2179:   for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
    2180:   *a -= mstart;
    2181:   return(0);
    2182: }

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

    2187:    Logically Collective

    2189:    Input Parameters:
    2190: +  x - the vector
    2191: .  m - first dimension of two dimensional array
    2192: .  n - second dimension of the two dimensional array
    2193: .  mstart - first index you will use in first coordinate direction (often 0)
    2194: .  nstart - first index in the second coordinate direction (often 0)
    2195: -  a - location of pointer to array obtained from VecGetArray2d()

    2197:    Level: developer

    2199:    Notes:
    2200:    For regular PETSc vectors this routine does not involve any copies. For
    2201:    any special vectors that do not store local vector data in a contiguous
    2202:    array, this routine will copy the data back into the underlying
    2203:    vector data structure from the array obtained with VecGetArray().

    2205:    This routine actually zeros out the a pointer.

    2207: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    2208:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    2209:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2210: @*/
    2211: PetscErrorCode  VecRestoreArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
    2212: {
    2214:   void           *dummy;

    2220:   dummy = (void*)(*a + mstart);
    2221:   PetscFree(dummy);
    2222:   VecRestoreArray(x,NULL);
    2223:   return(0);
    2224: }

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

    2231:    Logically Collective

    2233:    Input Parameter:
    2234: +  x - the vector
    2235: .  m - first dimension of two dimensional array
    2236: -  mstart - first index you will use in first coordinate direction (often 0)

    2238:    Output Parameter:
    2239: .  a - location to put pointer to the array

    2241:    Level: developer

    2243:   Notes:
    2244:    For a vector obtained from DMCreateLocalVector() mstart are likely
    2245:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
    2246:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().

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

    2250: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    2251:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    2252:           VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2253: @*/
    2254: PetscErrorCode  VecGetArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
    2255: {
    2257:   PetscInt       N;

    2263:   VecGetLocalSize(x,&N);
    2264:   if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
    2265:   VecGetArray(x,a);
    2266:   *a  -= mstart;
    2267:   return(0);
    2268: }

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

    2273:    Logically Collective

    2275:    Input Parameters:
    2276: +  x - the vector
    2277: .  m - first dimension of two dimensional array
    2278: .  mstart - first index you will use in first coordinate direction (often 0)
    2279: -  a - location of pointer to array obtained from VecGetArray21()

    2281:    Level: developer

    2283:    Notes:
    2284:    For regular PETSc vectors this routine does not involve any copies. For
    2285:    any special vectors that do not store local vector data in a contiguous
    2286:    array, this routine will copy the data back into the underlying
    2287:    vector data structure from the array obtained with VecGetArray1d().

    2289:    This routine actually zeros out the a pointer.

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

    2293: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    2294:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    2295:           VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
    2296: @*/
    2297: PetscErrorCode  VecRestoreArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
    2298: {

    2304:   VecRestoreArray(x,NULL);
    2305:   return(0);
    2306: }

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

    2314:    Logically Collective

    2316:    Input Parameter:
    2317: +  x - the vector
    2318: .  m - first dimension of three dimensional array
    2319: .  n - second dimension of three dimensional array
    2320: .  p - third dimension of three dimensional array
    2321: .  mstart - first index you will use in first coordinate direction (often 0)
    2322: .  nstart - first index in the second coordinate direction (often 0)
    2323: -  pstart - first index in the third coordinate direction (often 0)

    2325:    Output Parameter:
    2326: .  a - location to put pointer to the array

    2328:    Level: developer

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

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

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

    2340: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    2341:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    2342:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2343: @*/
    2344: PetscErrorCode  VecGetArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
    2345: {
    2347:   PetscInt       i,N,j;
    2348:   PetscScalar    *aa,**b;

    2354:   VecGetLocalSize(x,&N);
    2355:   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);
    2356:   VecGetArray(x,&aa);

    2358:   PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
    2359:   b    = (PetscScalar**)((*a) + m);
    2360:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
    2361:   for (i=0; i<m; i++)
    2362:     for (j=0; j<n; j++)
    2363:       b[i*n+j] = aa + i*n*p + j*p - pstart;

    2365:   *a -= mstart;
    2366:   return(0);
    2367: }

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

    2372:    Logically Collective

    2374:    Input Parameters:
    2375: +  x - the vector
    2376: .  m - first dimension of three dimensional array
    2377: .  n - second dimension of the three dimensional array
    2378: .  p - third dimension of the three dimensional array
    2379: .  mstart - first index you will use in first coordinate direction (often 0)
    2380: .  nstart - first index in the second coordinate direction (often 0)
    2381: .  pstart - first index in the third coordinate direction (often 0)
    2382: -  a - location of pointer to array obtained from VecGetArray3d()

    2384:    Level: developer

    2386:    Notes:
    2387:    For regular PETSc vectors this routine does not involve any copies. For
    2388:    any special vectors that do not store local vector data in a contiguous
    2389:    array, this routine will copy the data back into the underlying
    2390:    vector data structure from the array obtained with VecGetArray().

    2392:    This routine actually zeros out the a pointer.

    2394: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    2395:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    2396:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
    2397: @*/
    2398: PetscErrorCode  VecRestoreArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
    2399: {
    2401:   void           *dummy;

    2407:   dummy = (void*)(*a + mstart);
    2408:   PetscFree(dummy);
    2409:   VecRestoreArray(x,NULL);
    2410:   return(0);
    2411: }

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

    2418:    Logically Collective

    2420:    Input Parameter:
    2421: +  x - the vector
    2422: .  m - first dimension of four dimensional array
    2423: .  n - second dimension of four dimensional array
    2424: .  p - third dimension of four dimensional array
    2425: .  q - fourth dimension of four dimensional array
    2426: .  mstart - first index you will use in first coordinate direction (often 0)
    2427: .  nstart - first index in the second coordinate direction (often 0)
    2428: .  pstart - first index in the third coordinate direction (often 0)
    2429: -  qstart - first index in the fourth coordinate direction (often 0)

    2431:    Output Parameter:
    2432: .  a - location to put pointer to the array

    2434:    Level: beginner

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

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

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

    2446: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    2447:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    2448:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2449: @*/
    2450: PetscErrorCode  VecGetArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
    2451: {
    2453:   PetscInt       i,N,j,k;
    2454:   PetscScalar    *aa,***b,**c;

    2460:   VecGetLocalSize(x,&N);
    2461:   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);
    2462:   VecGetArray(x,&aa);

    2464:   PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
    2465:   b    = (PetscScalar***)((*a) + m);
    2466:   c    = (PetscScalar**)(b + m*n);
    2467:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
    2468:   for (i=0; i<m; i++)
    2469:     for (j=0; j<n; j++)
    2470:       b[i*n+j] = c + i*n*p + j*p - pstart;
    2471:   for (i=0; i<m; i++)
    2472:     for (j=0; j<n; j++)
    2473:       for (k=0; k<p; k++)
    2474:         c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
    2475:   *a -= mstart;
    2476:   return(0);
    2477: }

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

    2482:    Logically Collective

    2484:    Input Parameters:
    2485: +  x - the vector
    2486: .  m - first dimension of four dimensional array
    2487: .  n - second dimension of the four dimensional array
    2488: .  p - third dimension of the four dimensional array
    2489: .  q - fourth dimension of the four dimensional array
    2490: .  mstart - first index you will use in first coordinate direction (often 0)
    2491: .  nstart - first index in the second coordinate direction (often 0)
    2492: .  pstart - first index in the third coordinate direction (often 0)
    2493: .  qstart - first index in the fourth coordinate direction (often 0)
    2494: -  a - location of pointer to array obtained from VecGetArray4d()

    2496:    Level: beginner

    2498:    Notes:
    2499:    For regular PETSc vectors this routine does not involve any copies. For
    2500:    any special vectors that do not store local vector data in a contiguous
    2501:    array, this routine will copy the data back into the underlying
    2502:    vector data structure from the array obtained with VecGetArray().

    2504:    This routine actually zeros out the a pointer.

    2506: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    2507:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    2508:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
    2509: @*/
    2510: PetscErrorCode  VecRestoreArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
    2511: {
    2513:   void           *dummy;

    2519:   dummy = (void*)(*a + mstart);
    2520:   PetscFree(dummy);
    2521:   VecRestoreArray(x,NULL);
    2522:   return(0);
    2523: }

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

    2530:    Logically Collective

    2532:    Input Parameter:
    2533: +  x - the vector
    2534: .  m - first dimension of two dimensional array
    2535: .  n - second dimension of two dimensional array
    2536: .  mstart - first index you will use in first coordinate direction (often 0)
    2537: -  nstart - first index in the second coordinate direction (often 0)

    2539:    Output Parameter:
    2540: .  a - location to put pointer to the array

    2542:    Level: developer

    2544:   Notes:
    2545:    For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
    2546:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
    2547:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
    2548:    the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().

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

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

    2554: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    2555:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    2556:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2557: @*/
    2558: PetscErrorCode  VecGetArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
    2559: {
    2560:   PetscErrorCode    ierr;
    2561:   PetscInt          i,N;
    2562:   const PetscScalar *aa;

    2568:   VecGetLocalSize(x,&N);
    2569:   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);
    2570:   VecGetArrayRead(x,&aa);

    2572:   PetscMalloc1(m,a);
    2573:   for (i=0; i<m; i++) (*a)[i] = (PetscScalar*) aa + i*n - nstart;
    2574:   *a -= mstart;
    2575:   return(0);
    2576: }

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

    2581:    Logically Collective

    2583:    Input Parameters:
    2584: +  x - the vector
    2585: .  m - first dimension of two dimensional array
    2586: .  n - second dimension of the two dimensional array
    2587: .  mstart - first index you will use in first coordinate direction (often 0)
    2588: .  nstart - first index in the second coordinate direction (often 0)
    2589: -  a - location of pointer to array obtained from VecGetArray2d()

    2591:    Level: developer

    2593:    Notes:
    2594:    For regular PETSc vectors this routine does not involve any copies. For
    2595:    any special vectors that do not store local vector data in a contiguous
    2596:    array, this routine will copy the data back into the underlying
    2597:    vector data structure from the array obtained with VecGetArray().

    2599:    This routine actually zeros out the a pointer.

    2601: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    2602:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    2603:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2604: @*/
    2605: PetscErrorCode  VecRestoreArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
    2606: {
    2608:   void           *dummy;

    2614:   dummy = (void*)(*a + mstart);
    2615:   PetscFree(dummy);
    2616:   VecRestoreArrayRead(x,NULL);
    2617:   return(0);
    2618: }

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

    2625:    Logically Collective

    2627:    Input Parameter:
    2628: +  x - the vector
    2629: .  m - first dimension of two dimensional array
    2630: -  mstart - first index you will use in first coordinate direction (often 0)

    2632:    Output Parameter:
    2633: .  a - location to put pointer to the array

    2635:    Level: developer

    2637:   Notes:
    2638:    For a vector obtained from DMCreateLocalVector() mstart are likely
    2639:    obtained from the corner indices obtained from DMDAGetGhostCorners() while for
    2640:    DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().

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

    2644: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    2645:           VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    2646:           VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2647: @*/
    2648: PetscErrorCode  VecGetArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
    2649: {
    2651:   PetscInt       N;

    2657:   VecGetLocalSize(x,&N);
    2658:   if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
    2659:   VecGetArrayRead(x,(const PetscScalar**)a);
    2660:   *a  -= mstart;
    2661:   return(0);
    2662: }

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

    2667:    Logically Collective

    2669:    Input Parameters:
    2670: +  x - the vector
    2671: .  m - first dimension of two dimensional array
    2672: .  mstart - first index you will use in first coordinate direction (often 0)
    2673: -  a - location of pointer to array obtained from VecGetArray21()

    2675:    Level: developer

    2677:    Notes:
    2678:    For regular PETSc vectors this routine does not involve any copies. For
    2679:    any special vectors that do not store local vector data in a contiguous
    2680:    array, this routine will copy the data back into the underlying
    2681:    vector data structure from the array obtained with VecGetArray1dRead().

    2683:    This routine actually zeros out the a pointer.

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

    2687: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    2688:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    2689:           VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
    2690: @*/
    2691: PetscErrorCode  VecRestoreArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
    2692: {

    2698:   VecRestoreArrayRead(x,NULL);
    2699:   return(0);
    2700: }

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

    2708:    Logically Collective

    2710:    Input Parameter:
    2711: +  x - the vector
    2712: .  m - first dimension of three dimensional array
    2713: .  n - second dimension of three dimensional array
    2714: .  p - third dimension of three dimensional array
    2715: .  mstart - first index you will use in first coordinate direction (often 0)
    2716: .  nstart - first index in the second coordinate direction (often 0)
    2717: -  pstart - first index in the third coordinate direction (often 0)

    2719:    Output Parameter:
    2720: .  a - location to put pointer to the array

    2722:    Level: developer

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

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

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

    2734: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    2735:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    2736:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2737: @*/
    2738: PetscErrorCode  VecGetArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
    2739: {
    2740:   PetscErrorCode    ierr;
    2741:   PetscInt          i,N,j;
    2742:   const PetscScalar *aa;
    2743:   PetscScalar       **b;

    2749:   VecGetLocalSize(x,&N);
    2750:   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);
    2751:   VecGetArrayRead(x,&aa);

    2753:   PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
    2754:   b    = (PetscScalar**)((*a) + m);
    2755:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
    2756:   for (i=0; i<m; i++)
    2757:     for (j=0; j<n; j++)
    2758:       b[i*n+j] = (PetscScalar *)aa + i*n*p + j*p - pstart;

    2760:   *a -= mstart;
    2761:   return(0);
    2762: }

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

    2767:    Logically Collective

    2769:    Input Parameters:
    2770: +  x - the vector
    2771: .  m - first dimension of three dimensional array
    2772: .  n - second dimension of the three dimensional array
    2773: .  p - third dimension of the three dimensional array
    2774: .  mstart - first index you will use in first coordinate direction (often 0)
    2775: .  nstart - first index in the second coordinate direction (often 0)
    2776: .  pstart - first index in the third coordinate direction (often 0)
    2777: -  a - location of pointer to array obtained from VecGetArray3dRead()

    2779:    Level: developer

    2781:    Notes:
    2782:    For regular PETSc vectors this routine does not involve any copies. For
    2783:    any special vectors that do not store local vector data in a contiguous
    2784:    array, this routine will copy the data back into the underlying
    2785:    vector data structure from the array obtained with VecGetArray().

    2787:    This routine actually zeros out the a pointer.

    2789: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    2790:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    2791:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
    2792: @*/
    2793: PetscErrorCode  VecRestoreArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
    2794: {
    2796:   void           *dummy;

    2802:   dummy = (void*)(*a + mstart);
    2803:   PetscFree(dummy);
    2804:   VecRestoreArrayRead(x,NULL);
    2805:   return(0);
    2806: }

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

    2813:    Logically Collective

    2815:    Input Parameter:
    2816: +  x - the vector
    2817: .  m - first dimension of four dimensional array
    2818: .  n - second dimension of four dimensional array
    2819: .  p - third dimension of four dimensional array
    2820: .  q - fourth dimension of four dimensional array
    2821: .  mstart - first index you will use in first coordinate direction (often 0)
    2822: .  nstart - first index in the second coordinate direction (often 0)
    2823: .  pstart - first index in the third coordinate direction (often 0)
    2824: -  qstart - first index in the fourth coordinate direction (often 0)

    2826:    Output Parameter:
    2827: .  a - location to put pointer to the array

    2829:    Level: beginner

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

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

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

    2841: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
    2842:           VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
    2843:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
    2844: @*/
    2845: PetscErrorCode  VecGetArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
    2846: {
    2847:   PetscErrorCode    ierr;
    2848:   PetscInt          i,N,j,k;
    2849:   const PetscScalar *aa;
    2850:   PetscScalar       ***b,**c;

    2856:   VecGetLocalSize(x,&N);
    2857:   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);
    2858:   VecGetArrayRead(x,&aa);

    2860:   PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
    2861:   b    = (PetscScalar***)((*a) + m);
    2862:   c    = (PetscScalar**)(b + m*n);
    2863:   for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
    2864:   for (i=0; i<m; i++)
    2865:     for (j=0; j<n; j++)
    2866:       b[i*n+j] = c + i*n*p + j*p - pstart;
    2867:   for (i=0; i<m; i++)
    2868:     for (j=0; j<n; j++)
    2869:       for (k=0; k<p; k++)
    2870:         c[i*n*p+j*p+k] = (PetscScalar*) aa + i*n*p*q + j*p*q + k*q - qstart;
    2871:   *a -= mstart;
    2872:   return(0);
    2873: }

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

    2878:    Logically Collective

    2880:    Input Parameters:
    2881: +  x - the vector
    2882: .  m - first dimension of four dimensional array
    2883: .  n - second dimension of the four dimensional array
    2884: .  p - third dimension of the four dimensional array
    2885: .  q - fourth dimension of the four dimensional array
    2886: .  mstart - first index you will use in first coordinate direction (often 0)
    2887: .  nstart - first index in the second coordinate direction (often 0)
    2888: .  pstart - first index in the third coordinate direction (often 0)
    2889: .  qstart - first index in the fourth coordinate direction (often 0)
    2890: -  a - location of pointer to array obtained from VecGetArray4dRead()

    2892:    Level: beginner

    2894:    Notes:
    2895:    For regular PETSc vectors this routine does not involve any copies. For
    2896:    any special vectors that do not store local vector data in a contiguous
    2897:    array, this routine will copy the data back into the underlying
    2898:    vector data structure from the array obtained with VecGetArray().

    2900:    This routine actually zeros out the a pointer.

    2902: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
    2903:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
    2904:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
    2905: @*/
    2906: PetscErrorCode  VecRestoreArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
    2907: {
    2909:   void           *dummy;

    2915:   dummy = (void*)(*a + mstart);
    2916:   PetscFree(dummy);
    2917:   VecRestoreArrayRead(x,NULL);
    2918:   return(0);
    2919: }

    2921: #if defined(PETSC_USE_DEBUG)

    2923: /*@
    2924:    VecLockGet  - Gets the current lock status of a vector

    2926:    Logically Collective on Vec

    2928:    Input Parameter:
    2929: .  x - the vector

    2931:    Output Parameter:
    2932: .  state - greater than zero indicates the vector is still locked

    2934:    Level: beginner

    2936:    Concepts: vector^accessing local values

    2938: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockPush(), VecLockGet()
    2939: @*/
    2940: PetscErrorCode VecLockGet(Vec x,PetscInt *state)
    2941: {
    2944:   *state = x->lock;
    2945:   return(0);
    2946: }

    2948: /*@
    2949:    VecLockPush  - Lock a vector from writing

    2951:    Logically Collective on Vec

    2953:    Input Parameter:
    2954: .  x - the vector

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

    2959:     Call VecLockPop() to remove the latest lock

    2961:    Level: beginner

    2963:    Concepts: vector^accessing local values

    2965: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockPop(), VecLockGet()
    2966: @*/
    2967: PetscErrorCode VecLockPush(Vec x)
    2968: {
    2971:   x->lock++;
    2972:   return(0);
    2973: }

    2975: /*@
    2976:    VecLockPop  - Unlock a vector from writing

    2978:    Logically Collective on Vec

    2980:    Input Parameter:
    2981: .  x - the vector

    2983:    Level: beginner

    2985:    Concepts: vector^accessing local values

    2987: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockPush(), VecLockGet()
    2988: @*/
    2989: PetscErrorCode VecLockPop(Vec x)
    2990: {
    2993:   x->lock--;
    2994:   if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector has been unlocked too many times");
    2995:   return(0);
    2996: }

    2998: #endif