Actual source code: rvector.c

  1: #define PETSCVEC_DLL

  3: /*
  4:      Provides the interface functions for vector operations that have PetscScalar/PetscReal in the signature
  5:    These are the vector functions the user calls.
  6: */
 7:  #include private/vecimpl.h

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

 14:    Collective on Vec

 16:    Input Parameters:
 17: .  x, y  - the vectors

 19:    Output Parameter:
 20: .  max - the result

 22:    Level: advanced

 24:    Notes: any subset of the x and may be the same vector.
 25:           if a particular y_i is zero, it is treated as 1 in the above formula

 27: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs()
 28: @*/
 29: PetscErrorCode  VecMaxPointwiseDivide(Vec x,Vec y,PetscReal *max)
 30: {

 40:   if (x->map.N != y->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
 41:   if (x->map.n != y->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");

 43:   (*x->ops->maxpointwisedivide)(x,y,max);
 44:   return(0);
 45: }

 49: /*@
 50:    VecDot - Computes the vector dot product.

 52:    Collective on Vec

 54:    Input Parameters:
 55: .  x, y - the vectors

 57:    Output Parameter:
 58: .  val - the dot product

 60:    Performance Issues:
 61: +    per-processor memory bandwidth
 62: .    interprocessor latency
 63: -    work load inbalance that causes certain processes to arrive much earlier than
 64:      others

 66:    Notes for Users of Complex Numbers:
 67:    For complex vectors, VecDot() computes 
 68: $     val = (x,y) = y^H x,
 69:    where y^H denotes the conjugate transpose of y.

 71:    Use VecTDot() for the indefinite form
 72: $     val = (x,y) = y^T x,
 73:    where y^T denotes the transpose of y.

 75:    Level: intermediate

 77:    Concepts: inner product
 78:    Concepts: vector^inner product

 80: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd()
 81: @*/
 82: PetscErrorCode  VecDot(Vec x,Vec y,PetscScalar *val)
 83: {

 93:   if (x->map.N != y->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
 94:   if (x->map.n != y->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");

 97:   (*x->ops->dot)(x,y,val);
 99:   return(0);
100: }

104: /*@
105:    VecNorm  - Computes the vector norm.

107:    Collective on Vec

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

115:    Output Parameter:
116: .  val - the norm 

118:    Notes:
119: $     NORM_1 denotes sum_i |x_i|
120: $     NORM_2 denotes sqrt(sum_i (x_i)^2)
121: $     NORM_INFINITY denotes max_i |x_i|

123:    Level: intermediate

125:    Performance Issues:
126: +    per-processor memory bandwidth
127: .    interprocessor latency
128: -    work load inbalance that causes certain processes to arrive much earlier than
129:      others

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

136:    Concepts: norm
137:    Concepts: vector^norm

139: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), 
140:           VecNormBegin(), VecNormEnd()

142: @*/
143: PetscErrorCode  VecNorm(Vec x,NormType type,PetscReal *val)
144: {
145:   PetscTruth     flg;


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

162:   (*x->ops->norm)(x,type,val);

165:   if (type!=NORM_1_AND_2) {
166:     PetscObjectComposedDataSetReal((PetscObject)x,NormIds[type],*val);
167:   }
168:   return(0);
169: }

173: /*@
174:    VecNormalize - Normalizes a vector by 2-norm. 

176:    Collective on Vec

178:    Input Parameters:
179: +  x - the vector

181:    Output Parameter:
182: .  x - the normalized vector
183: -  val - the vector norm before normalization

185:    Level: intermediate

187:    Concepts: vector^normalizing
188:    Concepts: normalizing^vector

190: @*/
191: PetscErrorCode  VecNormalize(Vec x,PetscReal *val)
192: {

200:   VecNorm(x,NORM_2,val);
201:   if (!*val) {
202:     PetscInfo(x,"Vector of zero norm can not be normalized; Returning only the zero norm\n");
203:   } else if (*val != 1.0) {
204:     PetscScalar tmp = 1.0/(*val);
205:     VecScale(x,tmp);
206:   }
208:   return(0);
209: }

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

216:    Collective on Vec

218:    Input Parameter:
219: .  x - the vector

221:    Output Parameters:
222: +  val - the maximum component
223: -  p - the location of val

225:    Notes:
226:    Returns the value PETSC_MIN and p = -1 if the vector is of length 0.

228:    Level: intermediate

230:    Concepts: maximum^of vector
231:    Concepts: vector^maximum value

233: .seealso: VecNorm(), VecMin()
234: @*/
235: PetscErrorCode  VecMax(Vec x,PetscInt *p,PetscReal *val)
236: {

244:   (*x->ops->max)(x,p,val);
246:   return(0);
247: }

251: /*@
252:    VecMin - Determines the minimum vector component and its location.

254:    Collective on Vec

256:    Input Parameters:
257: .  x - the vector

259:    Output Parameter:
260: +  val - the minimum component
261: -  p - the location of val

263:    Level: intermediate

265:    Notes:
266:    Returns the value PETSC_MAX and p = -1 if the vector is of length 0.

268:    Concepts: minimum^of vector
269:    Concepts: vector^minimum entry

271: .seealso: VecMax()
272: @*/
273: PetscErrorCode  VecMin(Vec x,PetscInt *p,PetscReal *val)
274: {

282:   (*x->ops->min)(x,p,val);
284:   return(0);
285: }

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

293:    Collective on Vec

295:    Input Parameters:
296: .  x, y - the vectors

298:    Output Parameter:
299: .  val - the dot product

301:    Notes for Users of Complex Numbers:
302:    For complex vectors, VecTDot() computes the indefinite form
303: $     val = (x,y) = y^T x,
304:    where y^T denotes the transpose of y.

306:    Use VecDot() for the inner product
307: $     val = (x,y) = y^H x,
308:    where y^H denotes the conjugate transpose of y.

310:    Level: intermediate

312:    Concepts: inner product^non-Hermitian
313:    Concepts: vector^inner product
314:    Concepts: non-Hermitian inner product

316: .seealso: VecDot(), VecMTDot()
317: @*/
318: PetscErrorCode  VecTDot(Vec x,Vec y,PetscScalar *val)
319: {

329:   if (x->map.N != y->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
330:   if (x->map.n != y->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");

333:   (*x->ops->tdot)(x,y,val);
335:   return(0);
336: }

340: /*@
341:    VecScale - Scales a vector. 

343:    Collective on Vec

345:    Input Parameters:
346: +  x - the vector
347: -  alpha - the scalar

349:    Output Parameter:
350: .  x - the scaled vector

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

356:    Level: intermediate

358:    Concepts: vector^scaling
359:    Concepts: scaling^vector

361: @*/
362: PetscErrorCode  VecScale (Vec x, PetscScalar alpha)
363: {
364:   PetscReal      norms[4] = {0.0,0.0,0.0, 0.0};
365:   PetscTruth     flgs[4];
367:   PetscInt       i;

372:   if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
374:   (*x->ops->scale)(x,alpha);

376:   /*
377:    * Update cached data
378:    */
379:   for (i=0; i<4; i++) {
380:     PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],norms[i],flgs[i]);
381:   }

383:   /* in general we consider this object touched */
384:   PetscObjectStateIncrease((PetscObject)x);

386:   for (i=0; i<4; i++) {
387:     if (flgs[i]) {
388:       PetscObjectComposedDataSetReal((PetscObject)x,NormIds[i],PetscAbsScalar(alpha)*norms[i]);
389:     }
390:   }

393:   return(0);
394: }


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

402:    Collective on Vec

404:    Input Parameters:
405: +  x  - the vector
406: -  alpha - the scalar

408:    Output Parameter:
409: .  x  - the vector

411:    Note:
412:    For a vector of dimension n, VecSet() computes
413: $     x[i] = alpha, for i=1,...,n,
414:    so that all vector entries then equal the identical
415:    scalar value, alpha.  Use the more general routine
416:    VecSetValues() to set different vector entries.

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

421:    Level: beginner

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

425:    Concepts: vector^setting to constant

427: @*/
428: PetscErrorCode  VecSet(Vec x,PetscScalar alpha)
429: {
430:   PetscReal      val;

436:   if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"You cannot call this after you have called VecSetValues() but\n before you have called VecAssemblyBegin/End()");
437: #if defined (PETSC_USE_DEBUG)
438:  {
439:    PetscReal alpha_local,alpha_max;
440:    alpha_local = PetscAbsScalar(alpha);
441:    MPI_Allreduce(&alpha_local,&alpha_max,1,MPIU_REAL,MPI_MAX,x->comm);
442:    if (alpha_local != alpha_max) SETERRQ(PETSC_ERR_ARG_WRONG,"Same value should be used across all processors");
443:  }
444: #endif

447:   (*x->ops->set)(x,alpha);

450:   /*
451:    * Update cached data
452:    */
453:   /* in general we consider this object touched */
454:   PetscObjectStateIncrease((PetscObject)x);

456:   /* however, norms can be simply set */
457:   val = PetscAbsScalar(alpha);
458:   PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],x->map.N * val);
459:   PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
460:   val = sqrt((double)x->map.N) * val;
461:   PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],val);
462:   PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],val);
463:   return(0);
464: }


469: /*@
470:    VecAXPY - Computes y = alpha x + y. 

472:    Collective on Vec

474:    Input Parameters:
475: +  alpha - the scalar
476: -  x, y  - the vectors

478:    Output Parameter:
479: .  y - output vector

481:    Level: intermediate

483:    Concepts: vector^BLAS
484:    Concepts: BLAS

486: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY()
487: @*/
488: PetscErrorCode  VecAXPY(Vec y,PetscScalar alpha,Vec x)
489: {

498:   if (x->map.N != y->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
499:   if (x->map.n != y->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");

502:   (*y->ops->axpy)(y,alpha,x);
504:   PetscObjectStateIncrease((PetscObject)y);
505:   return(0);
506: }

510: /*@
511:    VecAXPBY - Computes y = alpha x + beta y. 

513:    Collective on Vec

515:    Input Parameters:
516: +  alpha,beta - the scalars
517: -  x, y  - the vectors

519:    Output Parameter:
520: .  y - output vector

522:    Level: intermediate

524:    Concepts: BLAS
525:    Concepts: vector^BLAS

527: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY()
528: @*/
529: PetscErrorCode  VecAXPBY(Vec y,PetscScalar alpha,PetscScalar beta,Vec x)
530: {

539:   if (x->map.N != y->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
540:   if (x->map.n != y->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");

543:   (*y->ops->axpby)(y,alpha,beta,x);
545:   PetscObjectStateIncrease((PetscObject)y);
546:   return(0);
547: }

551: /*@
552:    VecAYPX - Computes y = x + alpha y.

554:    Collective on Vec

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

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

563:    Level: intermediate

565:    Concepts: vector^BLAS
566:    Concepts: BLAS

568: .seealso: VecAXPY(), VecWAXPY()
569: @*/
570: PetscErrorCode  VecAYPX(Vec y,PetscScalar alpha,Vec x)
571: {

580:   if (x->map.N != y->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
581:   if (x->map.n != y->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");

584:    (*y->ops->aypx)(y,alpha,x);
586:   PetscObjectStateIncrease((PetscObject)y);
587:   return(0);
588: }


593: /*@
594:    VecWAXPY - Computes w = alpha x + y.

596:    Collective on Vec

598:    Input Parameters:
599: +  alpha - the scalar
600: -  x, y  - the vectors

602:    Output Parameter:
603: .  w - the result

605:    Level: intermediate

607:    Concepts: vector^BLAS
608:    Concepts: BLAS

610: .seealso: VecAXPY(), VecAYPX(), VecAXPBY()
611: @*/
612: PetscErrorCode  VecWAXPY(Vec w,PetscScalar alpha,Vec x,Vec y)
613: {

625:   if (x->map.N != y->map.N || x->map.N != w->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
626:   if (x->map.n != y->map.n || x->map.n != w->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");

629:    (*w->ops->waxpy)(w,alpha,x,y);
631:   PetscObjectStateIncrease((PetscObject)w);
632:   return(0);
633: }


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

641:    Not Collective

643:    Input Parameters:
644: +  x - vector to insert in
645: .  ni - number of elements to add
646: .  ix - indices where to add
647: .  y - array of values
648: -  iora - either INSERT_VALUES or ADD_VALUES, where
649:    ADD_VALUES adds values to any existing entries, and
650:    INSERT_VALUES replaces existing entries with new values

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

655:    Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES 
656:    options cannot be mixed without intervening calls to the assembly
657:    routines.

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

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

664:    If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES), 
665:    negative indices may be passed in ix. These rows are 
666:    simply ignored. This allows easily inserting element load matrices
667:    with homogeneous Dirchlet boundary conditions that you don't want represented
668:    in the vector.

670:    Level: beginner

672:    Concepts: vector^setting values

674: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesLocal(),
675:            VecSetValue(), VecSetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecGetValues()
676: @*/
677: PetscErrorCode  VecSetValues(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
678: {

687:   (*x->ops->setvalues)(x,ni,ix,y,iora);
689:   PetscObjectStateIncrease((PetscObject)x);
690:   return(0);
691: }

695: /*@
696:    VecGetValues - Gets values from certain locations of a vector. Currently 
697:           can only get values on the same processor

699:     Collective on Vec
700:  
701:    Input Parameters:
702: +  x - vector to get values from
703: .  ni - number of elements to get
704: -  ix - indices where to get them from (in global 1d numbering)

706:    Output Parameter:
707: .   y - array of values

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

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

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

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

718:    If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES),
719:    negative indices may be passed in ix. These rows are
720:    simply ignored.

722:    Level: beginner

724:    Concepts: vector^getting values

726: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecGetValuesLocal(),
727:            VecGetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecSetValues()
728: @*/
729: PetscErrorCode  VecGetValues(Vec x,PetscInt ni,const PetscInt ix[],PetscScalar y[])
730: {

738:   (*x->ops->getvalues)(x,ni,ix,y);
739:   return(0);
740: }

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

747:    Not Collective

749:    Input Parameters:
750: +  x - vector to insert in
751: .  ni - number of blocks to add
752: .  ix - indices where to add in block count, rather than element count
753: .  y - array of values
754: -  iora - either INSERT_VALUES or ADD_VALUES, where
755:    ADD_VALUES adds values to any existing entries, and
756:    INSERT_VALUES replaces existing entries with new values

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

762:    Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 
763:    options cannot be mixed without intervening calls to the assembly
764:    routines.

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

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

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

776:    Level: intermediate

778:    Concepts: vector^setting values blocked

780: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesBlockedLocal(),
781:            VecSetValues()
782: @*/
783: PetscErrorCode  VecSetValuesBlocked(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
784: {

793:   (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);
795:   PetscObjectStateIncrease((PetscObject)x);
796:   return(0);
797: }


802: /*@
803:    VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
804:    using a local ordering of the nodes. 

806:    Not Collective

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

817:    Level: intermediate

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

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

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

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

831:    Concepts: vector^setting values with local numbering

833: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetLocalToGlobalMapping(),
834:            VecSetValuesBlockedLocal()
835: @*/
836: PetscErrorCode  VecSetValuesLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
837: {
839:   PetscInt       lixp[128],*lix = lixp;


848:   if (!x->ops->setvalueslocal) {
849:     if (!x->mapping) {
850:       SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMapping()");
851:     }
852:     if (ni > 128) {
853:       PetscMalloc(ni*sizeof(PetscInt),&lix);
854:     }
855:     ISLocalToGlobalMappingApply(x->mapping,ni,(PetscInt*)ix,lix);
856:     (*x->ops->setvalues)(x,ni,lix,y,iora);
857:     if (ni > 128) {
858:       PetscFree(lix);
859:     }
860:   } else {
861:     (*x->ops->setvalueslocal)(x,ni,ix,y,iora);
862:   }
864:   PetscObjectStateIncrease((PetscObject)x);
865:   return(0);
866: }

870: /*@
871:    VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
872:    using a local ordering of the nodes. 

874:    Not Collective

876:    Input Parameters:
877: +  x - vector to insert in
878: .  ni - number of blocks to add
879: .  ix - indices where to add in block count, not element count
880: .  y - array of values
881: -  iora - either INSERT_VALUES or ADD_VALUES, where
882:    ADD_VALUES adds values to any existing entries, and
883:    INSERT_VALUES replaces existing entries with new values

885:    Level: intermediate

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

891:    Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 
892:    options cannot be mixed without intervening calls to the assembly
893:    routines.

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

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


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

903: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesBlocked(), 
904:            VecSetLocalToGlobalMappingBlock()
905: @*/
906: PetscErrorCode  VecSetValuesBlockedLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
907: {
909:   PetscInt       lixp[128],*lix = lixp;

916:   if (!x->bmapping) {
917:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMappingBlock()");
918:   }
919:   if (ni > 128) {
920:     PetscMalloc(ni*sizeof(PetscInt),&lix);
921:   }

924:   ISLocalToGlobalMappingApply(x->bmapping,ni,(PetscInt*)ix,lix);
925:   (*x->ops->setvaluesblocked)(x,ni,lix,y,iora);
927:   if (ni > 128) {
928:     PetscFree(lix);
929:   }
930:   PetscObjectStateIncrease((PetscObject)x);
931:   return(0);
932: }



938: /*@
939:    VecMTDot - Computes indefinite vector multiple dot products. 
940:    That is, it does NOT use the complex conjugate.

942:    Collective on Vec

944:    Input Parameters:
945: +  x - one vector
946: .  nv - number of vectors
947: -  y - array of vectors.  Note that vectors are pointers

949:    Output Parameter:
950: .  val - array of the dot products

952:    Notes for Users of Complex Numbers:
953:    For complex vectors, VecMTDot() computes the indefinite form
954: $      val = (x,y) = y^T x,
955:    where y^T denotes the transpose of y.

957:    Use VecMDot() for the inner product
958: $      val = (x,y) = y^H x,
959:    where y^H denotes the conjugate transpose of y.

961:    Level: intermediate

963:    Concepts: inner product^multiple
964:    Concepts: vector^multiple inner products

966: .seealso: VecMDot(), VecTDot()
967: @*/
968: PetscErrorCode  VecMTDot(Vec x,PetscInt nv,const Vec y[],PetscScalar *val)
969: {

980:   if (x->map.N != (*y)->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
981:   if (x->map.n != (*y)->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");

984:   (*x->ops->mtdot)(x,nv,y,val);
986:   return(0);
987: }

991: /*@
992:    VecMDot - Computes vector multiple dot products. 

994:    Collective on Vec

996:    Input Parameters:
997: +  x - one vector
998: .  nv - number of vectors
999: -  y - array of vectors. 

1001:    Output Parameter:
1002: .  val - array of the dot products

1004:    Notes for Users of Complex Numbers:
1005:    For complex vectors, VecMDot() computes 
1006: $     val = (x,y) = y^H x,
1007:    where y^H denotes the conjugate transpose of y.

1009:    Use VecMTDot() for the indefinite form
1010: $     val = (x,y) = y^T x,
1011:    where y^T denotes the transpose of y.

1013:    Level: intermediate

1015:    Concepts: inner product^multiple
1016:    Concepts: vector^multiple inner products

1018: .seealso: VecMTDot(), VecDot()
1019: @*/
1020: PetscErrorCode  VecMDot(Vec x,PetscInt nv,const Vec y[],PetscScalar *val)
1021: {

1026:   if (!nv) return(0);
1027:   if (nv < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1034:   if (x->map.N != (*y)->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
1035:   if (x->map.n != (*y)->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");

1038:   (*x->ops->mdot)(x,nv,y,val);
1040:   return(0);
1041: }

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

1048:    Collective on Vec

1050:    Input Parameters:
1051: +  nv - number of scalars and x-vectors
1052: .  alpha - array of scalars
1053: .  y - one vector
1054: -  x - array of vectors

1056:    Level: intermediate

1058:    Concepts: BLAS

1060: .seealso: VecAXPY(), VecWAXPY(), VecAYPX()
1061: @*/
1062: PetscErrorCode  VecMAXPY(Vec y,PetscInt nv,const PetscScalar alpha[],Vec *x)
1063: {

1068:   if (!nv) return(0);
1069:   if (nv < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1076:   if (y->map.N != (*x)->map.N) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths");
1077:   if (y->map.n != (*x)->map.n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths");

1080:   (*y->ops->maxpy)(y,nv,alpha,x);
1082:   PetscObjectStateIncrease((PetscObject)y);
1083:   return(0);
1084: }

1086: /*MC
1087:    VecGetArray - Returns a pointer to a contiguous array that contains this 
1088:    processor's portion of the vector data. For the standard PETSc
1089:    vectors, VecGetArray() returns a pointer to the local data array and
1090:    does not use any copies. If the underlying vector data is not stored
1091:    in a contiquous array this routine will copy the data to a contiquous
1092:    array and return a pointer to that. You MUST call VecRestoreArray() 
1093:    when you no longer need access to the array.

1095:    Synopsis:
1096:    PetscErrorCode VecGetArray(Vec x,PetscScalar *a[])

1098:    Not Collective

1100:    Input Parameter:
1101: .  x - the vector

1103:    Output Parameter:
1104: .  a - location to put pointer to the array

1106:    Fortran Note:
1107:    This routine is used differently from Fortran 77
1108: $    Vec         x
1109: $    PetscScalar x_array(1)
1110: $    PetscOffset i_x
1111: $    PetscErrorCode ierr
1112: $       call VecGetArray(x,x_array,i_x,ierr)
1113: $
1114: $   Access first local entry in vector with
1115: $      value = x_array(i_x + 1)
1116: $
1117: $      ...... other code
1118: $       call VecRestoreArray(x,x_array,i_x,ierr)
1119:    For Fortran 90 see VecGetArrayF90()

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

1124:    Level: beginner

1126:    Concepts: vector^accessing local values

1128: .seealso: VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(), VecGetArray2d()
1129: M*/
1132: PetscErrorCode VecGetArray_Private(Vec x,PetscScalar *a[])
1133: {

1140:   (*x->ops->getarray)(x,a);
1141:   return(0);
1142: }


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

1152:    Not Collective

1154:    Input Parameter:
1155: +  x - the vectors
1156: -  n - the number of vectors

1158:    Output Parameter:
1159: .  a - location to put pointer to the array

1161:    Fortran Note:
1162:    This routine is not supported in Fortran.

1164:    Level: intermediate

1166: .seealso: VecGetArray(), VecRestoreArrays()
1167: @*/
1168: PetscErrorCode  VecGetArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1169: {
1171:   PetscInt       i;
1172:   PetscScalar    **q;

1178:   if (n <= 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must get at least one array n = %D",n);
1179:   PetscMalloc(n*sizeof(PetscScalar*),&q);
1180:   for (i=0; i<n; ++i) {
1181:     VecGetArray(x[i],&q[i]);
1182:   }
1183:   *a = q;
1184:   return(0);
1185: }

1189: /*@C
1190:    VecRestoreArrays - Restores a group of vectors after VecGetArrays()
1191:    has been called.

1193:    Not Collective

1195:    Input Parameters:
1196: +  x - the vector
1197: .  n - the number of vectors
1198: -  a - location of pointer to arrays obtained from VecGetArrays()

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

1206:    Fortran Note:
1207:    This routine is not supported in Fortran.

1209:    Level: intermediate

1211: .seealso: VecGetArrays(), VecRestoreArray()
1212: @*/
1213: PetscErrorCode  VecRestoreArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1214: {
1216:   PetscInt       i;
1217:   PetscScalar    **q = *a;


1224:   for(i=0;i<n;++i) {
1225:     VecRestoreArray(x[i],&q[i]);
1226:  }
1227:   PetscFree(q);
1228:   return(0);
1229: }

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

1234:    Not Collective

1236:    Synopsis:
1237:    PetscErrorCode VecRestoreArray(Vec x,PetscScalar *a[])

1239:    Input Parameters:
1240: +  x - the vector
1241: -  a - location of pointer to array obtained from VecGetArray()

1243:    Level: beginner

1245:    Notes:
1246:    For regular PETSc vectors this routine does not involve any copies. For
1247:    any special vectors that do not store local vector data in a contiguous
1248:    array, this routine will copy the data back into the underlying 
1249:    vector data structure from the array obtained with VecGetArray().

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

1255:    Fortran Note:
1256:    This routine is used differently from Fortran 77
1257: $    Vec         x
1258: $    PetscScalar x_array(1)
1259: $    PetscOffset i_x
1260: $    PetscErrorCode ierr
1261: $       call VecGetArray(x,x_array,i_x,ierr)
1262: $
1263: $   Access first local entry in vector with
1264: $      value = x_array(i_x + 1)
1265: $
1266: $      ...... other code
1267: $       call VecRestoreArray(x,x_array,i_x,ierr)

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

1273: .seealso: VecGetArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(), VecRestoreArray2d()
1274: M*/
1277: PetscErrorCode VecRestoreArray_Private(Vec x,PetscScalar *a[])
1278: {

1285: #if defined(PETSC_USE_DEBUG)
1286:   CHKMEMQ;
1287: #endif
1288:   if (x->ops->restorearray) {
1289:     (*x->ops->restorearray)(x,a);
1290:   }
1291:   PetscObjectStateIncrease((PetscObject)x);
1292:   return(0);
1293: }


1298: /*@
1299:    VecPlaceArray - Allows one to replace the array in a vector with an
1300:    array provided by the user. This is useful to avoid copying an array
1301:    into a vector.

1303:    Not Collective

1305:    Input Parameters:
1306: +  vec - the vector
1307: -  array - the array

1309:    Notes:
1310:    You can return to the original array with a call to VecResetArray()

1312:    Level: developer

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

1316: @*/
1317: PetscErrorCode  VecPlaceArray(Vec vec,const PetscScalar array[])
1318: {

1325:   if (vec->ops->placearray) {
1326:     (*vec->ops->placearray)(vec,array);
1327:   } else {
1328:     SETERRQ(PETSC_ERR_SUP,"Cannot place array in this type of vector");
1329:   }
1330:   PetscObjectStateIncrease((PetscObject)vec);
1331:   return(0);
1332: }


1337: /*@C
1338:    VecReplaceArray - Allows one to replace the array in a vector with an
1339:    array provided by the user. This is useful to avoid copying an array
1340:    into a vector.

1342:    Not Collective

1344:    Input Parameters:
1345: +  vec - the vector
1346: -  array - the array

1348:    Notes:
1349:    This permanently replaces the array and frees the memory associated
1350:    with the old array.

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

1355:    Not supported from Fortran

1357:    Level: developer

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

1361: @*/
1362: PetscErrorCode  VecReplaceArray(Vec vec,const PetscScalar array[])
1363: {

1369:   if (vec->ops->replacearray) {
1370:     (*vec->ops->replacearray)(vec,array);
1371:  } else {
1372:     SETERRQ(PETSC_ERR_SUP,"Cannot replace array in this type of vector");
1373:   }
1374:   PetscObjectStateIncrease((PetscObject)vec);
1375:   return(0);
1376: }

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

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

1385:     Collective on Vec

1387:     Input Parameters:
1388: +   x - a vector to mimic
1389: -   n - the number of vectors to obtain

1391:     Output Parameters:
1392: +   y - Fortran90 pointer to the array of vectors
1393: -   ierr - error code

1395:     Example of Usage: 
1396: .vb
1397:     Vec x
1398:     Vec, pointer :: y(:)
1399:     ....
1400:     call VecDuplicateVecsF90(x,2,y,ierr)
1401:     call VecSet(y(2),alpha,ierr)
1402:     call VecSet(y(2),alpha,ierr)
1403:     ....
1404:     call VecDestroyVecsF90(y,2,ierr)
1405: .ve

1407:     Notes:
1408:     Not yet supported for all F90 compilers

1410:     Use VecDestroyVecsF90() to free the space.

1412:     Level: beginner

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

1416: M*/

1418: /*MC
1419:     VecRestoreArrayF90 - Restores a vector to a usable state after a call to
1420:     VecGetArrayF90().

1422:     Synopsis:
1423:     VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

1425:     Not collective

1427:     Input Parameters:
1428: +   x - vector
1429: -   xx_v - the Fortran90 pointer to the array

1431:     Output Parameter:
1432: .   ierr - error code

1434:     Example of Usage: 
1435: .vb
1436:     PetscScalar, pointer :: xx_v(:)
1437:     ....
1438:     call VecGetArrayF90(x,xx_v,ierr)
1439:     a = xx_v(3)
1440:     call VecRestoreArrayF90(x,xx_v,ierr)
1441: .ve
1442:    
1443:     Notes:
1444:     Not yet supported for all F90 compilers

1446:     Level: beginner

1448: .seealso:  VecGetArrayF90(), VecGetArray(), VecRestoreArray()

1450: M*/

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

1455:     Synopsis:
1456:     VecDestroyVecsF90({Vec, pointer :: x(:)},integer n,integer ierr)

1458:     Input Parameters:
1459: +   x - pointer to array of vector pointers
1460: -   n - the number of vectors previously obtained

1462:     Output Parameter:
1463: .   ierr - error code

1465:     Notes:
1466:     Not yet supported for all F90 compilers

1468:     Level: beginner

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

1472: M*/

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

1480:     Synopsis:
1481:     VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

1483:     Not Collective 

1485:     Input Parameter:
1486: .   x - vector

1488:     Output Parameters:
1489: +   xx_v - the Fortran90 pointer to the array
1490: -   ierr - error code

1492:     Example of Usage: 
1493: .vb
1494:     PetscScalar, pointer :: xx_v(:)
1495:     ....
1496:     call VecGetArrayF90(x,xx_v,ierr)
1497:     a = xx_v(3)
1498:     call VecRestoreArrayF90(x,xx_v,ierr)
1499: .ve

1501:     Notes:
1502:     Not yet supported for all F90 compilers

1504:     Level: beginner

1506: .seealso:  VecRestoreArrayF90(), VecGetArray(), VecRestoreArray()

1508: M*/


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

1518:    Not Collective

1520:    Input Parameter:
1521: +  x - the vector
1522: .  m - first dimension of two dimensional array
1523: .  n - second dimension of two dimensional array
1524: .  mstart - first index you will use in first coordinate direction (often 0)
1525: -  nstart - first index in the second coordinate direction (often 0)

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

1530:    Level: developer

1532:   Notes:
1533:    For a vector obtained from DACreateLocalVector() mstart and nstart are likely
1534:    obtained from the corner indices obtained from DAGetGhostCorners() while for
1535:    DACreateGlobalVector() they are the corner indices from DAGetCorners(). In both cases
1536:    the arguments from DAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
1537:    
1538:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

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

1542: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1543:           VecRestoreArray2d(), DAVecGetArray(), DAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1544:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1545: @*/
1546: PetscErrorCode  VecGetArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
1547: {
1549:   PetscInt       i,N;
1550:   PetscScalar    *aa;

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

1560:   PetscMalloc(m*sizeof(PetscScalar*),a);
1561:   for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
1562:   *a -= mstart;
1563:   return(0);
1564: }

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

1571:    Not Collective

1573:    Input Parameters:
1574: +  x - the vector
1575: .  m - first dimension of two dimensional array
1576: .  n - second dimension of the two dimensional array
1577: .  mstart - first index you will use in first coordinate direction (often 0)
1578: .  nstart - first index in the second coordinate direction (often 0)
1579: -  a - location of pointer to array obtained from VecGetArray2d()

1581:    Level: developer

1583:    Notes:
1584:    For regular PETSc vectors this routine does not involve any copies. For
1585:    any special vectors that do not store local vector data in a contiguous
1586:    array, this routine will copy the data back into the underlying 
1587:    vector data structure from the array obtained with VecGetArray().

1589:    This routine actually zeros out the a pointer. 

1591: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1592:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DAVecGetArray(), DAVecRestoreArray()
1593:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1594: @*/
1595: PetscErrorCode  VecRestoreArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
1596: {
1598:   void           *dummy;

1604:   dummy = (void*)(*a + mstart);
1605:   PetscFree(dummy);
1606:   VecRestoreArray(x,PETSC_NULL);
1607:   return(0);
1608: }

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

1617:    Not Collective

1619:    Input Parameter:
1620: +  x - the vector
1621: .  m - first dimension of two dimensional array
1622: -  mstart - first index you will use in first coordinate direction (often 0)

1624:    Output Parameter:
1625: .  a - location to put pointer to the array

1627:    Level: developer

1629:   Notes:
1630:    For a vector obtained from DACreateLocalVector() mstart are likely
1631:    obtained from the corner indices obtained from DAGetGhostCorners() while for
1632:    DACreateGlobalVector() they are the corner indices from DAGetCorners(). 
1633:    
1634:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

1636: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1637:           VecRestoreArray2d(), DAVecGetArray(), DAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1638:           VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1639: @*/
1640: PetscErrorCode  VecGetArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
1641: {
1643:   PetscInt       N;

1649:   VecGetLocalSize(x,&N);
1650:   if (m != N) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
1651:   VecGetArray(x,a);
1652:   *a  -= mstart;
1653:   return(0);
1654: }

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

1661:    Not Collective

1663:    Input Parameters:
1664: +  x - the vector
1665: .  m - first dimension of two dimensional array
1666: .  mstart - first index you will use in first coordinate direction (often 0)
1667: -  a - location of pointer to array obtained from VecGetArray21()

1669:    Level: developer

1671:    Notes:
1672:    For regular PETSc vectors this routine does not involve any copies. For
1673:    any special vectors that do not store local vector data in a contiguous
1674:    array, this routine will copy the data back into the underlying 
1675:    vector data structure from the array obtained with VecGetArray1d().

1677:    This routine actually zeros out the a pointer. 

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

1681: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1682:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DAVecGetArray(), DAVecRestoreArray()
1683:           VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
1684: @*/
1685: PetscErrorCode  VecRestoreArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
1686: {

1692:   VecRestoreArray(x,PETSC_NULL);
1693:   return(0);
1694: }


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

1704:    Not Collective

1706:    Input Parameter:
1707: +  x - the vector
1708: .  m - first dimension of three dimensional array
1709: .  n - second dimension of three dimensional array
1710: .  p - third dimension of three dimensional array
1711: .  mstart - first index you will use in first coordinate direction (often 0)
1712: .  nstart - first index in the second coordinate direction (often 0)
1713: -  pstart - first index in the third coordinate direction (often 0)

1715:    Output Parameter:
1716: .  a - location to put pointer to the array

1718:    Level: developer

1720:   Notes:
1721:    For a vector obtained from DACreateLocalVector() mstart, nstart, and pstart are likely
1722:    obtained from the corner indices obtained from DAGetGhostCorners() while for
1723:    DACreateGlobalVector() they are the corner indices from DAGetCorners(). In both cases
1724:    the arguments from DAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
1725:    
1726:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

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

1730: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1731:           VecRestoreArray2d(), DAVecGetarray(), DAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1732:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1733: @*/
1734: PetscErrorCode  VecGetArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
1735: {
1737:   PetscInt       i,N,j;
1738:   PetscScalar    *aa,**b;

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

1748:   PetscMalloc(m*sizeof(PetscScalar**)+m*n*sizeof(PetscScalar*),a);
1749:   b    = (PetscScalar **)((*a) + m);
1750:   for (i=0; i<m; i++)   (*a)[i] = b + i*n - nstart;
1751:   for (i=0; i<m; i++) {
1752:     for (j=0; j<n; j++) {
1753:       b[i*n+j] = aa + i*n*p + j*p - pstart;
1754:     }
1755:   }
1756:   *a -= mstart;
1757:   return(0);
1758: }

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

1765:    Not Collective

1767:    Input Parameters:
1768: +  x - the vector
1769: .  m - first dimension of three dimensional array
1770: .  n - second dimension of the three dimensional array
1771: .  p - third dimension of the three dimensional array
1772: .  mstart - first index you will use in first coordinate direction (often 0)
1773: .  nstart - first index in the second coordinate direction (often 0)
1774: .  pstart - first index in the third coordinate direction (often 0)
1775: -  a - location of pointer to array obtained from VecGetArray3d()

1777:    Level: developer

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

1785:    This routine actually zeros out the a pointer. 

1787: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1788:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DAVecGetArray(), DAVecRestoreArray()
1789:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
1790: @*/
1791: PetscErrorCode  VecRestoreArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
1792: {
1794:   void           *dummy;

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

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

1813:    Not Collective

1815:    Input Parameter:
1816: +  x - the vector
1817: .  m - first dimension of four dimensional array
1818: .  n - second dimension of four dimensional array
1819: .  p - third dimension of four dimensional array
1820: .  q - fourth dimension of four dimensional array
1821: .  mstart - first index you will use in first coordinate direction (often 0)
1822: .  nstart - first index in the second coordinate direction (often 0)
1823: .  pstart - first index in the third coordinate direction (often 0)
1824: -  qstart - first index in the fourth coordinate direction (often 0)

1826:    Output Parameter:
1827: .  a - location to put pointer to the array

1829:    Level: beginner

1831:   Notes:
1832:    For a vector obtained from DACreateLocalVector() mstart, nstart, and pstart are likely
1833:    obtained from the corner indices obtained from DAGetGhostCorners() while for
1834:    DACreateGlobalVector() they are the corner indices from DAGetCorners(). In both cases
1835:    the arguments from DAGet[Ghost}Corners() are reversed in the call to VecGetArray3d().
1836:    
1837:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

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

1841: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1842:           VecRestoreArray2d(), DAVecGetarray(), DAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1843:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1844: @*/
1845: PetscErrorCode  VecGetArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
1846: {
1848:   PetscInt       i,N,j,k;
1849:   PetscScalar    *aa,***b,**c;

1855:   VecGetLocalSize(x,&N);
1856:   if (m*n*p*q != N) SETERRQ5(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);
1857:   VecGetArray(x,&aa);

1859:   PetscMalloc(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p*sizeof(PetscScalar*),a);
1860:   b    = (PetscScalar ***)((*a) + m);
1861:   c    = (PetscScalar **)(b + m*n);
1862:   for (i=0; i<m; i++)   (*a)[i] = b + i*n - nstart;
1863:   for (i=0; i<m; i++) {
1864:     for (j=0; j<n; j++) {
1865:       b[i*n+j] = c + i*n*p + j*p - pstart;
1866:     }
1867:   }
1868:   for (i=0; i<m; i++) {
1869:     for (j=0; j<n; j++) {
1870:       for (k=0; k<p; k++) {
1871:         c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
1872:       }
1873:     }
1874:   }
1875:   *a -= mstart;
1876:   return(0);
1877: }

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

1884:    Not Collective

1886:    Input Parameters:
1887: +  x - the vector
1888: .  m - first dimension of four dimensional array
1889: .  n - second dimension of the four dimensional array
1890: .  p - third dimension of the four dimensional array
1891: .  q - fourth dimension of the four dimensional array
1892: .  mstart - first index you will use in first coordinate direction (often 0)
1893: .  nstart - first index in the second coordinate direction (often 0)
1894: .  pstart - first index in the third coordinate direction (often 0)
1895: .  qstart - first index in the fourth coordinate direction (often 0)
1896: -  a - location of pointer to array obtained from VecGetArray4d()

1898:    Level: beginner

1900:    Notes:
1901:    For regular PETSc vectors this routine does not involve any copies. For
1902:    any special vectors that do not store local vector data in a contiguous
1903:    array, this routine will copy the data back into the underlying 
1904:    vector data structure from the array obtained with VecGetArray().

1906:    This routine actually zeros out the a pointer. 

1908: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1909:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DAVecGetArray(), DAVecRestoreArray()
1910:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
1911: @*/
1912: PetscErrorCode  VecRestoreArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
1913: {
1915:   void           *dummy;

1921:   dummy = (void*)(*a + mstart);
1922:   PetscFree(dummy);
1923:   VecRestoreArray(x,PETSC_NULL);
1924:   return(0);
1925: }