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,((PetscObject)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:    Notes: x and y must be different vectors

485:    Concepts: vector^BLAS
486:    Concepts: BLAS

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

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

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

512: /*@
513:    VecAXPBY - Computes y = alpha x + beta y. 

515:    Collective on Vec

517:    Input Parameters:
518: +  alpha,beta - the scalars
519: -  x, y  - the vectors

521:    Output Parameter:
522: .  y - output vector

524:    Level: intermediate

526:    Notes: x and y must be different vectors 

528:    Concepts: BLAS
529:    Concepts: vector^BLAS

531: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY()
532: @*/
533: PetscErrorCode  VecAXPBY(Vec y,PetscScalar alpha,PetscScalar beta,Vec x)
534: {

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

547:   (*y->ops->axpby)(y,alpha,beta,x);
549:   PetscObjectStateIncrease((PetscObject)y);
550:   return(0);
551: }

555: /*@
556:    VecAYPX - Computes y = x + alpha y.

558:    Collective on Vec

560:    Input Parameters:
561: +  alpha - the scalar
562: -  x, y  - the vectors

564:    Output Parameter:
565: .  y - output vector

567:    Level: intermediate

569:    Notes: x and y must be different vectors

571:    Concepts: vector^BLAS
572:    Concepts: BLAS

574: .seealso: VecAXPY(), VecWAXPY()
575: @*/
576: PetscErrorCode  VecAYPX(Vec y,PetscScalar alpha,Vec x)
577: {

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

590:    (*y->ops->aypx)(y,alpha,x);
592:   PetscObjectStateIncrease((PetscObject)y);
593:   return(0);
594: }


599: /*@
600:    VecWAXPY - Computes w = alpha x + y.

602:    Collective on Vec

604:    Input Parameters:
605: +  alpha - the scalar
606: -  x, y  - the vectors

608:    Output Parameter:
609: .  w - the result

611:    Level: intermediate

613:    Notes: Neither the vector x or y can be the same as vector w

615:    Concepts: vector^BLAS
616:    Concepts: BLAS

618: .seealso: VecAXPY(), VecAYPX(), VecAXPBY()
619: @*/
620: PetscErrorCode  VecWAXPY(Vec w,PetscScalar alpha,Vec x,Vec y)
621: {

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

637:    (*w->ops->waxpy)(w,alpha,x,y);
639:   PetscObjectStateIncrease((PetscObject)w);
640:   return(0);
641: }


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

649:    Not Collective

651:    Input Parameters:
652: +  x - vector to insert in
653: .  ni - number of elements to add
654: .  ix - indices where to add
655: .  y - array of values
656: -  iora - either INSERT_VALUES or ADD_VALUES, where
657:    ADD_VALUES adds values to any existing entries, and
658:    INSERT_VALUES replaces existing entries with new values

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

663:    Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES 
664:    options cannot be mixed without intervening calls to the assembly
665:    routines.

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

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

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

678:    Level: beginner

680:    Concepts: vector^setting values

682: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesLocal(),
683:            VecSetValue(), VecSetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecGetValues()
684: @*/
685: PetscErrorCode  VecSetValues(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
686: {

695:   (*x->ops->setvalues)(x,ni,ix,y,iora);
697:   PetscObjectStateIncrease((PetscObject)x);
698:   return(0);
699: }

703: /*@
704:    VecGetValues - Gets values from certain locations of a vector. Currently 
705:           can only get values on the same processor

707:     Collective on Vec
708:  
709:    Input Parameters:
710: +  x - vector to get values from
711: .  ni - number of elements to get
712: -  ix - indices where to get them from (in global 1d numbering)

714:    Output Parameter:
715: .   y - array of values

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

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

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

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

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

730:    Level: beginner

732:    Concepts: vector^getting values

734: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecGetValuesLocal(),
735:            VecGetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecSetValues()
736: @*/
737: PetscErrorCode  VecGetValues(Vec x,PetscInt ni,const PetscInt ix[],PetscScalar y[])
738: {

746:   (*x->ops->getvalues)(x,ni,ix,y);
747:   return(0);
748: }

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

755:    Not Collective

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

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

770:    Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 
771:    options cannot be mixed without intervening calls to the assembly
772:    routines.

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

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

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

784:    Level: intermediate

786:    Concepts: vector^setting values blocked

788: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesBlockedLocal(),
789:            VecSetValues()
790: @*/
791: PetscErrorCode  VecSetValuesBlocked(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
792: {

801:   (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);
803:   PetscObjectStateIncrease((PetscObject)x);
804:   return(0);
805: }


810: /*@
811:    VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
812:    using a local ordering of the nodes. 

814:    Not Collective

816:    Input Parameters:
817: +  x - vector to insert in
818: .  ni - number of elements to add
819: .  ix - indices where to add
820: .  y - array of values
821: -  iora - either INSERT_VALUES or ADD_VALUES, where
822:    ADD_VALUES adds values to any existing entries, and
823:    INSERT_VALUES replaces existing entries with new values

825:    Level: intermediate

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

830:    Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES 
831:    options cannot be mixed without intervening calls to the assembly
832:    routines.

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

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

839:    Concepts: vector^setting values with local numbering

841: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetLocalToGlobalMapping(),
842:            VecSetValuesBlockedLocal()
843: @*/
844: PetscErrorCode  VecSetValuesLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
845: {
847:   PetscInt       lixp[128],*lix = lixp;


856:   if (!x->ops->setvalueslocal) {
857:     if (!x->mapping) {
858:       SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMapping()");
859:     }
860:     if (ni > 128) {
861:       PetscMalloc(ni*sizeof(PetscInt),&lix);
862:     }
863:     ISLocalToGlobalMappingApply(x->mapping,ni,(PetscInt*)ix,lix);
864:     (*x->ops->setvalues)(x,ni,lix,y,iora);
865:     if (ni > 128) {
866:       PetscFree(lix);
867:     }
868:   } else {
869:     (*x->ops->setvalueslocal)(x,ni,ix,y,iora);
870:   }
872:   PetscObjectStateIncrease((PetscObject)x);
873:   return(0);
874: }

878: /*@
879:    VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
880:    using a local ordering of the nodes. 

882:    Not Collective

884:    Input Parameters:
885: +  x - vector to insert in
886: .  ni - number of blocks to add
887: .  ix - indices where to add in block count, not element count
888: .  y - array of values
889: -  iora - either INSERT_VALUES or ADD_VALUES, where
890:    ADD_VALUES adds values to any existing entries, and
891:    INSERT_VALUES replaces existing entries with new values

893:    Level: intermediate

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

899:    Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 
900:    options cannot be mixed without intervening calls to the assembly
901:    routines.

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

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


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

911: .seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesBlocked(), 
912:            VecSetLocalToGlobalMappingBlock()
913: @*/
914: PetscErrorCode  VecSetValuesBlockedLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
915: {
917:   PetscInt       lixp[128],*lix = lixp;

924:   if (!x->bmapping) {
925:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMappingBlock()");
926:   }
927:   if (ni > 128) {
928:     PetscMalloc(ni*sizeof(PetscInt),&lix);
929:   }

932:   ISLocalToGlobalMappingApply(x->bmapping,ni,(PetscInt*)ix,lix);
933:   (*x->ops->setvaluesblocked)(x,ni,lix,y,iora);
935:   if (ni > 128) {
936:     PetscFree(lix);
937:   }
938:   PetscObjectStateIncrease((PetscObject)x);
939:   return(0);
940: }



946: /*@
947:    VecMTDot - Computes indefinite vector multiple dot products. 
948:    That is, it does NOT use the complex conjugate.

950:    Collective on Vec

952:    Input Parameters:
953: +  x - one vector
954: .  nv - number of vectors
955: -  y - array of vectors.  Note that vectors are pointers

957:    Output Parameter:
958: .  val - array of the dot products

960:    Notes for Users of Complex Numbers:
961:    For complex vectors, VecMTDot() computes the indefinite form
962: $      val = (x,y) = y^T x,
963:    where y^T denotes the transpose of y.

965:    Use VecMDot() for the inner product
966: $      val = (x,y) = y^H x,
967:    where y^H denotes the conjugate transpose of y.

969:    Level: intermediate

971:    Concepts: inner product^multiple
972:    Concepts: vector^multiple inner products

974: .seealso: VecMDot(), VecTDot()
975: @*/
976: PetscErrorCode  VecMTDot(Vec x,PetscInt nv,const Vec y[],PetscScalar *val)
977: {

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

992:   (*x->ops->mtdot)(x,nv,y,val);
994:   return(0);
995: }

999: /*@
1000:    VecMDot - Computes vector multiple dot products. 

1002:    Collective on Vec

1004:    Input Parameters:
1005: +  x - one vector
1006: .  nv - number of vectors
1007: -  y - array of vectors. 

1009:    Output Parameter:
1010: .  val - array of the dot products

1012:    Notes for Users of Complex Numbers:
1013:    For complex vectors, VecMDot() computes 
1014: $     val = (x,y) = y^H x,
1015:    where y^H denotes the conjugate transpose of y.

1017:    Use VecMTDot() for the indefinite form
1018: $     val = (x,y) = y^T x,
1019:    where y^T denotes the transpose of y.

1021:    Level: intermediate

1023:    Concepts: inner product^multiple
1024:    Concepts: vector^multiple inner products

1026: .seealso: VecMTDot(), VecDot()
1027: @*/
1028: PetscErrorCode  VecMDot(Vec x,PetscInt nv,const Vec y[],PetscScalar *val)
1029: {

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

1046:   (*x->ops->mdot)(x,nv,y,val);
1048:   return(0);
1049: }

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

1056:    Collective on Vec

1058:    Input Parameters:
1059: +  nv - number of scalars and x-vectors
1060: .  alpha - array of scalars
1061: .  y - one vector
1062: -  x - array of vectors

1064:    Level: intermediate

1066:    Concepts: BLAS

1068: .seealso: VecAXPY(), VecWAXPY(), VecAYPX()
1069: @*/
1070: PetscErrorCode  VecMAXPY(Vec y,PetscInt nv,const PetscScalar alpha[],Vec *x)
1071: {

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

1088:   (*y->ops->maxpy)(y,nv,alpha,x);
1090:   PetscObjectStateIncrease((PetscObject)y);
1091:   return(0);
1092: }

1094: /*MC
1095:    VecGetArray - Returns a pointer to a contiguous array that contains this 
1096:    processor's portion of the vector data. For the standard PETSc
1097:    vectors, VecGetArray() returns a pointer to the local data array and
1098:    does not use any copies. If the underlying vector data is not stored
1099:    in a contiquous array this routine will copy the data to a contiquous
1100:    array and return a pointer to that. You MUST call VecRestoreArray() 
1101:    when you no longer need access to the array.

1103:    Synopsis:
1104:    PetscErrorCode VecGetArray(Vec x,PetscScalar *a[])

1106:    Not Collective

1108:    Input Parameter:
1109: .  x - the vector

1111:    Output Parameter:
1112: .  a - location to put pointer to the array

1114:    Fortran Note:
1115:    This routine is used differently from Fortran 77
1116: $    Vec         x
1117: $    PetscScalar x_array(1)
1118: $    PetscOffset i_x
1119: $    PetscErrorCode ierr
1120: $       call VecGetArray(x,x_array,i_x,ierr)
1121: $
1122: $   Access first local entry in vector with
1123: $      value = x_array(i_x + 1)
1124: $
1125: $      ...... other code
1126: $       call VecRestoreArray(x,x_array,i_x,ierr)
1127:    For Fortran 90 see VecGetArrayF90()

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

1132:    Level: beginner

1134:    Concepts: vector^accessing local values

1136: .seealso: VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(), VecGetArray2d()
1137: M*/
1140: PetscErrorCode VecGetArray_Private(Vec x,PetscScalar *a[])
1141: {

1148:   (*x->ops->getarray)(x,a);
1149:   return(0);
1150: }


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

1160:    Not Collective

1162:    Input Parameter:
1163: +  x - the vectors
1164: -  n - the number of vectors

1166:    Output Parameter:
1167: .  a - location to put pointer to the array

1169:    Fortran Note:
1170:    This routine is not supported in Fortran.

1172:    Level: intermediate

1174: .seealso: VecGetArray(), VecRestoreArrays()
1175: @*/
1176: PetscErrorCode  VecGetArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1177: {
1179:   PetscInt       i;
1180:   PetscScalar    **q;

1186:   if (n <= 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must get at least one array n = %D",n);
1187:   PetscMalloc(n*sizeof(PetscScalar*),&q);
1188:   for (i=0; i<n; ++i) {
1189:     VecGetArray(x[i],&q[i]);
1190:   }
1191:   *a = q;
1192:   return(0);
1193: }

1197: /*@C
1198:    VecRestoreArrays - Restores a group of vectors after VecGetArrays()
1199:    has been called.

1201:    Not Collective

1203:    Input Parameters:
1204: +  x - the vector
1205: .  n - the number of vectors
1206: -  a - location of pointer to arrays obtained from VecGetArrays()

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

1214:    Fortran Note:
1215:    This routine is not supported in Fortran.

1217:    Level: intermediate

1219: .seealso: VecGetArrays(), VecRestoreArray()
1220: @*/
1221: PetscErrorCode  VecRestoreArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1222: {
1224:   PetscInt       i;
1225:   PetscScalar    **q = *a;


1232:   for(i=0;i<n;++i) {
1233:     VecRestoreArray(x[i],&q[i]);
1234:  }
1235:   PetscFree(q);
1236:   return(0);
1237: }

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

1242:    Not Collective

1244:    Synopsis:
1245:    PetscErrorCode VecRestoreArray(Vec x,PetscScalar *a[])

1247:    Input Parameters:
1248: +  x - the vector
1249: -  a - location of pointer to array obtained from VecGetArray()

1251:    Level: beginner

1253:    Notes:
1254:    For regular PETSc vectors this routine does not involve any copies. For
1255:    any special vectors that do not store local vector data in a contiguous
1256:    array, this routine will copy the data back into the underlying 
1257:    vector data structure from the array obtained with VecGetArray().

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

1263:    Fortran Note:
1264:    This routine is used differently from Fortran 77
1265: $    Vec         x
1266: $    PetscScalar x_array(1)
1267: $    PetscOffset i_x
1268: $    PetscErrorCode ierr
1269: $       call VecGetArray(x,x_array,i_x,ierr)
1270: $
1271: $   Access first local entry in vector with
1272: $      value = x_array(i_x + 1)
1273: $
1274: $      ...... other code
1275: $       call VecRestoreArray(x,x_array,i_x,ierr)

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

1281: .seealso: VecGetArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(), VecRestoreArray2d()
1282: M*/
1285: PetscErrorCode VecRestoreArray_Private(Vec x,PetscScalar *a[])
1286: {

1293: #if defined(PETSC_USE_DEBUG)
1294:   CHKMEMQ;
1295: #endif
1296:   if (x->ops->restorearray) {
1297:     (*x->ops->restorearray)(x,a);
1298:   }
1299:   PetscObjectStateIncrease((PetscObject)x);
1300:   return(0);
1301: }


1306: /*@
1307:    VecPlaceArray - Allows one to replace the array in a vector with an
1308:    array provided by the user. This is useful to avoid copying an array
1309:    into a vector.

1311:    Not Collective

1313:    Input Parameters:
1314: +  vec - the vector
1315: -  array - the array

1317:    Notes:
1318:    You can return to the original array with a call to VecResetArray()

1320:    Level: developer

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

1324: @*/
1325: PetscErrorCode  VecPlaceArray(Vec vec,const PetscScalar array[])
1326: {

1333:   if (vec->ops->placearray) {
1334:     (*vec->ops->placearray)(vec,array);
1335:   } else {
1336:     SETERRQ(PETSC_ERR_SUP,"Cannot place array in this type of vector");
1337:   }
1338:   PetscObjectStateIncrease((PetscObject)vec);
1339:   return(0);
1340: }


1345: /*@C
1346:    VecReplaceArray - Allows one to replace the array in a vector with an
1347:    array provided by the user. This is useful to avoid copying an array
1348:    into a vector.

1350:    Not Collective

1352:    Input Parameters:
1353: +  vec - the vector
1354: -  array - the array

1356:    Notes:
1357:    This permanently replaces the array and frees the memory associated
1358:    with the old array.

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

1363:    Not supported from Fortran

1365:    Level: developer

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

1369: @*/
1370: PetscErrorCode  VecReplaceArray(Vec vec,const PetscScalar array[])
1371: {

1377:   if (vec->ops->replacearray) {
1378:     (*vec->ops->replacearray)(vec,array);
1379:  } else {
1380:     SETERRQ(PETSC_ERR_SUP,"Cannot replace array in this type of vector");
1381:   }
1382:   PetscObjectStateIncrease((PetscObject)vec);
1383:   return(0);
1384: }

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

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

1393:     Collective on Vec

1395:     Input Parameters:
1396: +   x - a vector to mimic
1397: -   n - the number of vectors to obtain

1399:     Output Parameters:
1400: +   y - Fortran90 pointer to the array of vectors
1401: -   ierr - error code

1403:     Example of Usage: 
1404: .vb
1405:     Vec x
1406:     Vec, pointer :: y(:)
1407:     ....
1408:     call VecDuplicateVecsF90(x,2,y,ierr)
1409:     call VecSet(y(2),alpha,ierr)
1410:     call VecSet(y(2),alpha,ierr)
1411:     ....
1412:     call VecDestroyVecsF90(y,2,ierr)
1413: .ve

1415:     Notes:
1416:     Not yet supported for all F90 compilers

1418:     Use VecDestroyVecsF90() to free the space.

1420:     Level: beginner

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

1424: M*/

1426: /*MC
1427:     VecRestoreArrayF90 - Restores a vector to a usable state after a call to
1428:     VecGetArrayF90().

1430:     Synopsis:
1431:     VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

1433:     Not collective

1435:     Input Parameters:
1436: +   x - vector
1437: -   xx_v - the Fortran90 pointer to the array

1439:     Output Parameter:
1440: .   ierr - error code

1442:     Example of Usage: 
1443: .vb
1444:     PetscScalar, pointer :: xx_v(:)
1445:     ....
1446:     call VecGetArrayF90(x,xx_v,ierr)
1447:     a = xx_v(3)
1448:     call VecRestoreArrayF90(x,xx_v,ierr)
1449: .ve
1450:    
1451:     Notes:
1452:     Not yet supported for all F90 compilers

1454:     Level: beginner

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

1458: M*/

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

1463:     Synopsis:
1464:     VecDestroyVecsF90({Vec, pointer :: x(:)},integer n,integer ierr)

1466:     Input Parameters:
1467: +   x - pointer to array of vector pointers
1468: -   n - the number of vectors previously obtained

1470:     Output Parameter:
1471: .   ierr - error code

1473:     Notes:
1474:     Not yet supported for all F90 compilers

1476:     Level: beginner

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

1480: M*/

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

1488:     Synopsis:
1489:     VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)

1491:     Not Collective 

1493:     Input Parameter:
1494: .   x - vector

1496:     Output Parameters:
1497: +   xx_v - the Fortran90 pointer to the array
1498: -   ierr - error code

1500:     Example of Usage: 
1501: .vb
1502:     PetscScalar, pointer :: xx_v(:)
1503:     ....
1504:     call VecGetArrayF90(x,xx_v,ierr)
1505:     a = xx_v(3)
1506:     call VecRestoreArrayF90(x,xx_v,ierr)
1507: .ve

1509:     Notes:
1510:     Not yet supported for all F90 compilers

1512:     Level: beginner

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

1516: M*/


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

1526:    Not Collective

1528:    Input Parameter:
1529: +  x - the vector
1530: .  m - first dimension of two dimensional array
1531: .  n - second dimension of two dimensional array
1532: .  mstart - first index you will use in first coordinate direction (often 0)
1533: -  nstart - first index in the second coordinate direction (often 0)

1535:    Output Parameter:
1536: .  a - location to put pointer to the array

1538:    Level: developer

1540:   Notes:
1541:    For a vector obtained from DACreateLocalVector() mstart and nstart are likely
1542:    obtained from the corner indices obtained from DAGetGhostCorners() while for
1543:    DACreateGlobalVector() they are the corner indices from DAGetCorners(). In both cases
1544:    the arguments from DAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
1545:    
1546:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

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

1550: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1551:           VecRestoreArray2d(), DAVecGetArray(), DAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1552:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1553: @*/
1554: PetscErrorCode  VecGetArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
1555: {
1557:   PetscInt       i,N;
1558:   PetscScalar    *aa;

1564:   VecGetLocalSize(x,&N);
1565:   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);
1566:   VecGetArray(x,&aa);

1568:   PetscMalloc(m*sizeof(PetscScalar*),a);
1569:   for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
1570:   *a -= mstart;
1571:   return(0);
1572: }

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

1579:    Not Collective

1581:    Input Parameters:
1582: +  x - the vector
1583: .  m - first dimension of two dimensional array
1584: .  n - second dimension of the two dimensional array
1585: .  mstart - first index you will use in first coordinate direction (often 0)
1586: .  nstart - first index in the second coordinate direction (often 0)
1587: -  a - location of pointer to array obtained from VecGetArray2d()

1589:    Level: developer

1591:    Notes:
1592:    For regular PETSc vectors this routine does not involve any copies. For
1593:    any special vectors that do not store local vector data in a contiguous
1594:    array, this routine will copy the data back into the underlying 
1595:    vector data structure from the array obtained with VecGetArray().

1597:    This routine actually zeros out the a pointer. 

1599: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1600:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DAVecGetArray(), DAVecRestoreArray()
1601:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1602: @*/
1603: PetscErrorCode  VecRestoreArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
1604: {
1606:   void           *dummy;

1612:   dummy = (void*)(*a + mstart);
1613:   PetscFree(dummy);
1614:   VecRestoreArray(x,PETSC_NULL);
1615:   return(0);
1616: }

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

1625:    Not Collective

1627:    Input Parameter:
1628: +  x - the vector
1629: .  m - first dimension of two dimensional array
1630: -  mstart - first index you will use in first coordinate direction (often 0)

1632:    Output Parameter:
1633: .  a - location to put pointer to the array

1635:    Level: developer

1637:   Notes:
1638:    For a vector obtained from DACreateLocalVector() mstart are likely
1639:    obtained from the corner indices obtained from DAGetGhostCorners() while for
1640:    DACreateGlobalVector() they are the corner indices from DAGetCorners(). 
1641:    
1642:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

1644: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1645:           VecRestoreArray2d(), DAVecGetArray(), DAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1646:           VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1647: @*/
1648: PetscErrorCode  VecGetArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
1649: {
1651:   PetscInt       N;

1657:   VecGetLocalSize(x,&N);
1658:   if (m != N) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
1659:   VecGetArray(x,a);
1660:   *a  -= mstart;
1661:   return(0);
1662: }

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

1669:    Not Collective

1671:    Input Parameters:
1672: +  x - the vector
1673: .  m - first dimension of two dimensional array
1674: .  mstart - first index you will use in first coordinate direction (often 0)
1675: -  a - location of pointer to array obtained from VecGetArray21()

1677:    Level: developer

1679:    Notes:
1680:    For regular PETSc vectors this routine does not involve any copies. For
1681:    any special vectors that do not store local vector data in a contiguous
1682:    array, this routine will copy the data back into the underlying 
1683:    vector data structure from the array obtained with VecGetArray1d().

1685:    This routine actually zeros out the a pointer. 

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

1689: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1690:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DAVecGetArray(), DAVecRestoreArray()
1691:           VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
1692: @*/
1693: PetscErrorCode  VecRestoreArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
1694: {

1700:   VecRestoreArray(x,PETSC_NULL);
1701:   return(0);
1702: }


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

1712:    Not Collective

1714:    Input Parameter:
1715: +  x - the vector
1716: .  m - first dimension of three dimensional array
1717: .  n - second dimension of three dimensional array
1718: .  p - third dimension of three dimensional array
1719: .  mstart - first index you will use in first coordinate direction (often 0)
1720: .  nstart - first index in the second coordinate direction (often 0)
1721: -  pstart - first index in the third coordinate direction (often 0)

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

1726:    Level: developer

1728:   Notes:
1729:    For a vector obtained from DACreateLocalVector() mstart, nstart, and pstart are likely
1730:    obtained from the corner indices obtained from DAGetGhostCorners() while for
1731:    DACreateGlobalVector() they are the corner indices from DAGetCorners(). In both cases
1732:    the arguments from DAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
1733:    
1734:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

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

1738: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1739:           VecRestoreArray2d(), DAVecGetarray(), DAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1740:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1741: @*/
1742: PetscErrorCode  VecGetArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
1743: {
1745:   PetscInt       i,N,j;
1746:   PetscScalar    *aa,**b;

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

1756:   PetscMalloc(m*sizeof(PetscScalar**)+m*n*sizeof(PetscScalar*),a);
1757:   b    = (PetscScalar **)((*a) + m);
1758:   for (i=0; i<m; i++)   (*a)[i] = b + i*n - nstart;
1759:   for (i=0; i<m; i++) {
1760:     for (j=0; j<n; j++) {
1761:       b[i*n+j] = aa + i*n*p + j*p - pstart;
1762:     }
1763:   }
1764:   *a -= mstart;
1765:   return(0);
1766: }

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

1773:    Not Collective

1775:    Input Parameters:
1776: +  x - the vector
1777: .  m - first dimension of three dimensional array
1778: .  n - second dimension of the three dimensional array
1779: .  p - third dimension of the three dimensional array
1780: .  mstart - first index you will use in first coordinate direction (often 0)
1781: .  nstart - first index in the second coordinate direction (often 0)
1782: .  pstart - first index in the third coordinate direction (often 0)
1783: -  a - location of pointer to array obtained from VecGetArray3d()

1785:    Level: developer

1787:    Notes:
1788:    For regular PETSc vectors this routine does not involve any copies. For
1789:    any special vectors that do not store local vector data in a contiguous
1790:    array, this routine will copy the data back into the underlying 
1791:    vector data structure from the array obtained with VecGetArray().

1793:    This routine actually zeros out the a pointer. 

1795: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1796:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DAVecGetArray(), DAVecRestoreArray()
1797:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
1798: @*/
1799: PetscErrorCode  VecRestoreArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
1800: {
1802:   void           *dummy;

1808:   dummy = (void*)(*a + mstart);
1809:   PetscFree(dummy);
1810:   VecRestoreArray(x,PETSC_NULL);
1811:   return(0);
1812: }

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

1821:    Not Collective

1823:    Input Parameter:
1824: +  x - the vector
1825: .  m - first dimension of four dimensional array
1826: .  n - second dimension of four dimensional array
1827: .  p - third dimension of four dimensional array
1828: .  q - fourth dimension of four dimensional array
1829: .  mstart - first index you will use in first coordinate direction (often 0)
1830: .  nstart - first index in the second coordinate direction (often 0)
1831: .  pstart - first index in the third coordinate direction (often 0)
1832: -  qstart - first index in the fourth coordinate direction (often 0)

1834:    Output Parameter:
1835: .  a - location to put pointer to the array

1837:    Level: beginner

1839:   Notes:
1840:    For a vector obtained from DACreateLocalVector() mstart, nstart, and pstart are likely
1841:    obtained from the corner indices obtained from DAGetGhostCorners() while for
1842:    DACreateGlobalVector() they are the corner indices from DAGetCorners(). In both cases
1843:    the arguments from DAGet[Ghost}Corners() are reversed in the call to VecGetArray3d().
1844:    
1845:    For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.

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

1849: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1850:           VecRestoreArray2d(), DAVecGetarray(), DAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1851:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1852: @*/
1853: PetscErrorCode  VecGetArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
1854: {
1856:   PetscInt       i,N,j,k;
1857:   PetscScalar    *aa,***b,**c;

1863:   VecGetLocalSize(x,&N);
1864:   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);
1865:   VecGetArray(x,&aa);

1867:   PetscMalloc(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p*sizeof(PetscScalar*),a);
1868:   b    = (PetscScalar ***)((*a) + m);
1869:   c    = (PetscScalar **)(b + m*n);
1870:   for (i=0; i<m; i++)   (*a)[i] = b + i*n - nstart;
1871:   for (i=0; i<m; i++) {
1872:     for (j=0; j<n; j++) {
1873:       b[i*n+j] = c + i*n*p + j*p - pstart;
1874:     }
1875:   }
1876:   for (i=0; i<m; i++) {
1877:     for (j=0; j<n; j++) {
1878:       for (k=0; k<p; k++) {
1879:         c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
1880:       }
1881:     }
1882:   }
1883:   *a -= mstart;
1884:   return(0);
1885: }

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

1892:    Not Collective

1894:    Input Parameters:
1895: +  x - the vector
1896: .  m - first dimension of four dimensional array
1897: .  n - second dimension of the four dimensional array
1898: .  p - third dimension of the four dimensional array
1899: .  q - fourth dimension of the four dimensional array
1900: .  mstart - first index you will use in first coordinate direction (often 0)
1901: .  nstart - first index in the second coordinate direction (often 0)
1902: .  pstart - first index in the third coordinate direction (often 0)
1903: .  qstart - first index in the fourth coordinate direction (often 0)
1904: -  a - location of pointer to array obtained from VecGetArray4d()

1906:    Level: beginner

1908:    Notes:
1909:    For regular PETSc vectors this routine does not involve any copies. For
1910:    any special vectors that do not store local vector data in a contiguous
1911:    array, this routine will copy the data back into the underlying 
1912:    vector data structure from the array obtained with VecGetArray().

1914:    This routine actually zeros out the a pointer. 

1916: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1917:           VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DAVecGetArray(), DAVecRestoreArray()
1918:           VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
1919: @*/
1920: PetscErrorCode  VecRestoreArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
1921: {
1923:   void           *dummy;

1929:   dummy = (void*)(*a + mstart);
1930:   PetscFree(dummy);
1931:   VecRestoreArray(x,PETSC_NULL);
1932:   return(0);
1933: }