Actual source code: rvector.c
petsc-dev 2014-02-02
2: /*
3: Provides the interface functions for vector operations that have PetscScalar/PetscReal in the signature
4: These are the vector functions the user calls.
5: */
6: #include <petsc-private/vecimpl.h> /*I "petscvec.h" I*/
7: static PetscInt VecGetSubVectorSavedStateId = -1;
10: if ((x)->map->N != (y)->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths %d != %d", (x)->map->N, (y)->map->N); \
11: if ((x)->map->n != (y)->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths %d != %d", (x)->map->n, (y)->map->n);
15: PETSC_EXTERN PetscErrorCode VecValidValues(Vec vec,PetscInt argnum,PetscBool begin)
16: {
17: #if defined(PETSC_USE_DEBUG)
18: PetscErrorCode ierr;
19: PetscInt n,i;
20: const PetscScalar *x;
23: #if defined(PETSC_HAVE_CUSP)
24: if ((vec->petscnative || vec->ops->getarray) && vec->valid_GPU_array != PETSC_CUSP_GPU) {
25: #else
26: if (vec->petscnative || vec->ops->getarray) {
27: #endif
28: VecGetLocalSize(vec,&n);
29: VecGetArrayRead(vec,&x);
30: for (i=0; i<n; i++) {
31: if (begin) {
32: if (PetscIsInfOrNanScalar(x[i])) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FP,"Vec entry at local location %D is not-a-number or infinite at beginning of function: Parameter number %D",i,argnum);
33: } else {
34: if (PetscIsInfOrNanScalar(x[i])) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FP,"Vec entry at local location %D is not-a-number or infinite at end of function: Parameter number %D",i,argnum);
35: }
36: }
37: VecRestoreArrayRead(vec,&x);
38: }
39: return(0);
40: #else
41: return 0;
42: #endif
43: }
47: /*@
48: VecMaxPointwiseDivide - Computes the maximum of the componentwise division max = max_i abs(x_i/y_i).
50: Logically Collective on Vec
52: Input Parameters:
53: . x, y - the vectors
55: Output Parameter:
56: . max - the result
58: Level: advanced
60: Notes: x and y may be the same vector
61: if a particular y_i is zero, it is treated as 1 in the above formula
63: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs()
64: @*/
65: PetscErrorCode VecMaxPointwiseDivide(Vec x,Vec y,PetscReal *max)
66: {
78: (*x->ops->maxpointwisedivide)(x,y,max);
79: return(0);
80: }
84: /*@
85: VecDot - Computes the vector dot product.
87: Collective on Vec
89: Input Parameters:
90: . x, y - the vectors
92: Output Parameter:
93: . val - the dot product
95: Performance Issues:
96: $ per-processor memory bandwidth
97: $ interprocessor latency
98: $ work load inbalance that causes certain processes to arrive much earlier than others
100: Notes for Users of Complex Numbers:
101: For complex vectors, VecDot() computes
102: $ val = (x,y) = y^H x,
103: where y^H denotes the conjugate transpose of y. Note that this corresponds to the usual "mathematicians" complex
104: inner product where the SECOND argument gets the complex conjugate. Since the BLASdot() complex conjugates the first
105: first argument we call the BLASdot() with the arguments reversed.
107: Use VecTDot() for the indefinite form
108: $ val = (x,y) = y^T x,
109: where y^T denotes the transpose of y.
111: Level: intermediate
113: Concepts: inner product
114: Concepts: vector^inner product
116: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecDotRealPart()
117: @*/
118: PetscErrorCode VecDot(Vec x,Vec y,PetscScalar *val)
119: {
131: PetscLogEventBarrierBegin(VEC_DotBarrier,x,y,0,0,PetscObjectComm((PetscObject)x));
132: (*x->ops->dot)(x,y,val);
133: PetscLogEventBarrierEnd(VEC_DotBarrier,x,y,0,0,PetscObjectComm((PetscObject)x));
134: return(0);
135: }
139: /*@
140: VecDotRealPart - Computes the real part of the vector dot product.
142: Collective on Vec
144: Input Parameters:
145: . x, y - the vectors
147: Output Parameter:
148: . val - the real part of the dot product;
150: Performance Issues:
151: $ per-processor memory bandwidth
152: $ interprocessor latency
153: $ work load inbalance that causes certain processes to arrive much earlier than others
155: Notes for Users of Complex Numbers:
156: See VecDot() for more details on the definition of the dot product for complex numbers
158: For real numbers this returns the same value as VecDot()
160: For complex numbers in C^n (that is a vector of n components with a complex number for each component) this is equal to the usual real dot product on the
161: the space R^{2n} (that is a vector of 2n components with the real or imaginary part of the complex numbers for components)
163: Developer Note: This is not currently optimized to compute only the real part of the dot product.
165: Level: intermediate
167: Concepts: inner product
168: Concepts: vector^inner product
170: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecDot(), VecDotNorm2()
171: @*/
172: PetscErrorCode VecDotRealPart(Vec x,Vec y,PetscReal *val)
173: {
175: PetscScalar fdot;
178: VecDot(x,y,&fdot);
179: *val = PetscRealPart(fdot);
180: return(0);
181: }
185: /*@
186: VecNorm - Computes the vector norm.
188: Collective on Vec
190: Input Parameters:
191: + x - the vector
192: - type - one of NORM_1, NORM_2, NORM_INFINITY. Also available
193: NORM_1_AND_2, which computes both norms and stores them
194: in a two element array.
196: Output Parameter:
197: . val - the norm
199: Notes:
200: $ NORM_1 denotes sum_i |x_i|
201: $ NORM_2 denotes sqrt(sum_i (x_i)^2)
202: $ NORM_INFINITY denotes max_i |x_i|
204: Level: intermediate
206: Performance Issues:
207: $ per-processor memory bandwidth
208: $ interprocessor latency
209: $ work load inbalance that causes certain processes to arrive much earlier than others
211: Compile Option:
212: PETSC_HAVE_SLOW_BLAS_NORM2 will cause a C (loop unrolled) version of the norm to be used, rather
213: than the BLAS. This should probably only be used when one is using the FORTRAN BLAS routines
214: (as opposed to vendor provided) because the FORTRAN BLAS NRM2() routine is very slow.
216: Concepts: norm
217: Concepts: vector^norm
219: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNormAvailable(),
220: VecNormBegin(), VecNormEnd()
222: @*/
223: PetscErrorCode VecNorm(Vec x,NormType type,PetscReal *val)
224: {
225: PetscBool flg;
232: if (((PetscObject)x)->precision != sizeof(PetscReal)) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Wrong precision of input argument");
234: /*
235: * Cached data?
236: */
237: if (type!=NORM_1_AND_2) {
238: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,flg);
239: if (flg) return(0);
240: }
241: PetscLogEventBarrierBegin(VEC_NormBarrier,x,0,0,0,PetscObjectComm((PetscObject)x));
242: (*x->ops->norm)(x,type,val);
243: PetscLogEventBarrierEnd(VEC_NormBarrier,x,0,0,0,PetscObjectComm((PetscObject)x));
245: if (type!=NORM_1_AND_2) {
246: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[type],*val);
247: }
248: return(0);
249: }
253: /*@
254: VecNormAvailable - Returns the vector norm if it is already known.
256: Not Collective
258: Input Parameters:
259: + x - the vector
260: - type - one of NORM_1, NORM_2, NORM_INFINITY. Also available
261: NORM_1_AND_2, which computes both norms and stores them
262: in a two element array.
264: Output Parameter:
265: + available - PETSC_TRUE if the val returned is valid
266: - val - the norm
268: Notes:
269: $ NORM_1 denotes sum_i |x_i|
270: $ NORM_2 denotes sqrt(sum_i (x_i)^2)
271: $ NORM_INFINITY denotes max_i |x_i|
273: Level: intermediate
275: Performance Issues:
276: $ per-processor memory bandwidth
277: $ interprocessor latency
278: $ work load inbalance that causes certain processes to arrive much earlier than others
280: Compile Option:
281: PETSC_HAVE_SLOW_BLAS_NORM2 will cause a C (loop unrolled) version of the norm to be used, rather
282: than the BLAS. This should probably only be used when one is using the FORTRAN BLAS routines
283: (as opposed to vendor provided) because the FORTRAN BLAS NRM2() routine is very slow.
285: Concepts: norm
286: Concepts: vector^norm
288: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNorm()
289: VecNormBegin(), VecNormEnd()
291: @*/
292: PetscErrorCode VecNormAvailable(Vec x,NormType type,PetscBool *available,PetscReal *val)
293: {
301: *available = PETSC_FALSE;
302: if (type!=NORM_1_AND_2) {
303: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,*available);
304: }
305: return(0);
306: }
310: /*@
311: VecNormalize - Normalizes a vector by 2-norm.
313: Collective on Vec
315: Input Parameters:
316: + x - the vector
318: Output Parameter:
319: . x - the normalized vector
320: - val - the vector norm before normalization
322: Level: intermediate
324: Concepts: vector^normalizing
325: Concepts: normalizing^vector
327: @*/
328: PetscErrorCode VecNormalize(Vec x,PetscReal *val)
329: {
331: PetscReal norm;
336: PetscLogEventBegin(VEC_Normalize,x,0,0,0);
337: VecNorm(x,NORM_2,&norm);
338: if (norm == 0.0) {
339: PetscInfo(x,"Vector of zero norm can not be normalized; Returning only the zero norm\n");
340: } else if (norm != 1.0) {
341: PetscScalar tmp = 1.0/norm;
342: VecScale(x,tmp);
343: }
344: if (val) *val = norm;
345: PetscLogEventEnd(VEC_Normalize,x,0,0,0);
346: return(0);
347: }
351: /*@C
352: VecMax - Determines the maximum vector component and its location.
354: Collective on Vec
356: Input Parameter:
357: . x - the vector
359: Output Parameters:
360: + val - the maximum component
361: - p - the location of val (pass NULL if you don't want this)
363: Notes:
364: Returns the value PETSC_MIN_REAL and p = -1 if the vector is of length 0.
366: Returns the smallest index with the maximum value
367: Level: intermediate
369: Concepts: maximum^of vector
370: Concepts: vector^maximum value
372: .seealso: VecNorm(), VecMin()
373: @*/
374: PetscErrorCode VecMax(Vec x,PetscInt *p,PetscReal *val)
375: {
382: PetscLogEventBegin(VEC_Max,x,0,0,0);
383: (*x->ops->max)(x,p,val);
384: PetscLogEventEnd(VEC_Max,x,0,0,0);
385: return(0);
386: }
390: /*@
391: VecMin - Determines the minimum vector component and its location.
393: Collective on Vec
395: Input Parameters:
396: . x - the vector
398: Output Parameter:
399: + val - the minimum component
400: - p - the location of val (pass NULL if you don't want this location)
402: Level: intermediate
404: Notes:
405: Returns the value PETSC_MAX_REAL and p = -1 if the vector is of length 0.
407: This returns the smallest index with the minumum value
409: Concepts: minimum^of vector
410: Concepts: vector^minimum entry
412: .seealso: VecMax()
413: @*/
414: PetscErrorCode VecMin(Vec x,PetscInt *p,PetscReal *val)
415: {
422: PetscLogEventBegin(VEC_Min,x,0,0,0);
423: (*x->ops->min)(x,p,val);
424: PetscLogEventEnd(VEC_Min,x,0,0,0);
425: return(0);
426: }
430: /*@
431: VecTDot - Computes an indefinite vector dot product. That is, this
432: routine does NOT use the complex conjugate.
434: Collective on Vec
436: Input Parameters:
437: . x, y - the vectors
439: Output Parameter:
440: . val - the dot product
442: Notes for Users of Complex Numbers:
443: For complex vectors, VecTDot() computes the indefinite form
444: $ val = (x,y) = y^T x,
445: where y^T denotes the transpose of y.
447: Use VecDot() for the inner product
448: $ val = (x,y) = y^H x,
449: where y^H denotes the conjugate transpose of y.
451: Level: intermediate
453: Concepts: inner product^non-Hermitian
454: Concepts: vector^inner product
455: Concepts: non-Hermitian inner product
457: .seealso: VecDot(), VecMTDot()
458: @*/
459: PetscErrorCode VecTDot(Vec x,Vec y,PetscScalar *val)
460: {
472: PetscLogEventBegin(VEC_TDot,x,y,0,0);
473: (*x->ops->tdot)(x,y,val);
474: PetscLogEventEnd(VEC_TDot,x,y,0,0);
475: return(0);
476: }
480: /*@
481: VecScale - Scales a vector.
483: Not collective on Vec
485: Input Parameters:
486: + x - the vector
487: - alpha - the scalar
489: Output Parameter:
490: . x - the scaled vector
492: Note:
493: For a vector with n components, VecScale() computes
494: $ x[i] = alpha * x[i], for i=1,...,n.
496: Level: intermediate
498: Concepts: vector^scaling
499: Concepts: scaling^vector
501: @*/
502: PetscErrorCode VecScale(Vec x, PetscScalar alpha)
503: {
504: PetscReal norms[4] = {0.0,0.0,0.0, 0.0};
505: PetscBool flgs[4];
507: PetscInt i;
512: if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
513: PetscLogEventBegin(VEC_Scale,x,0,0,0);
514: if (alpha != (PetscScalar)1.0) {
515: /* get current stashed norms */
516: for (i=0; i<4; i++) {
517: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],norms[i],flgs[i]);
518: }
519: (*x->ops->scale)(x,alpha);
520: PetscObjectStateIncrease((PetscObject)x);
521: /* put the scaled stashed norms back into the Vec */
522: for (i=0; i<4; i++) {
523: if (flgs[i]) {
524: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[i],PetscAbsScalar(alpha)*norms[i]);
525: }
526: }
527: }
528: PetscLogEventEnd(VEC_Scale,x,0,0,0);
529: return(0);
530: }
534: /*@
535: VecSet - Sets all components of a vector to a single scalar value.
537: Logically Collective on Vec
539: Input Parameters:
540: + x - the vector
541: - alpha - the scalar
543: Output Parameter:
544: . x - the vector
546: Note:
547: For a vector of dimension n, VecSet() computes
548: $ x[i] = alpha, for i=1,...,n,
549: so that all vector entries then equal the identical
550: scalar value, alpha. Use the more general routine
551: VecSetValues() to set different vector entries.
553: You CANNOT call this after you have called VecSetValues() but before you call
554: VecAssemblyBegin/End().
556: Level: beginner
558: .seealso VecSetValues(), VecSetValuesBlocked(), VecSetRandom()
560: Concepts: vector^setting to constant
562: @*/
563: PetscErrorCode VecSet(Vec x,PetscScalar alpha)
564: {
565: PetscReal val;
571: if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"You cannot call this after you have called VecSetValues() but\n before you have called VecAssemblyBegin/End()");
574: PetscLogEventBegin(VEC_Set,x,0,0,0);
575: (*x->ops->set)(x,alpha);
576: PetscLogEventEnd(VEC_Set,x,0,0,0);
577: PetscObjectStateIncrease((PetscObject)x);
579: /* norms can be simply set */
580: val = PetscAbsScalar(alpha);
581: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],x->map->N * val);
582: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
583: val = PetscSqrtReal((PetscReal)x->map->N) * val;
584: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],val);
585: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],val);
586: return(0);
587: }
592: /*@
593: VecAXPY - Computes y = alpha x + y.
595: Logically Collective on Vec
597: Input Parameters:
598: + alpha - the scalar
599: - x, y - the vectors
601: Output Parameter:
602: . y - output vector
604: Level: intermediate
606: Notes: x and y MUST be different vectors
608: Concepts: vector^BLAS
609: Concepts: BLAS
611: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY()
612: @*/
613: PetscErrorCode VecAXPY(Vec y,PetscScalar alpha,Vec x)
614: {
624: if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
627: PetscLogEventBegin(VEC_AXPY,x,y,0,0);
628: (*y->ops->axpy)(y,alpha,x);
629: PetscLogEventEnd(VEC_AXPY,x,y,0,0);
630: PetscObjectStateIncrease((PetscObject)y);
631: return(0);
632: }
636: /*@
637: VecAXPBY - Computes y = alpha x + beta y.
639: Logically Collective on Vec
641: Input Parameters:
642: + alpha,beta - the scalars
643: - x, y - the vectors
645: Output Parameter:
646: . y - output vector
648: Level: intermediate
650: Notes: x and y MUST be different vectors
652: Concepts: BLAS
653: Concepts: vector^BLAS
655: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY()
656: @*/
657: PetscErrorCode VecAXPBY(Vec y,PetscScalar alpha,PetscScalar beta,Vec x)
658: {
668: if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
672: PetscLogEventBegin(VEC_AXPY,x,y,0,0);
673: (*y->ops->axpby)(y,alpha,beta,x);
674: PetscLogEventEnd(VEC_AXPY,x,y,0,0);
675: PetscObjectStateIncrease((PetscObject)y);
676: return(0);
677: }
681: /*@
682: VecAXPBYPCZ - Computes z = alpha x + beta y + gamma z
684: Logically Collective on Vec
686: Input Parameters:
687: + alpha,beta, gamma - the scalars
688: - x, y, z - the vectors
690: Output Parameter:
691: . z - output vector
693: Level: intermediate
695: Notes: x, y and z must be different vectors
697: Developer Note: alpha = 1 or gamma = 1 or gamma = 0.0 are handled as special cases
699: Concepts: BLAS
700: Concepts: vector^BLAS
702: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY()
703: @*/
704: PetscErrorCode VecAXPBYPCZ(Vec z,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec x,Vec y)
705: {
719: if (x == y || x == z) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
720: if (y == z) SETERRQ(PetscObjectComm((PetscObject)y),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
725: PetscLogEventBegin(VEC_AXPBYPCZ,x,y,z,0);
726: (*y->ops->axpbypcz)(z,alpha,beta,gamma,x,y);
727: PetscLogEventEnd(VEC_AXPBYPCZ,x,y,z,0);
728: PetscObjectStateIncrease((PetscObject)z);
729: return(0);
730: }
734: /*@
735: VecAYPX - Computes y = x + alpha y.
737: Logically Collective on Vec
739: Input Parameters:
740: + alpha - the scalar
741: - x, y - the vectors
743: Output Parameter:
744: . y - output vector
746: Level: intermediate
748: Notes: x and y MUST be different vectors
750: Concepts: vector^BLAS
751: Concepts: BLAS
753: .seealso: VecAXPY(), VecWAXPY()
754: @*/
755: PetscErrorCode VecAYPX(Vec y,PetscScalar alpha,Vec x)
756: {
764: if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y must be different vectors");
767: PetscLogEventBegin(VEC_AYPX,x,y,0,0);
768: (*y->ops->aypx)(y,alpha,x);
769: PetscLogEventEnd(VEC_AYPX,x,y,0,0);
770: PetscObjectStateIncrease((PetscObject)y);
771: return(0);
772: }
777: /*@
778: VecWAXPY - Computes w = alpha x + y.
780: Logically Collective on Vec
782: Input Parameters:
783: + alpha - the scalar
784: - x, y - the vectors
786: Output Parameter:
787: . w - the result
789: Level: intermediate
791: Notes: w cannot be either x or y, but x and y can be the same
793: Concepts: vector^BLAS
794: Concepts: BLAS
796: .seealso: VecAXPY(), VecAYPX(), VecAXPBY()
797: @*/
798: PetscErrorCode VecWAXPY(Vec w,PetscScalar alpha,Vec x,Vec y)
799: {
813: if (w == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector y, suggest VecAXPY()");
814: if (w == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector x, suggest VecAYPX()");
817: PetscLogEventBegin(VEC_WAXPY,x,y,w,0);
818: (*w->ops->waxpy)(w,alpha,x,y);
819: PetscLogEventEnd(VEC_WAXPY,x,y,w,0);
820: PetscObjectStateIncrease((PetscObject)w);
821: return(0);
822: }
827: /*@
828: VecSetValues - Inserts or adds values into certain locations of a vector.
830: Not Collective
832: Input Parameters:
833: + x - vector to insert in
834: . ni - number of elements to add
835: . ix - indices where to add
836: . y - array of values
837: - iora - either INSERT_VALUES or ADD_VALUES, where
838: ADD_VALUES adds values to any existing entries, and
839: INSERT_VALUES replaces existing entries with new values
841: Notes:
842: VecSetValues() sets x[ix[i]] = y[i], for i=0,...,ni-1.
844: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
845: options cannot be mixed without intervening calls to the assembly
846: routines.
848: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
849: MUST be called after all calls to VecSetValues() have been completed.
851: VecSetValues() uses 0-based indices in Fortran as well as in C.
853: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
854: negative indices may be passed in ix. These rows are
855: simply ignored. This allows easily inserting element load matrices
856: with homogeneous Dirchlet boundary conditions that you don't want represented
857: in the vector.
859: Level: beginner
861: Concepts: vector^setting values
863: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesLocal(),
864: VecSetValue(), VecSetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecGetValues()
865: @*/
866: PetscErrorCode VecSetValues(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
867: {
875: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
876: (*x->ops->setvalues)(x,ni,ix,y,iora);
877: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
878: PetscObjectStateIncrease((PetscObject)x);
879: return(0);
880: }
884: /*@
885: VecGetValues - Gets values from certain locations of a vector. Currently
886: can only get values on the same processor
888: Not Collective
890: Input Parameters:
891: + x - vector to get values from
892: . ni - number of elements to get
893: - ix - indices where to get them from (in global 1d numbering)
895: Output Parameter:
896: . y - array of values
898: Notes:
899: The user provides the allocated array y; it is NOT allocated in this routine
901: VecGetValues() gets y[i] = x[ix[i]], for i=0,...,ni-1.
903: VecAssemblyBegin() and VecAssemblyEnd() MUST be called before calling this
905: VecGetValues() uses 0-based indices in Fortran as well as in C.
907: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
908: negative indices may be passed in ix. These rows are
909: simply ignored.
911: Level: beginner
913: Concepts: vector^getting values
915: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecGetValuesLocal(),
916: VecGetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecSetValues()
917: @*/
918: PetscErrorCode VecGetValues(Vec x,PetscInt ni,const PetscInt ix[],PetscScalar y[])
919: {
927: (*x->ops->getvalues)(x,ni,ix,y);
928: return(0);
929: }
933: /*@
934: VecSetValuesBlocked - Inserts or adds blocks of values into certain locations of a vector.
936: Not Collective
938: Input Parameters:
939: + x - vector to insert in
940: . ni - number of blocks to add
941: . ix - indices where to add in block count, rather than element count
942: . y - array of values
943: - iora - either INSERT_VALUES or ADD_VALUES, where
944: ADD_VALUES adds values to any existing entries, and
945: INSERT_VALUES replaces existing entries with new values
947: Notes:
948: VecSetValuesBlocked() sets x[bs*ix[i]+j] = y[bs*i+j],
949: for j=0,...,bs, for i=0,...,ni-1. where bs was set with VecSetBlockSize().
951: Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
952: options cannot be mixed without intervening calls to the assembly
953: routines.
955: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
956: MUST be called after all calls to VecSetValuesBlocked() have been completed.
958: VecSetValuesBlocked() uses 0-based indices in Fortran as well as in C.
960: Negative indices may be passed in ix, these rows are
961: simply ignored. This allows easily inserting element load matrices
962: with homogeneous Dirchlet boundary conditions that you don't want represented
963: in the vector.
965: Level: intermediate
967: Concepts: vector^setting values blocked
969: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesBlockedLocal(),
970: VecSetValues()
971: @*/
972: PetscErrorCode VecSetValuesBlocked(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
973: {
981: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
982: (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);
983: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
984: PetscObjectStateIncrease((PetscObject)x);
985: return(0);
986: }
991: /*@
992: VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
993: using a local ordering of the nodes.
995: Not Collective
997: Input Parameters:
998: + x - vector to insert in
999: . ni - number of elements to add
1000: . ix - indices where to add
1001: . y - array of values
1002: - iora - either INSERT_VALUES or ADD_VALUES, where
1003: ADD_VALUES adds values to any existing entries, and
1004: INSERT_VALUES replaces existing entries with new values
1006: Level: intermediate
1008: Notes:
1009: VecSetValuesLocal() sets x[ix[i]] = y[i], for i=0,...,ni-1.
1011: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
1012: options cannot be mixed without intervening calls to the assembly
1013: routines.
1015: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
1016: MUST be called after all calls to VecSetValuesLocal() have been completed.
1018: VecSetValuesLocal() uses 0-based indices in Fortran as well as in C.
1020: Concepts: vector^setting values with local numbering
1022: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetLocalToGlobalMapping(),
1023: VecSetValuesBlockedLocal()
1024: @*/
1025: PetscErrorCode VecSetValuesLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
1026: {
1028: PetscInt lixp[128],*lix = lixp;
1036: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
1037: if (!x->ops->setvalueslocal) {
1038: if (!x->map->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMapping()");
1039: if (ni > 128) {
1040: PetscMalloc1(ni,&lix);
1041: }
1042: ISLocalToGlobalMappingApply(x->map->mapping,ni,(PetscInt*)ix,lix);
1043: (*x->ops->setvalues)(x,ni,lix,y,iora);
1044: if (ni > 128) {
1045: PetscFree(lix);
1046: }
1047: } else {
1048: (*x->ops->setvalueslocal)(x,ni,ix,y,iora);
1049: }
1050: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
1051: PetscObjectStateIncrease((PetscObject)x);
1052: return(0);
1053: }
1057: /*@
1058: VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
1059: using a local ordering of the nodes.
1061: Not Collective
1063: Input Parameters:
1064: + x - vector to insert in
1065: . ni - number of blocks to add
1066: . ix - indices where to add in block count, not element count
1067: . y - array of values
1068: - iora - either INSERT_VALUES or ADD_VALUES, where
1069: ADD_VALUES adds values to any existing entries, and
1070: INSERT_VALUES replaces existing entries with new values
1072: Level: intermediate
1074: Notes:
1075: VecSetValuesBlockedLocal() sets x[bs*ix[i]+j] = y[bs*i+j],
1076: for j=0,..bs-1, for i=0,...,ni-1, where bs has been set with VecSetBlockSize().
1078: Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1079: options cannot be mixed without intervening calls to the assembly
1080: routines.
1082: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
1083: MUST be called after all calls to VecSetValuesBlockedLocal() have been completed.
1085: VecSetValuesBlockedLocal() uses 0-based indices in Fortran as well as in C.
1088: Concepts: vector^setting values blocked with local numbering
1090: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesBlocked(),
1091: VecSetLocalToGlobalMappingBlock()
1092: @*/
1093: PetscErrorCode VecSetValuesBlockedLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
1094: {
1096: PetscInt lixp[128],*lix = lixp;
1103: if (!x->map->bmapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMappingBlock()");
1104: if (ni > 128) {
1105: PetscMalloc1(ni,&lix);
1106: }
1108: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
1109: ISLocalToGlobalMappingApply(x->map->bmapping,ni,(PetscInt*)ix,lix);
1110: (*x->ops->setvaluesblocked)(x,ni,lix,y,iora);
1111: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
1112: if (ni > 128) {
1113: PetscFree(lix);
1114: }
1115: PetscObjectStateIncrease((PetscObject)x);
1116: return(0);
1117: }
1121: /*@
1122: VecMTDot - Computes indefinite vector multiple dot products.
1123: That is, it does NOT use the complex conjugate.
1125: Collective on Vec
1127: Input Parameters:
1128: + x - one vector
1129: . nv - number of vectors
1130: - y - array of vectors. Note that vectors are pointers
1132: Output Parameter:
1133: . val - array of the dot products
1135: Notes for Users of Complex Numbers:
1136: For complex vectors, VecMTDot() computes the indefinite form
1137: $ val = (x,y) = y^T x,
1138: where y^T denotes the transpose of y.
1140: Use VecMDot() for the inner product
1141: $ val = (x,y) = y^H x,
1142: where y^H denotes the conjugate transpose of y.
1144: Level: intermediate
1146: Concepts: inner product^multiple
1147: Concepts: vector^multiple inner products
1149: .seealso: VecMDot(), VecTDot()
1150: @*/
1151: PetscErrorCode VecMTDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1152: {
1165: PetscLogEventBegin(VEC_MTDot,x,*y,0,0);
1166: (*x->ops->mtdot)(x,nv,y,val);
1167: PetscLogEventEnd(VEC_MTDot,x,*y,0,0);
1168: return(0);
1169: }
1173: /*@
1174: VecMDot - Computes vector multiple dot products.
1176: Collective on Vec
1178: Input Parameters:
1179: + x - one vector
1180: . nv - number of vectors
1181: - y - array of vectors.
1183: Output Parameter:
1184: . val - array of the dot products (does not allocate the array)
1186: Notes for Users of Complex Numbers:
1187: For complex vectors, VecMDot() computes
1188: $ val = (x,y) = y^H x,
1189: where y^H denotes the conjugate transpose of y.
1191: Use VecMTDot() for the indefinite form
1192: $ val = (x,y) = y^T x,
1193: where y^T denotes the transpose of y.
1195: Level: intermediate
1197: Concepts: inner product^multiple
1198: Concepts: vector^multiple inner products
1200: .seealso: VecMTDot(), VecDot()
1201: @*/
1202: PetscErrorCode VecMDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1203: {
1208: if (!nv) return(0);
1209: if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1218: PetscLogEventBarrierBegin(VEC_MDotBarrier,x,*y,0,0,PetscObjectComm((PetscObject)x));
1219: (*x->ops->mdot)(x,nv,y,val);
1220: PetscLogEventBarrierEnd(VEC_MDotBarrier,x,*y,0,0,PetscObjectComm((PetscObject)x));
1221: return(0);
1222: }
1226: /*@
1227: VecMAXPY - Computes y = y + sum alpha[j] x[j]
1229: Logically Collective on Vec
1231: Input Parameters:
1232: + nv - number of scalars and x-vectors
1233: . alpha - array of scalars
1234: . y - one vector
1235: - x - array of vectors
1237: Level: intermediate
1239: Notes: y cannot be any of the x vectors
1241: Concepts: BLAS
1243: .seealso: VecAXPY(), VecWAXPY(), VecAYPX()
1244: @*/
1245: PetscErrorCode VecMAXPY(Vec y,PetscInt nv,const PetscScalar alpha[],Vec x[])
1246: {
1248: PetscInt i;
1252: if (!nv) return(0);
1253: if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1263: PetscLogEventBegin(VEC_MAXPY,*x,y,0,0);
1264: (*y->ops->maxpy)(y,nv,alpha,x);
1265: PetscLogEventEnd(VEC_MAXPY,*x,y,0,0);
1266: PetscObjectStateIncrease((PetscObject)y);
1267: return(0);
1268: }
1272: /*@
1273: VecGetSubVector - Gets a vector representing part of another vector
1275: Collective on IS (and Vec if nonlocal entries are needed)
1277: Input Arguments:
1278: + X - vector from which to extract a subvector
1279: - is - index set representing portion of X to extract
1281: Output Arguments:
1282: . Y - subvector corresponding to is
1284: Level: advanced
1286: Notes:
1287: The subvector Y should be returned with VecRestoreSubVector().
1289: This function may return a subvector without making a copy, therefore it is not safe to use the original vector while
1290: modifying the subvector. Other non-overlapping subvectors can still be obtained from X using this function.
1292: .seealso: MatGetSubMatrix()
1293: @*/
1294: PetscErrorCode VecGetSubVector(Vec X,IS is,Vec *Y)
1295: {
1296: PetscErrorCode ierr;
1297: Vec Z;
1298: PetscObjectState state;
1304: if (X->ops->getsubvector) {
1305: (*X->ops->getsubvector)(X,is,&Z);
1306: } else { /* Default implementation currently does no caching */
1307: PetscInt gstart,gend,start;
1308: PetscBool contiguous,gcontiguous;
1309: VecGetOwnershipRange(X,&gstart,&gend);
1310: ISContiguousLocal(is,gstart,gend,&start,&contiguous);
1311: MPI_Allreduce(&contiguous,&gcontiguous,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));
1312: if (gcontiguous) { /* We can do a no-copy implementation */
1313: PetscInt n,N;
1314: PetscScalar *x;
1315: PetscMPIInt size;
1316: ISGetLocalSize(is,&n);
1317: VecGetArray(X,&x);
1318: MPI_Comm_size(PetscObjectComm((PetscObject)X),&size);
1319: if (size == 1) {
1320: VecCreateSeqWithArray(PetscObjectComm((PetscObject)X),1,n,x+start,&Z);
1321: } else {
1322: ISGetSize(is,&N);
1323: VecCreateMPIWithArray(PetscObjectComm((PetscObject)X),1,n,N,x+start,&Z);
1324: }
1325: VecRestoreArray(X,&x);
1326: } else { /* Have to create a scatter and do a copy */
1327: VecScatter scatter;
1328: PetscInt n,N;
1329: ISGetLocalSize(is,&n);
1330: ISGetSize(is,&N);
1331: VecCreate(PetscObjectComm((PetscObject)is),&Z);
1332: VecSetSizes(Z,n,N);
1333: VecSetType(Z,((PetscObject)X)->type_name);
1334: VecScatterCreate(X,is,Z,NULL,&scatter);
1335: VecScatterBegin(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
1336: VecScatterEnd(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
1337: VecScatterDestroy(&scatter);
1338: }
1339: }
1340: /* Record the state when the subvector was gotten so we know whether its values need to be put back */
1341: if (VecGetSubVectorSavedStateId < 0) {PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId);}
1342: PetscObjectStateGet((PetscObject)Z,&state);
1343: PetscObjectComposedDataSetInt((PetscObject)Z,VecGetSubVectorSavedStateId,state);
1344: *Y = Z;
1345: return(0);
1346: }
1350: /*@
1351: VecRestoreSubVector - Restores a subvector extracted using VecGetSubVector()
1353: Collective on IS (and Vec if nonlocal entries need to be written)
1355: Input Arguments:
1356: + X - vector from which subvector was obtained
1357: . is - index set representing the subset of X
1358: - Y - subvector being restored
1360: Level: advanced
1362: .seealso: VecGetSubVector()
1363: @*/
1364: PetscErrorCode VecRestoreSubVector(Vec X,IS is,Vec *Y)
1365: {
1373: if (X->ops->restoresubvector) {
1374: (*X->ops->restoresubvector)(X,is,Y);
1375: } else {
1376: PetscObjectState savedstate=0,newstate;
1377: PetscBool valid;
1378: PetscObjectComposedDataGetInt((PetscObject)*Y,VecGetSubVectorSavedStateId,savedstate,valid);
1379: PetscObjectStateGet((PetscObject)*Y,&newstate);
1380: if (valid && savedstate < newstate) {
1381: /* We might need to copy entries back, first check whether we have no-copy view */
1382: PetscInt gstart,gend,start;
1383: PetscBool contiguous,gcontiguous;
1384: VecGetOwnershipRange(X,&gstart,&gend);
1385: ISContiguousLocal(is,gstart,gend,&start,&contiguous);
1386: MPI_Allreduce(&contiguous,&gcontiguous,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));
1387: if (!gcontiguous) SETERRQ(PetscObjectComm((PetscObject)is),PETSC_ERR_SUP,"Unhandled case, values have been changed and need to be copied back into X");
1388: }
1389: VecDestroy(Y);
1390: }
1391: return(0);
1392: }
1396: /*@C
1397: VecGetArray - Returns a pointer to a contiguous array that contains this
1398: processor's portion of the vector data. For the standard PETSc
1399: vectors, VecGetArray() returns a pointer to the local data array and
1400: does not use any copies. If the underlying vector data is not stored
1401: in a contiquous array this routine will copy the data to a contiquous
1402: array and return a pointer to that. You MUST call VecRestoreArray()
1403: when you no longer need access to the array.
1405: Logically Collective on Vec
1407: Input Parameter:
1408: . x - the vector
1410: Output Parameter:
1411: . a - location to put pointer to the array
1413: Fortran Note:
1414: This routine is used differently from Fortran 77
1415: $ Vec x
1416: $ PetscScalar x_array(1)
1417: $ PetscOffset i_x
1418: $ PetscErrorCode ierr
1419: $ call VecGetArray(x,x_array,i_x,ierr)
1420: $
1421: $ Access first local entry in vector with
1422: $ value = x_array(i_x + 1)
1423: $
1424: $ ...... other code
1425: $ call VecRestoreArray(x,x_array,i_x,ierr)
1426: For Fortran 90 see VecGetArrayF90()
1428: See the Fortran chapter of the users manual and
1429: petsc/src/snes/examples/tutorials/ex5f.F for details.
1431: Level: beginner
1433: Concepts: vector^accessing local values
1435: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(), VecGetArray2d()
1436: @*/
1437: PetscErrorCode VecGetArray(Vec x,PetscScalar **a)
1438: {
1443: if (x->petscnative) {
1444: #if defined(PETSC_HAVE_CUSP)
1445: if (x->valid_GPU_array == PETSC_CUSP_GPU) {
1446: VecCUSPCopyFromGPU(x);
1447: }
1448: #endif
1449: #if defined(PETSC_HAVE_VIENNACL)
1450: if (x->valid_GPU_array == PETSC_VIENNACL_GPU) {
1451: VecViennaCLCopyFromGPU(x);
1452: }
1453: #endif
1454: *a = *((PetscScalar **)x->data);
1455: } else {
1456: (*x->ops->getarray)(x,a);
1457: }
1458: return(0);
1459: }
1463: /*@C
1464: VecGetArrayRead - Get read-only pointer to contiguous array containing this processor's portion of the vector data.
1466: Not Collective
1468: Input Parameters:
1469: . x - the vector
1471: Output Parameter:
1472: . a - the array
1474: Level: beginner
1476: Notes:
1477: The array must be returned using a matching call to VecRestoreArrayRead().
1479: Unlike VecGetArray(), this routine is not collective and preserves cached information like vector norms.
1481: Standard PETSc vectors use contiguous storage so that this routine does not perform a copy. Other vector
1482: implementations may require a copy, but must such implementations should cache the contiguous representation so that
1483: only one copy is performed when this routine is called multiple times in sequence.
1485: .seealso: VecGetArray(), VecRestoreArray()
1486: @*/
1487: PetscErrorCode VecGetArrayRead(Vec x,const PetscScalar **a)
1488: {
1493: if (x->petscnative) {
1494: #if defined(PETSC_HAVE_CUSP)
1495: if (x->valid_GPU_array == PETSC_CUSP_GPU) {
1496: VecCUSPCopyFromGPU(x);
1497: }
1498: #endif
1499: #if defined(PETSC_HAVE_VIENNACL)
1500: if (x->valid_GPU_array == PETSC_VIENNACL_GPU) {
1501: VecViennaCLCopyFromGPU(x);
1502: }
1503: #endif
1504: *a = *((PetscScalar **)x->data);
1505: } else if (x->ops->getarrayread) {
1506: (*x->ops->getarrayread)(x,a);
1507: } else {
1508: (*x->ops->getarray)(x,(PetscScalar**)a);
1509: }
1510: return(0);
1511: }
1515: /*@C
1516: VecGetArrays - Returns a pointer to the arrays in a set of vectors
1517: that were created by a call to VecDuplicateVecs(). You MUST call
1518: VecRestoreArrays() when you no longer need access to the array.
1520: Logically Collective on Vec
1522: Input Parameter:
1523: + x - the vectors
1524: - n - the number of vectors
1526: Output Parameter:
1527: . a - location to put pointer to the array
1529: Fortran Note:
1530: This routine is not supported in Fortran.
1532: Level: intermediate
1534: .seealso: VecGetArray(), VecRestoreArrays()
1535: @*/
1536: PetscErrorCode VecGetArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1537: {
1539: PetscInt i;
1540: PetscScalar **q;
1546: if (n <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must get at least one array n = %D",n);
1547: PetscMalloc1(n,&q);
1548: for (i=0; i<n; ++i) {
1549: VecGetArray(x[i],&q[i]);
1550: }
1551: *a = q;
1552: return(0);
1553: }
1557: /*@C
1558: VecRestoreArrays - Restores a group of vectors after VecGetArrays()
1559: has been called.
1561: Logically Collective on Vec
1563: Input Parameters:
1564: + x - the vector
1565: . n - the number of vectors
1566: - a - location of pointer to arrays obtained from VecGetArrays()
1568: Notes:
1569: For regular PETSc vectors this routine does not involve any copies. For
1570: any special vectors that do not store local vector data in a contiguous
1571: array, this routine will copy the data back into the underlying
1572: vector data structure from the arrays obtained with VecGetArrays().
1574: Fortran Note:
1575: This routine is not supported in Fortran.
1577: Level: intermediate
1579: .seealso: VecGetArrays(), VecRestoreArray()
1580: @*/
1581: PetscErrorCode VecRestoreArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1582: {
1584: PetscInt i;
1585: PetscScalar **q = *a;
1592: for (i=0; i<n; ++i) {
1593: VecRestoreArray(x[i],&q[i]);
1594: }
1595: PetscFree(q);
1596: return(0);
1597: }
1601: /*@C
1602: VecRestoreArray - Restores a vector after VecGetArray() has been called.
1604: Logically Collective on Vec
1606: Input Parameters:
1607: + x - the vector
1608: - a - location of pointer to array obtained from VecGetArray()
1610: Level: beginner
1612: Notes:
1613: For regular PETSc vectors this routine does not involve any copies. For
1614: any special vectors that do not store local vector data in a contiguous
1615: array, this routine will copy the data back into the underlying
1616: vector data structure from the array obtained with VecGetArray().
1618: This routine actually zeros out the a pointer. This is to prevent accidental
1619: us of the array after it has been restored. If you pass null for a it will
1620: not zero the array pointer a.
1622: Fortran Note:
1623: This routine is used differently from Fortran 77
1624: $ Vec x
1625: $ PetscScalar x_array(1)
1626: $ PetscOffset i_x
1627: $ PetscErrorCode ierr
1628: $ call VecGetArray(x,x_array,i_x,ierr)
1629: $
1630: $ Access first local entry in vector with
1631: $ value = x_array(i_x + 1)
1632: $
1633: $ ...... other code
1634: $ call VecRestoreArray(x,x_array,i_x,ierr)
1636: See the Fortran chapter of the users manual and
1637: petsc/src/snes/examples/tutorials/ex5f.F for details.
1638: For Fortran 90 see VecRestoreArrayF90()
1640: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(), VecRestoreArray2d()
1641: @*/
1642: PetscErrorCode VecRestoreArray(Vec x,PetscScalar **a)
1643: {
1648: if (x->petscnative) {
1649: #if defined(PETSC_HAVE_CUSP)
1650: x->valid_GPU_array = PETSC_CUSP_CPU;
1651: #endif
1652: #if defined(PETSC_HAVE_VIENNACL)
1653: x->valid_GPU_array = PETSC_VIENNACL_CPU;
1654: #endif
1655: } else {
1656: (*x->ops->restorearray)(x,a);
1657: }
1658: if (a) *a = NULL;
1659: PetscObjectStateIncrease((PetscObject)x);
1660: return(0);
1661: }
1665: /*@C
1666: VecRestoreArrayRead - Restore array obtained with VecGetArrayRead()
1668: Not Collective
1670: Input Parameters:
1671: + vec - the vector
1672: - array - the array
1674: Level: beginner
1676: .seealso: VecGetArray(), VecRestoreArray()
1677: @*/
1678: PetscErrorCode VecRestoreArrayRead(Vec x,const PetscScalar **a)
1679: {
1684: if (x->petscnative) {
1685: #if defined(PETSC_HAVE_VIENNACL)
1686: x->valid_GPU_array = PETSC_VIENNACL_CPU;
1687: #endif
1688: } else if (x->ops->restorearrayread) {
1689: (*x->ops->restorearrayread)(x,a);
1690: } else {
1691: (*x->ops->restorearray)(x,(PetscScalar**)a);
1692: }
1693: if (a) *a = NULL;
1694: return(0);
1695: }
1699: /*@
1700: VecPlaceArray - Allows one to replace the array in a vector with an
1701: array provided by the user. This is useful to avoid copying an array
1702: into a vector.
1704: Not Collective
1706: Input Parameters:
1707: + vec - the vector
1708: - array - the array
1710: Notes:
1711: You can return to the original array with a call to VecResetArray()
1713: Level: developer
1715: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray()
1717: @*/
1718: PetscErrorCode VecPlaceArray(Vec vec,const PetscScalar array[])
1719: {
1726: if (vec->ops->placearray) {
1727: (*vec->ops->placearray)(vec,array);
1728: } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot place array in this type of vector");
1729: PetscObjectStateIncrease((PetscObject)vec);
1730: return(0);
1731: }
1735: /*@C
1736: VecReplaceArray - Allows one to replace the array in a vector with an
1737: array provided by the user. This is useful to avoid copying an array
1738: into a vector.
1740: Not Collective
1742: Input Parameters:
1743: + vec - the vector
1744: - array - the array
1746: Notes:
1747: This permanently replaces the array and frees the memory associated
1748: with the old array.
1750: The memory passed in MUST be obtained with PetscMalloc() and CANNOT be
1751: freed by the user. It will be freed when the vector is destroy.
1753: Not supported from Fortran
1755: Level: developer
1757: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray()
1759: @*/
1760: PetscErrorCode VecReplaceArray(Vec vec,const PetscScalar array[])
1761: {
1767: if (vec->ops->replacearray) {
1768: (*vec->ops->replacearray)(vec,array);
1769: } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot replace array in this type of vector");
1770: PetscObjectStateIncrease((PetscObject)vec);
1771: return(0);
1772: }
1774: /*MC
1775: VecDuplicateVecsF90 - Creates several vectors of the same type as an existing vector
1776: and makes them accessible via a Fortran90 pointer.
1778: Synopsis:
1779: VecDuplicateVecsF90(Vec x,PetscInt n,{Vec, pointer :: y(:)},integer ierr)
1781: Collective on Vec
1783: Input Parameters:
1784: + x - a vector to mimic
1785: - n - the number of vectors to obtain
1787: Output Parameters:
1788: + y - Fortran90 pointer to the array of vectors
1789: - ierr - error code
1791: Example of Usage:
1792: .vb
1793: Vec x
1794: Vec, pointer :: y(:)
1795: ....
1796: call VecDuplicateVecsF90(x,2,y,ierr)
1797: call VecSet(y(2),alpha,ierr)
1798: call VecSet(y(2),alpha,ierr)
1799: ....
1800: call VecDestroyVecsF90(2,y,ierr)
1801: .ve
1803: Notes:
1804: Not yet supported for all F90 compilers
1806: Use VecDestroyVecsF90() to free the space.
1808: Level: beginner
1810: .seealso: VecDestroyVecsF90(), VecDuplicateVecs()
1812: M*/
1814: /*MC
1815: VecRestoreArrayF90 - Restores a vector to a usable state after a call to
1816: VecGetArrayF90().
1818: Synopsis:
1819: VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
1821: Logically Collective on Vec
1823: Input Parameters:
1824: + x - vector
1825: - xx_v - the Fortran90 pointer to the array
1827: Output Parameter:
1828: . ierr - error code
1830: Example of Usage:
1831: .vb
1832: PetscScalar, pointer :: xx_v(:)
1833: ....
1834: call VecGetArrayF90(x,xx_v,ierr)
1835: a = xx_v(3)
1836: call VecRestoreArrayF90(x,xx_v,ierr)
1837: .ve
1839: Level: beginner
1841: .seealso: VecGetArrayF90(), VecGetArray(), VecRestoreArray(), UsingFortran
1843: M*/
1845: /*MC
1846: VecDestroyVecsF90 - Frees a block of vectors obtained with VecDuplicateVecsF90().
1848: Synopsis:
1849: VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)
1851: Collective on Vec
1853: Input Parameters:
1854: + n - the number of vectors previously obtained
1855: - x - pointer to array of vector pointers
1857: Output Parameter:
1858: . ierr - error code
1860: Notes:
1861: Not yet supported for all F90 compilers
1863: Level: beginner
1865: .seealso: VecDestroyVecs(), VecDuplicateVecsF90()
1867: M*/
1869: /*MC
1870: VecGetArrayF90 - Accesses a vector array from Fortran90. For default PETSc
1871: vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
1872: this routine is implementation dependent. You MUST call VecRestoreArrayF90()
1873: when you no longer need access to the array.
1875: Synopsis:
1876: VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
1878: Logically Collective on Vec
1880: Input Parameter:
1881: . x - vector
1883: Output Parameters:
1884: + xx_v - the Fortran90 pointer to the array
1885: - ierr - error code
1887: Example of Usage:
1888: .vb
1889: PetscScalar, pointer :: xx_v(:)
1890: ....
1891: call VecGetArrayF90(x,xx_v,ierr)
1892: a = xx_v(3)
1893: call VecRestoreArrayF90(x,xx_v,ierr)
1894: .ve
1896: Level: beginner
1898: .seealso: VecRestoreArrayF90(), VecGetArray(), VecRestoreArray(), UsingFortran
1900: M*/
1905: /*@C
1906: VecGetArray2d - Returns a pointer to a 2d contiguous array that contains this
1907: processor's portion of the vector data. You MUST call VecRestoreArray2d()
1908: when you no longer need access to the array.
1910: Logically Collective
1912: Input Parameter:
1913: + x - the vector
1914: . m - first dimension of two dimensional array
1915: . n - second dimension of two dimensional array
1916: . mstart - first index you will use in first coordinate direction (often 0)
1917: - nstart - first index in the second coordinate direction (often 0)
1919: Output Parameter:
1920: . a - location to put pointer to the array
1922: Level: developer
1924: Notes:
1925: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
1926: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
1927: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
1928: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
1930: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
1932: Concepts: vector^accessing local values as 2d array
1934: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1935: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1936: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1937: @*/
1938: PetscErrorCode VecGetArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
1939: {
1941: PetscInt i,N;
1942: PetscScalar *aa;
1948: VecGetLocalSize(x,&N);
1949: if (m*n != N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 2d array dimensions %D by %D",N,m,n);
1950: VecGetArray(x,&aa);
1952: PetscMalloc1(m,a);
1953: for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
1954: *a -= mstart;
1955: return(0);
1956: }
1960: /*@C
1961: VecRestoreArray2d - Restores a vector after VecGetArray2d() has been called.
1963: Logically Collective
1965: Input Parameters:
1966: + x - the vector
1967: . m - first dimension of two dimensional array
1968: . n - second dimension of the two dimensional array
1969: . mstart - first index you will use in first coordinate direction (often 0)
1970: . nstart - first index in the second coordinate direction (often 0)
1971: - a - location of pointer to array obtained from VecGetArray2d()
1973: Level: developer
1975: Notes:
1976: For regular PETSc vectors this routine does not involve any copies. For
1977: any special vectors that do not store local vector data in a contiguous
1978: array, this routine will copy the data back into the underlying
1979: vector data structure from the array obtained with VecGetArray().
1981: This routine actually zeros out the a pointer.
1983: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1984: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
1985: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1986: @*/
1987: PetscErrorCode VecRestoreArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
1988: {
1990: void *dummy;
1996: dummy = (void*)(*a + mstart);
1997: PetscFree(dummy);
1998: VecRestoreArray(x,NULL);
1999: return(0);
2000: }
2004: /*@C
2005: VecGetArray1d - Returns a pointer to a 1d contiguous array that contains this
2006: processor's portion of the vector data. You MUST call VecRestoreArray1d()
2007: when you no longer need access to the array.
2009: Logically Collective
2011: Input Parameter:
2012: + x - the vector
2013: . m - first dimension of two dimensional array
2014: - mstart - first index you will use in first coordinate direction (often 0)
2016: Output Parameter:
2017: . a - location to put pointer to the array
2019: Level: developer
2021: Notes:
2022: For a vector obtained from DMCreateLocalVector() mstart are likely
2023: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2024: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
2026: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2028: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2029: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2030: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2031: @*/
2032: PetscErrorCode VecGetArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2033: {
2035: PetscInt N;
2041: VecGetLocalSize(x,&N);
2042: if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
2043: VecGetArray(x,a);
2044: *a -= mstart;
2045: return(0);
2046: }
2050: /*@C
2051: VecRestoreArray1d - Restores a vector after VecGetArray1d() has been called.
2053: Logically Collective
2055: Input Parameters:
2056: + x - the vector
2057: . m - first dimension of two dimensional array
2058: . mstart - first index you will use in first coordinate direction (often 0)
2059: - a - location of pointer to array obtained from VecGetArray21()
2061: Level: developer
2063: Notes:
2064: For regular PETSc vectors this routine does not involve any copies. For
2065: any special vectors that do not store local vector data in a contiguous
2066: array, this routine will copy the data back into the underlying
2067: vector data structure from the array obtained with VecGetArray1d().
2069: This routine actually zeros out the a pointer.
2071: Concepts: vector^accessing local values as 1d array
2073: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2074: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2075: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
2076: @*/
2077: PetscErrorCode VecRestoreArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2078: {
2084: VecRestoreArray(x,NULL);
2085: return(0);
2086: }
2091: /*@C
2092: VecGetArray3d - Returns a pointer to a 3d contiguous array that contains this
2093: processor's portion of the vector data. You MUST call VecRestoreArray3d()
2094: when you no longer need access to the array.
2096: Logically Collective
2098: Input Parameter:
2099: + x - the vector
2100: . m - first dimension of three dimensional array
2101: . n - second dimension of three dimensional array
2102: . p - third dimension of three dimensional array
2103: . mstart - first index you will use in first coordinate direction (often 0)
2104: . nstart - first index in the second coordinate direction (often 0)
2105: - pstart - first index in the third coordinate direction (often 0)
2107: Output Parameter:
2108: . a - location to put pointer to the array
2110: Level: developer
2112: Notes:
2113: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
2114: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2115: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
2116: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
2118: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2120: Concepts: vector^accessing local values as 3d array
2122: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2123: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2124: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2125: @*/
2126: PetscErrorCode VecGetArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
2127: {
2129: PetscInt i,N,j;
2130: PetscScalar *aa,**b;
2136: VecGetLocalSize(x,&N);
2137: if (m*n*p != N) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 3d array dimensions %D by %D by %D",N,m,n,p);
2138: VecGetArray(x,&aa);
2140: PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
2141: b = (PetscScalar**)((*a) + m);
2142: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
2143: for (i=0; i<m; i++)
2144: for (j=0; j<n; j++)
2145: b[i*n+j] = aa + i*n*p + j*p - pstart;
2147: *a -= mstart;
2148: return(0);
2149: }
2153: /*@C
2154: VecRestoreArray3d - Restores a vector after VecGetArray3d() has been called.
2156: Logically Collective
2158: Input Parameters:
2159: + x - the vector
2160: . m - first dimension of three dimensional array
2161: . n - second dimension of the three dimensional array
2162: . p - third dimension of the three dimensional array
2163: . mstart - first index you will use in first coordinate direction (often 0)
2164: . nstart - first index in the second coordinate direction (often 0)
2165: . pstart - first index in the third coordinate direction (often 0)
2166: - a - location of pointer to array obtained from VecGetArray3d()
2168: Level: developer
2170: Notes:
2171: For regular PETSc vectors this routine does not involve any copies. For
2172: any special vectors that do not store local vector data in a contiguous
2173: array, this routine will copy the data back into the underlying
2174: vector data structure from the array obtained with VecGetArray().
2176: This routine actually zeros out the a pointer.
2178: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2179: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2180: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
2181: @*/
2182: PetscErrorCode VecRestoreArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
2183: {
2185: void *dummy;
2191: dummy = (void*)(*a + mstart);
2192: PetscFree(dummy);
2193: VecRestoreArray(x,NULL);
2194: return(0);
2195: }
2199: /*@C
2200: VecGetArray4d - Returns a pointer to a 4d contiguous array that contains this
2201: processor's portion of the vector data. You MUST call VecRestoreArray4d()
2202: when you no longer need access to the array.
2204: Logically Collective
2206: Input Parameter:
2207: + x - the vector
2208: . m - first dimension of four dimensional array
2209: . n - second dimension of four dimensional array
2210: . p - third dimension of four dimensional array
2211: . q - fourth dimension of four dimensional array
2212: . mstart - first index you will use in first coordinate direction (often 0)
2213: . nstart - first index in the second coordinate direction (often 0)
2214: . pstart - first index in the third coordinate direction (often 0)
2215: - qstart - first index in the fourth coordinate direction (often 0)
2217: Output Parameter:
2218: . a - location to put pointer to the array
2220: Level: beginner
2222: Notes:
2223: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
2224: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2225: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
2226: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
2228: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2230: Concepts: vector^accessing local values as 3d array
2232: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2233: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2234: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2235: @*/
2236: PetscErrorCode VecGetArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
2237: {
2239: PetscInt i,N,j,k;
2240: PetscScalar *aa,***b,**c;
2246: VecGetLocalSize(x,&N);
2247: if (m*n*p*q != N) SETERRQ5(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 4d array dimensions %D by %D by %D by %D",N,m,n,p,q);
2248: VecGetArray(x,&aa);
2250: PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
2251: b = (PetscScalar***)((*a) + m);
2252: c = (PetscScalar**)(b + m*n);
2253: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
2254: for (i=0; i<m; i++)
2255: for (j=0; j<n; j++)
2256: b[i*n+j] = c + i*n*p + j*p - pstart;
2257: for (i=0; i<m; i++)
2258: for (j=0; j<n; j++)
2259: for (k=0; k<p; k++)
2260: c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
2261: *a -= mstart;
2262: return(0);
2263: }
2267: /*@C
2268: VecRestoreArray4d - Restores a vector after VecGetArray3d() has been called.
2270: Logically Collective
2272: Input Parameters:
2273: + x - the vector
2274: . m - first dimension of four dimensional array
2275: . n - second dimension of the four dimensional array
2276: . p - third dimension of the four dimensional array
2277: . q - fourth dimension of the four dimensional array
2278: . mstart - first index you will use in first coordinate direction (often 0)
2279: . nstart - first index in the second coordinate direction (often 0)
2280: . pstart - first index in the third coordinate direction (often 0)
2281: . qstart - first index in the fourth coordinate direction (often 0)
2282: - a - location of pointer to array obtained from VecGetArray4d()
2284: Level: beginner
2286: Notes:
2287: For regular PETSc vectors this routine does not involve any copies. For
2288: any special vectors that do not store local vector data in a contiguous
2289: array, this routine will copy the data back into the underlying
2290: vector data structure from the array obtained with VecGetArray().
2292: This routine actually zeros out the a pointer.
2294: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2295: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2296: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
2297: @*/
2298: PetscErrorCode VecRestoreArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
2299: {
2301: void *dummy;
2307: dummy = (void*)(*a + mstart);
2308: PetscFree(dummy);
2309: VecRestoreArray(x,NULL);
2310: return(0);
2311: }