Actual source code: rvector.c
petsc-3.5.2 2014-09-08
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 (if |alpha|*N not too large) */
580: val = PetscAbsScalar(alpha);
581: if (x->map->N == 0) {
582: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],0.0l);
583: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],0.0);
584: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],0.0);
585: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],0.0);
586: } else if (val > PETSC_MAX_REAL/x->map->N) {
587: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
588: } else {
589: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],x->map->N * val);
590: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
591: val = PetscSqrtReal((PetscReal)x->map->N) * val;
592: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],val);
593: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],val);
594: }
595: return(0);
596: }
601: /*@
602: VecAXPY - Computes y = alpha x + y.
604: Logically Collective on Vec
606: Input Parameters:
607: + alpha - the scalar
608: - x, y - the vectors
610: Output Parameter:
611: . y - output vector
613: Level: intermediate
615: Notes: x and y MUST be different vectors
617: Concepts: vector^BLAS
618: Concepts: BLAS
620: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY()
621: @*/
622: PetscErrorCode VecAXPY(Vec y,PetscScalar alpha,Vec x)
623: {
633: if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
636: PetscLogEventBegin(VEC_AXPY,x,y,0,0);
637: (*y->ops->axpy)(y,alpha,x);
638: PetscLogEventEnd(VEC_AXPY,x,y,0,0);
639: PetscObjectStateIncrease((PetscObject)y);
640: return(0);
641: }
645: /*@
646: VecAXPBY - Computes y = alpha x + beta y.
648: Logically Collective on Vec
650: Input Parameters:
651: + alpha,beta - the scalars
652: - x, y - the vectors
654: Output Parameter:
655: . y - output vector
657: Level: intermediate
659: Notes: x and y MUST be different vectors
661: Concepts: BLAS
662: Concepts: vector^BLAS
664: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY()
665: @*/
666: PetscErrorCode VecAXPBY(Vec y,PetscScalar alpha,PetscScalar beta,Vec x)
667: {
677: if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
681: PetscLogEventBegin(VEC_AXPY,x,y,0,0);
682: (*y->ops->axpby)(y,alpha,beta,x);
683: PetscLogEventEnd(VEC_AXPY,x,y,0,0);
684: PetscObjectStateIncrease((PetscObject)y);
685: return(0);
686: }
690: /*@
691: VecAXPBYPCZ - Computes z = alpha x + beta y + gamma z
693: Logically Collective on Vec
695: Input Parameters:
696: + alpha,beta, gamma - the scalars
697: - x, y, z - the vectors
699: Output Parameter:
700: . z - output vector
702: Level: intermediate
704: Notes: x, y and z must be different vectors
706: Developer Note: alpha = 1 or gamma = 1 or gamma = 0.0 are handled as special cases
708: Concepts: BLAS
709: Concepts: vector^BLAS
711: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY()
712: @*/
713: PetscErrorCode VecAXPBYPCZ(Vec z,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec x,Vec y)
714: {
728: if (x == y || x == z) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
729: if (y == z) SETERRQ(PetscObjectComm((PetscObject)y),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
734: PetscLogEventBegin(VEC_AXPBYPCZ,x,y,z,0);
735: (*y->ops->axpbypcz)(z,alpha,beta,gamma,x,y);
736: PetscLogEventEnd(VEC_AXPBYPCZ,x,y,z,0);
737: PetscObjectStateIncrease((PetscObject)z);
738: return(0);
739: }
743: /*@
744: VecAYPX - Computes y = x + alpha y.
746: Logically Collective on Vec
748: Input Parameters:
749: + alpha - the scalar
750: - x, y - the vectors
752: Output Parameter:
753: . y - output vector
755: Level: intermediate
757: Notes: x and y MUST be different vectors
759: Concepts: vector^BLAS
760: Concepts: BLAS
762: .seealso: VecAXPY(), VecWAXPY()
763: @*/
764: PetscErrorCode VecAYPX(Vec y,PetscScalar alpha,Vec x)
765: {
773: if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y must be different vectors");
776: PetscLogEventBegin(VEC_AYPX,x,y,0,0);
777: (*y->ops->aypx)(y,alpha,x);
778: PetscLogEventEnd(VEC_AYPX,x,y,0,0);
779: PetscObjectStateIncrease((PetscObject)y);
780: return(0);
781: }
786: /*@
787: VecWAXPY - Computes w = alpha x + y.
789: Logically Collective on Vec
791: Input Parameters:
792: + alpha - the scalar
793: - x, y - the vectors
795: Output Parameter:
796: . w - the result
798: Level: intermediate
800: Notes: w cannot be either x or y, but x and y can be the same
802: Concepts: vector^BLAS
803: Concepts: BLAS
805: .seealso: VecAXPY(), VecAYPX(), VecAXPBY()
806: @*/
807: PetscErrorCode VecWAXPY(Vec w,PetscScalar alpha,Vec x,Vec y)
808: {
822: if (w == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector y, suggest VecAXPY()");
823: if (w == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector x, suggest VecAYPX()");
826: PetscLogEventBegin(VEC_WAXPY,x,y,w,0);
827: (*w->ops->waxpy)(w,alpha,x,y);
828: PetscLogEventEnd(VEC_WAXPY,x,y,w,0);
829: PetscObjectStateIncrease((PetscObject)w);
830: return(0);
831: }
836: /*@
837: VecSetValues - Inserts or adds values into certain locations of a vector.
839: Not Collective
841: Input Parameters:
842: + x - vector to insert in
843: . ni - number of elements to add
844: . ix - indices where to add
845: . y - array of values
846: - iora - either INSERT_VALUES or ADD_VALUES, where
847: ADD_VALUES adds values to any existing entries, and
848: INSERT_VALUES replaces existing entries with new values
850: Notes:
851: VecSetValues() sets x[ix[i]] = y[i], for i=0,...,ni-1.
853: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
854: options cannot be mixed without intervening calls to the assembly
855: routines.
857: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
858: MUST be called after all calls to VecSetValues() have been completed.
860: VecSetValues() uses 0-based indices in Fortran as well as in C.
862: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
863: negative indices may be passed in ix. These rows are
864: simply ignored. This allows easily inserting element load matrices
865: with homogeneous Dirchlet boundary conditions that you don't want represented
866: in the vector.
868: Level: beginner
870: Concepts: vector^setting values
872: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesLocal(),
873: VecSetValue(), VecSetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecGetValues()
874: @*/
875: PetscErrorCode VecSetValues(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
876: {
884: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
885: (*x->ops->setvalues)(x,ni,ix,y,iora);
886: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
887: PetscObjectStateIncrease((PetscObject)x);
888: return(0);
889: }
893: /*@
894: VecGetValues - Gets values from certain locations of a vector. Currently
895: can only get values on the same processor
897: Not Collective
899: Input Parameters:
900: + x - vector to get values from
901: . ni - number of elements to get
902: - ix - indices where to get them from (in global 1d numbering)
904: Output Parameter:
905: . y - array of values
907: Notes:
908: The user provides the allocated array y; it is NOT allocated in this routine
910: VecGetValues() gets y[i] = x[ix[i]], for i=0,...,ni-1.
912: VecAssemblyBegin() and VecAssemblyEnd() MUST be called before calling this
914: VecGetValues() uses 0-based indices in Fortran as well as in C.
916: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
917: negative indices may be passed in ix. These rows are
918: simply ignored.
920: Level: beginner
922: Concepts: vector^getting values
924: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecGetValuesLocal(),
925: VecGetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecSetValues()
926: @*/
927: PetscErrorCode VecGetValues(Vec x,PetscInt ni,const PetscInt ix[],PetscScalar y[])
928: {
936: (*x->ops->getvalues)(x,ni,ix,y);
937: return(0);
938: }
942: /*@
943: VecSetValuesBlocked - Inserts or adds blocks of values into certain locations of a vector.
945: Not Collective
947: Input Parameters:
948: + x - vector to insert in
949: . ni - number of blocks to add
950: . ix - indices where to add in block count, rather than element count
951: . y - array of values
952: - iora - either INSERT_VALUES or ADD_VALUES, where
953: ADD_VALUES adds values to any existing entries, and
954: INSERT_VALUES replaces existing entries with new values
956: Notes:
957: VecSetValuesBlocked() sets x[bs*ix[i]+j] = y[bs*i+j],
958: for j=0,...,bs, for i=0,...,ni-1. where bs was set with VecSetBlockSize().
960: Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
961: options cannot be mixed without intervening calls to the assembly
962: routines.
964: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
965: MUST be called after all calls to VecSetValuesBlocked() have been completed.
967: VecSetValuesBlocked() uses 0-based indices in Fortran as well as in C.
969: Negative indices may be passed in ix, these rows are
970: simply ignored. This allows easily inserting element load matrices
971: with homogeneous Dirchlet boundary conditions that you don't want represented
972: in the vector.
974: Level: intermediate
976: Concepts: vector^setting values blocked
978: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesBlockedLocal(),
979: VecSetValues()
980: @*/
981: PetscErrorCode VecSetValuesBlocked(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
982: {
990: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
991: (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);
992: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
993: PetscObjectStateIncrease((PetscObject)x);
994: return(0);
995: }
1000: /*@
1001: VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
1002: using a local ordering of the nodes.
1004: Not Collective
1006: Input Parameters:
1007: + x - vector to insert in
1008: . ni - number of elements to add
1009: . ix - indices where to add
1010: . y - array of values
1011: - iora - either INSERT_VALUES or ADD_VALUES, where
1012: ADD_VALUES adds values to any existing entries, and
1013: INSERT_VALUES replaces existing entries with new values
1015: Level: intermediate
1017: Notes:
1018: VecSetValuesLocal() sets x[ix[i]] = y[i], for i=0,...,ni-1.
1020: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
1021: options cannot be mixed without intervening calls to the assembly
1022: routines.
1024: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
1025: MUST be called after all calls to VecSetValuesLocal() have been completed.
1027: VecSetValuesLocal() uses 0-based indices in Fortran as well as in C.
1029: Concepts: vector^setting values with local numbering
1031: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetLocalToGlobalMapping(),
1032: VecSetValuesBlockedLocal()
1033: @*/
1034: PetscErrorCode VecSetValuesLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
1035: {
1037: PetscInt lixp[128],*lix = lixp;
1045: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
1046: if (!x->ops->setvalueslocal) {
1047: if (!x->map->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMapping()");
1048: if (ni > 128) {
1049: PetscMalloc1(ni,&lix);
1050: }
1051: ISLocalToGlobalMappingApply(x->map->mapping,ni,(PetscInt*)ix,lix);
1052: (*x->ops->setvalues)(x,ni,lix,y,iora);
1053: if (ni > 128) {
1054: PetscFree(lix);
1055: }
1056: } else {
1057: (*x->ops->setvalueslocal)(x,ni,ix,y,iora);
1058: }
1059: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
1060: PetscObjectStateIncrease((PetscObject)x);
1061: return(0);
1062: }
1066: /*@
1067: VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
1068: using a local ordering of the nodes.
1070: Not Collective
1072: Input Parameters:
1073: + x - vector to insert in
1074: . ni - number of blocks to add
1075: . ix - indices where to add in block count, not element count
1076: . y - array of values
1077: - iora - either INSERT_VALUES or ADD_VALUES, where
1078: ADD_VALUES adds values to any existing entries, and
1079: INSERT_VALUES replaces existing entries with new values
1081: Level: intermediate
1083: Notes:
1084: VecSetValuesBlockedLocal() sets x[bs*ix[i]+j] = y[bs*i+j],
1085: for j=0,..bs-1, for i=0,...,ni-1, where bs has been set with VecSetBlockSize().
1087: Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1088: options cannot be mixed without intervening calls to the assembly
1089: routines.
1091: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
1092: MUST be called after all calls to VecSetValuesBlockedLocal() have been completed.
1094: VecSetValuesBlockedLocal() uses 0-based indices in Fortran as well as in C.
1097: Concepts: vector^setting values blocked with local numbering
1099: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesBlocked(),
1100: VecSetLocalToGlobalMapping()
1101: @*/
1102: PetscErrorCode VecSetValuesBlockedLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
1103: {
1105: PetscInt lixp[128],*lix = lixp;
1112: if (ni > 128) {
1113: PetscMalloc1(ni,&lix);
1114: }
1116: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
1117: ISLocalToGlobalMappingApplyBlock(x->map->mapping,ni,(PetscInt*)ix,lix);
1118: (*x->ops->setvaluesblocked)(x,ni,lix,y,iora);
1119: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
1120: if (ni > 128) {
1121: PetscFree(lix);
1122: }
1123: PetscObjectStateIncrease((PetscObject)x);
1124: return(0);
1125: }
1129: /*@
1130: VecMTDot - Computes indefinite vector multiple dot products.
1131: That is, it does NOT use the complex conjugate.
1133: Collective on Vec
1135: Input Parameters:
1136: + x - one vector
1137: . nv - number of vectors
1138: - y - array of vectors. Note that vectors are pointers
1140: Output Parameter:
1141: . val - array of the dot products
1143: Notes for Users of Complex Numbers:
1144: For complex vectors, VecMTDot() computes the indefinite form
1145: $ val = (x,y) = y^T x,
1146: where y^T denotes the transpose of y.
1148: Use VecMDot() for the inner product
1149: $ val = (x,y) = y^H x,
1150: where y^H denotes the conjugate transpose of y.
1152: Level: intermediate
1154: Concepts: inner product^multiple
1155: Concepts: vector^multiple inner products
1157: .seealso: VecMDot(), VecTDot()
1158: @*/
1159: PetscErrorCode VecMTDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1160: {
1173: PetscLogEventBegin(VEC_MTDot,x,*y,0,0);
1174: (*x->ops->mtdot)(x,nv,y,val);
1175: PetscLogEventEnd(VEC_MTDot,x,*y,0,0);
1176: return(0);
1177: }
1181: /*@
1182: VecMDot - Computes vector multiple dot products.
1184: Collective on Vec
1186: Input Parameters:
1187: + x - one vector
1188: . nv - number of vectors
1189: - y - array of vectors.
1191: Output Parameter:
1192: . val - array of the dot products (does not allocate the array)
1194: Notes for Users of Complex Numbers:
1195: For complex vectors, VecMDot() computes
1196: $ val = (x,y) = y^H x,
1197: where y^H denotes the conjugate transpose of y.
1199: Use VecMTDot() for the indefinite form
1200: $ val = (x,y) = y^T x,
1201: where y^T denotes the transpose of y.
1203: Level: intermediate
1205: Concepts: inner product^multiple
1206: Concepts: vector^multiple inner products
1208: .seealso: VecMTDot(), VecDot()
1209: @*/
1210: PetscErrorCode VecMDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1211: {
1216: if (!nv) return(0);
1217: if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1226: PetscLogEventBarrierBegin(VEC_MDotBarrier,x,*y,0,0,PetscObjectComm((PetscObject)x));
1227: (*x->ops->mdot)(x,nv,y,val);
1228: PetscLogEventBarrierEnd(VEC_MDotBarrier,x,*y,0,0,PetscObjectComm((PetscObject)x));
1229: return(0);
1230: }
1234: /*@
1235: VecMAXPY - Computes y = y + sum alpha[j] x[j]
1237: Logically Collective on Vec
1239: Input Parameters:
1240: + nv - number of scalars and x-vectors
1241: . alpha - array of scalars
1242: . y - one vector
1243: - x - array of vectors
1245: Level: intermediate
1247: Notes: y cannot be any of the x vectors
1249: Concepts: BLAS
1251: .seealso: VecAXPY(), VecWAXPY(), VecAYPX()
1252: @*/
1253: PetscErrorCode VecMAXPY(Vec y,PetscInt nv,const PetscScalar alpha[],Vec x[])
1254: {
1256: PetscInt i;
1260: if (!nv) return(0);
1261: if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1271: PetscLogEventBegin(VEC_MAXPY,*x,y,0,0);
1272: (*y->ops->maxpy)(y,nv,alpha,x);
1273: PetscLogEventEnd(VEC_MAXPY,*x,y,0,0);
1274: PetscObjectStateIncrease((PetscObject)y);
1275: return(0);
1276: }
1280: /*@
1281: VecGetSubVector - Gets a vector representing part of another vector
1283: Collective on IS (and Vec if nonlocal entries are needed)
1285: Input Arguments:
1286: + X - vector from which to extract a subvector
1287: - is - index set representing portion of X to extract
1289: Output Arguments:
1290: . Y - subvector corresponding to is
1292: Level: advanced
1294: Notes:
1295: The subvector Y should be returned with VecRestoreSubVector().
1297: This function may return a subvector without making a copy, therefore it is not safe to use the original vector while
1298: modifying the subvector. Other non-overlapping subvectors can still be obtained from X using this function.
1300: .seealso: MatGetSubMatrix()
1301: @*/
1302: PetscErrorCode VecGetSubVector(Vec X,IS is,Vec *Y)
1303: {
1304: PetscErrorCode ierr;
1305: Vec Z;
1306: PetscObjectState state;
1312: if (X->ops->getsubvector) {
1313: (*X->ops->getsubvector)(X,is,&Z);
1314: } else { /* Default implementation currently does no caching */
1315: PetscInt gstart,gend,start;
1316: PetscBool contiguous,gcontiguous;
1317: VecGetOwnershipRange(X,&gstart,&gend);
1318: ISContiguousLocal(is,gstart,gend,&start,&contiguous);
1319: MPI_Allreduce(&contiguous,&gcontiguous,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));
1320: if (gcontiguous) { /* We can do a no-copy implementation */
1321: PetscInt n,N,bs;
1322: PetscScalar *x;
1323: PetscMPIInt size;
1324: ISGetLocalSize(is,&n);
1325: VecGetArray(X,&x);
1326: VecGetBlockSize(X,&bs);
1327: if (n%bs) bs = 1;
1328: MPI_Comm_size(PetscObjectComm((PetscObject)X),&size);
1329: if (size == 1) {
1330: VecCreateSeqWithArray(PetscObjectComm((PetscObject)X),bs,n,x+start,&Z);
1331: } else {
1332: ISGetSize(is,&N);
1333: VecCreateMPIWithArray(PetscObjectComm((PetscObject)X),bs,n,N,x+start,&Z);
1334: }
1335: VecRestoreArray(X,&x);
1336: } else { /* Have to create a scatter and do a copy */
1337: VecScatter scatter;
1338: PetscInt n,N;
1339: ISGetLocalSize(is,&n);
1340: ISGetSize(is,&N);
1341: VecCreate(PetscObjectComm((PetscObject)is),&Z);
1342: VecSetSizes(Z,n,N);
1343: VecSetType(Z,((PetscObject)X)->type_name);
1344: VecScatterCreate(X,is,Z,NULL,&scatter);
1345: VecScatterBegin(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
1346: VecScatterEnd(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
1347: VecScatterDestroy(&scatter);
1348: }
1349: }
1350: /* Record the state when the subvector was gotten so we know whether its values need to be put back */
1351: if (VecGetSubVectorSavedStateId < 0) {PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId);}
1352: PetscObjectStateGet((PetscObject)Z,&state);
1353: PetscObjectComposedDataSetInt((PetscObject)Z,VecGetSubVectorSavedStateId,state);
1354: *Y = Z;
1355: return(0);
1356: }
1360: /*@
1361: VecRestoreSubVector - Restores a subvector extracted using VecGetSubVector()
1363: Collective on IS (and Vec if nonlocal entries need to be written)
1365: Input Arguments:
1366: + X - vector from which subvector was obtained
1367: . is - index set representing the subset of X
1368: - Y - subvector being restored
1370: Level: advanced
1372: .seealso: VecGetSubVector()
1373: @*/
1374: PetscErrorCode VecRestoreSubVector(Vec X,IS is,Vec *Y)
1375: {
1383: if (X->ops->restoresubvector) {
1384: (*X->ops->restoresubvector)(X,is,Y);
1385: } else {
1386: PetscObjectState savedstate=0,newstate;
1387: PetscBool valid;
1388: PetscObjectComposedDataGetInt((PetscObject)*Y,VecGetSubVectorSavedStateId,savedstate,valid);
1389: PetscObjectStateGet((PetscObject)*Y,&newstate);
1390: if (valid && savedstate < newstate) {
1391: /* We might need to copy entries back, first check whether we have no-copy view */
1392: PetscInt gstart,gend,start;
1393: PetscBool contiguous,gcontiguous;
1394: VecGetOwnershipRange(X,&gstart,&gend);
1395: ISContiguousLocal(is,gstart,gend,&start,&contiguous);
1396: MPI_Allreduce(&contiguous,&gcontiguous,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));
1397: if (!gcontiguous) SETERRQ(PetscObjectComm((PetscObject)is),PETSC_ERR_SUP,"Unhandled case, values have been changed and need to be copied back into X");
1398: }
1399: VecDestroy(Y);
1400: }
1401: return(0);
1402: }
1406: /*@C
1407: VecGetArray - Returns a pointer to a contiguous array that contains this
1408: processor's portion of the vector data. For the standard PETSc
1409: vectors, VecGetArray() returns a pointer to the local data array and
1410: does not use any copies. If the underlying vector data is not stored
1411: in a contiquous array this routine will copy the data to a contiquous
1412: array and return a pointer to that. You MUST call VecRestoreArray()
1413: when you no longer need access to the array.
1415: Logically Collective on Vec
1417: Input Parameter:
1418: . x - the vector
1420: Output Parameter:
1421: . a - location to put pointer to the array
1423: Fortran Note:
1424: This routine is used differently from Fortran 77
1425: $ Vec x
1426: $ PetscScalar x_array(1)
1427: $ PetscOffset i_x
1428: $ PetscErrorCode ierr
1429: $ call VecGetArray(x,x_array,i_x,ierr)
1430: $
1431: $ Access first local entry in vector with
1432: $ value = x_array(i_x + 1)
1433: $
1434: $ ...... other code
1435: $ call VecRestoreArray(x,x_array,i_x,ierr)
1436: For Fortran 90 see VecGetArrayF90()
1438: See the Fortran chapter of the users manual and
1439: petsc/src/snes/examples/tutorials/ex5f.F for details.
1441: Level: beginner
1443: Concepts: vector^accessing local values
1445: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(), VecGetArray2d()
1446: @*/
1447: PetscErrorCode VecGetArray(Vec x,PetscScalar **a)
1448: {
1453: if (x->petscnative) {
1454: #if defined(PETSC_HAVE_CUSP)
1455: if (x->valid_GPU_array == PETSC_CUSP_GPU) {
1456: VecCUSPCopyFromGPU(x);
1457: }
1458: #endif
1459: #if defined(PETSC_HAVE_VIENNACL)
1460: if (x->valid_GPU_array == PETSC_VIENNACL_GPU) {
1461: VecViennaCLCopyFromGPU(x);
1462: }
1463: #endif
1464: *a = *((PetscScalar **)x->data);
1465: } else {
1466: (*x->ops->getarray)(x,a);
1467: }
1468: return(0);
1469: }
1473: /*@C
1474: VecGetArrayRead - Get read-only pointer to contiguous array containing this processor's portion of the vector data.
1476: Not Collective
1478: Input Parameters:
1479: . x - the vector
1481: Output Parameter:
1482: . a - the array
1484: Level: beginner
1486: Notes:
1487: The array must be returned using a matching call to VecRestoreArrayRead().
1489: Unlike VecGetArray(), this routine is not collective and preserves cached information like vector norms.
1491: Standard PETSc vectors use contiguous storage so that this routine does not perform a copy. Other vector
1492: implementations may require a copy, but must such implementations should cache the contiguous representation so that
1493: only one copy is performed when this routine is called multiple times in sequence.
1495: .seealso: VecGetArray(), VecRestoreArray()
1496: @*/
1497: PetscErrorCode VecGetArrayRead(Vec x,const PetscScalar **a)
1498: {
1503: if (x->petscnative) {
1504: #if defined(PETSC_HAVE_CUSP)
1505: if (x->valid_GPU_array == PETSC_CUSP_GPU) {
1506: VecCUSPCopyFromGPU(x);
1507: }
1508: #endif
1509: #if defined(PETSC_HAVE_VIENNACL)
1510: if (x->valid_GPU_array == PETSC_VIENNACL_GPU) {
1511: VecViennaCLCopyFromGPU(x);
1512: }
1513: #endif
1514: *a = *((PetscScalar **)x->data);
1515: } else if (x->ops->getarrayread) {
1516: (*x->ops->getarrayread)(x,a);
1517: } else {
1518: (*x->ops->getarray)(x,(PetscScalar**)a);
1519: }
1520: return(0);
1521: }
1525: /*@C
1526: VecGetArrays - Returns a pointer to the arrays in a set of vectors
1527: that were created by a call to VecDuplicateVecs(). You MUST call
1528: VecRestoreArrays() when you no longer need access to the array.
1530: Logically Collective on Vec
1532: Input Parameter:
1533: + x - the vectors
1534: - n - the number of vectors
1536: Output Parameter:
1537: . a - location to put pointer to the array
1539: Fortran Note:
1540: This routine is not supported in Fortran.
1542: Level: intermediate
1544: .seealso: VecGetArray(), VecRestoreArrays()
1545: @*/
1546: PetscErrorCode VecGetArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1547: {
1549: PetscInt i;
1550: PetscScalar **q;
1556: if (n <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must get at least one array n = %D",n);
1557: PetscMalloc1(n,&q);
1558: for (i=0; i<n; ++i) {
1559: VecGetArray(x[i],&q[i]);
1560: }
1561: *a = q;
1562: return(0);
1563: }
1567: /*@C
1568: VecRestoreArrays - Restores a group of vectors after VecGetArrays()
1569: has been called.
1571: Logically Collective on Vec
1573: Input Parameters:
1574: + x - the vector
1575: . n - the number of vectors
1576: - a - location of pointer to arrays obtained from VecGetArrays()
1578: Notes:
1579: For regular PETSc vectors this routine does not involve any copies. For
1580: any special vectors that do not store local vector data in a contiguous
1581: array, this routine will copy the data back into the underlying
1582: vector data structure from the arrays obtained with VecGetArrays().
1584: Fortran Note:
1585: This routine is not supported in Fortran.
1587: Level: intermediate
1589: .seealso: VecGetArrays(), VecRestoreArray()
1590: @*/
1591: PetscErrorCode VecRestoreArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1592: {
1594: PetscInt i;
1595: PetscScalar **q = *a;
1602: for (i=0; i<n; ++i) {
1603: VecRestoreArray(x[i],&q[i]);
1604: }
1605: PetscFree(q);
1606: return(0);
1607: }
1611: /*@C
1612: VecRestoreArray - Restores a vector after VecGetArray() has been called.
1614: Logically Collective on Vec
1616: Input Parameters:
1617: + x - the vector
1618: - a - location of pointer to array obtained from VecGetArray()
1620: Level: beginner
1622: Notes:
1623: For regular PETSc vectors this routine does not involve any copies. For
1624: any special vectors that do not store local vector data in a contiguous
1625: array, this routine will copy the data back into the underlying
1626: vector data structure from the array obtained with VecGetArray().
1628: This routine actually zeros out the a pointer. This is to prevent accidental
1629: us of the array after it has been restored. If you pass null for a it will
1630: not zero the array pointer a.
1632: Fortran Note:
1633: This routine is used differently from Fortran 77
1634: $ Vec x
1635: $ PetscScalar x_array(1)
1636: $ PetscOffset i_x
1637: $ PetscErrorCode ierr
1638: $ call VecGetArray(x,x_array,i_x,ierr)
1639: $
1640: $ Access first local entry in vector with
1641: $ value = x_array(i_x + 1)
1642: $
1643: $ ...... other code
1644: $ call VecRestoreArray(x,x_array,i_x,ierr)
1646: See the Fortran chapter of the users manual and
1647: petsc/src/snes/examples/tutorials/ex5f.F for details.
1648: For Fortran 90 see VecRestoreArrayF90()
1650: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(), VecRestoreArray2d()
1651: @*/
1652: PetscErrorCode VecRestoreArray(Vec x,PetscScalar **a)
1653: {
1658: if (x->petscnative) {
1659: #if defined(PETSC_HAVE_CUSP)
1660: x->valid_GPU_array = PETSC_CUSP_CPU;
1661: #endif
1662: #if defined(PETSC_HAVE_VIENNACL)
1663: x->valid_GPU_array = PETSC_VIENNACL_CPU;
1664: #endif
1665: } else {
1666: (*x->ops->restorearray)(x,a);
1667: }
1668: if (a) *a = NULL;
1669: PetscObjectStateIncrease((PetscObject)x);
1670: return(0);
1671: }
1675: /*@C
1676: VecRestoreArrayRead - Restore array obtained with VecGetArrayRead()
1678: Not Collective
1680: Input Parameters:
1681: + vec - the vector
1682: - array - the array
1684: Level: beginner
1686: .seealso: VecGetArray(), VecRestoreArray()
1687: @*/
1688: PetscErrorCode VecRestoreArrayRead(Vec x,const PetscScalar **a)
1689: {
1694: if (x->petscnative) {
1695: #if defined(PETSC_HAVE_VIENNACL)
1696: x->valid_GPU_array = PETSC_VIENNACL_CPU;
1697: #endif
1698: } else if (x->ops->restorearrayread) {
1699: (*x->ops->restorearrayread)(x,a);
1700: } else {
1701: (*x->ops->restorearray)(x,(PetscScalar**)a);
1702: }
1703: if (a) *a = NULL;
1704: return(0);
1705: }
1709: /*@
1710: VecPlaceArray - Allows one to replace the array in a vector with an
1711: array provided by the user. This is useful to avoid copying an array
1712: into a vector.
1714: Not Collective
1716: Input Parameters:
1717: + vec - the vector
1718: - array - the array
1720: Notes:
1721: You can return to the original array with a call to VecResetArray()
1723: Level: developer
1725: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray()
1727: @*/
1728: PetscErrorCode VecPlaceArray(Vec vec,const PetscScalar array[])
1729: {
1736: if (vec->ops->placearray) {
1737: (*vec->ops->placearray)(vec,array);
1738: } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot place array in this type of vector");
1739: PetscObjectStateIncrease((PetscObject)vec);
1740: return(0);
1741: }
1745: /*@C
1746: VecReplaceArray - Allows one to replace the array in a vector with an
1747: array provided by the user. This is useful to avoid copying an array
1748: into a vector.
1750: Not Collective
1752: Input Parameters:
1753: + vec - the vector
1754: - array - the array
1756: Notes:
1757: This permanently replaces the array and frees the memory associated
1758: with the old array.
1760: The memory passed in MUST be obtained with PetscMalloc() and CANNOT be
1761: freed by the user. It will be freed when the vector is destroy.
1763: Not supported from Fortran
1765: Level: developer
1767: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray()
1769: @*/
1770: PetscErrorCode VecReplaceArray(Vec vec,const PetscScalar array[])
1771: {
1777: if (vec->ops->replacearray) {
1778: (*vec->ops->replacearray)(vec,array);
1779: } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot replace array in this type of vector");
1780: PetscObjectStateIncrease((PetscObject)vec);
1781: return(0);
1782: }
1784: /*MC
1785: VecDuplicateVecsF90 - Creates several vectors of the same type as an existing vector
1786: and makes them accessible via a Fortran90 pointer.
1788: Synopsis:
1789: VecDuplicateVecsF90(Vec x,PetscInt n,{Vec, pointer :: y(:)},integer ierr)
1791: Collective on Vec
1793: Input Parameters:
1794: + x - a vector to mimic
1795: - n - the number of vectors to obtain
1797: Output Parameters:
1798: + y - Fortran90 pointer to the array of vectors
1799: - ierr - error code
1801: Example of Usage:
1802: .vb
1803: Vec x
1804: Vec, pointer :: y(:)
1805: ....
1806: call VecDuplicateVecsF90(x,2,y,ierr)
1807: call VecSet(y(2),alpha,ierr)
1808: call VecSet(y(2),alpha,ierr)
1809: ....
1810: call VecDestroyVecsF90(2,y,ierr)
1811: .ve
1813: Notes:
1814: Not yet supported for all F90 compilers
1816: Use VecDestroyVecsF90() to free the space.
1818: Level: beginner
1820: .seealso: VecDestroyVecsF90(), VecDuplicateVecs()
1822: M*/
1824: /*MC
1825: VecRestoreArrayF90 - Restores a vector to a usable state after a call to
1826: VecGetArrayF90().
1828: Synopsis:
1829: VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
1831: Logically Collective on Vec
1833: Input Parameters:
1834: + x - vector
1835: - xx_v - the Fortran90 pointer to the array
1837: Output Parameter:
1838: . ierr - error code
1840: Example of Usage:
1841: .vb
1842: PetscScalar, pointer :: xx_v(:)
1843: ....
1844: call VecGetArrayF90(x,xx_v,ierr)
1845: a = xx_v(3)
1846: call VecRestoreArrayF90(x,xx_v,ierr)
1847: .ve
1849: Level: beginner
1851: .seealso: VecGetArrayF90(), VecGetArray(), VecRestoreArray(), UsingFortran
1853: M*/
1855: /*MC
1856: VecDestroyVecsF90 - Frees a block of vectors obtained with VecDuplicateVecsF90().
1858: Synopsis:
1859: VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)
1861: Collective on Vec
1863: Input Parameters:
1864: + n - the number of vectors previously obtained
1865: - x - pointer to array of vector pointers
1867: Output Parameter:
1868: . ierr - error code
1870: Notes:
1871: Not yet supported for all F90 compilers
1873: Level: beginner
1875: .seealso: VecDestroyVecs(), VecDuplicateVecsF90()
1877: M*/
1879: /*MC
1880: VecGetArrayF90 - Accesses a vector array from Fortran90. For default PETSc
1881: vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
1882: this routine is implementation dependent. You MUST call VecRestoreArrayF90()
1883: when you no longer need access to the array.
1885: Synopsis:
1886: VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
1888: Logically Collective on Vec
1890: Input Parameter:
1891: . x - vector
1893: Output Parameters:
1894: + xx_v - the Fortran90 pointer to the array
1895: - ierr - error code
1897: Example of Usage:
1898: .vb
1899: PetscScalar, pointer :: xx_v(:)
1900: ....
1901: call VecGetArrayF90(x,xx_v,ierr)
1902: a = xx_v(3)
1903: call VecRestoreArrayF90(x,xx_v,ierr)
1904: .ve
1906: Level: beginner
1908: .seealso: VecRestoreArrayF90(), VecGetArray(), VecRestoreArray(), UsingFortran
1910: M*/
1915: /*@C
1916: VecGetArray2d - Returns a pointer to a 2d contiguous array that contains this
1917: processor's portion of the vector data. You MUST call VecRestoreArray2d()
1918: when you no longer need access to the array.
1920: Logically Collective
1922: Input Parameter:
1923: + x - the vector
1924: . m - first dimension of two dimensional array
1925: . n - second dimension of two dimensional array
1926: . mstart - first index you will use in first coordinate direction (often 0)
1927: - nstart - first index in the second coordinate direction (often 0)
1929: Output Parameter:
1930: . a - location to put pointer to the array
1932: Level: developer
1934: Notes:
1935: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
1936: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
1937: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
1938: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
1940: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
1942: Concepts: vector^accessing local values as 2d array
1944: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
1945: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
1946: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1947: @*/
1948: PetscErrorCode VecGetArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
1949: {
1951: PetscInt i,N;
1952: PetscScalar *aa;
1958: VecGetLocalSize(x,&N);
1959: 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);
1960: VecGetArray(x,&aa);
1962: PetscMalloc1(m,a);
1963: for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
1964: *a -= mstart;
1965: return(0);
1966: }
1970: /*@C
1971: VecRestoreArray2d - Restores a vector after VecGetArray2d() has been called.
1973: Logically Collective
1975: Input Parameters:
1976: + x - the vector
1977: . m - first dimension of two dimensional array
1978: . n - second dimension of the two dimensional array
1979: . mstart - first index you will use in first coordinate direction (often 0)
1980: . nstart - first index in the second coordinate direction (often 0)
1981: - a - location of pointer to array obtained from VecGetArray2d()
1983: Level: developer
1985: Notes:
1986: For regular PETSc vectors this routine does not involve any copies. For
1987: any special vectors that do not store local vector data in a contiguous
1988: array, this routine will copy the data back into the underlying
1989: vector data structure from the array obtained with VecGetArray().
1991: This routine actually zeros out the a pointer.
1993: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
1994: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
1995: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
1996: @*/
1997: PetscErrorCode VecRestoreArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
1998: {
2000: void *dummy;
2006: dummy = (void*)(*a + mstart);
2007: PetscFree(dummy);
2008: VecRestoreArray(x,NULL);
2009: return(0);
2010: }
2014: /*@C
2015: VecGetArray1d - Returns a pointer to a 1d contiguous array that contains this
2016: processor's portion of the vector data. You MUST call VecRestoreArray1d()
2017: when you no longer need access to the array.
2019: Logically Collective
2021: Input Parameter:
2022: + x - the vector
2023: . m - first dimension of two dimensional array
2024: - mstart - first index you will use in first coordinate direction (often 0)
2026: Output Parameter:
2027: . a - location to put pointer to the array
2029: Level: developer
2031: Notes:
2032: For a vector obtained from DMCreateLocalVector() mstart are likely
2033: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2034: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
2036: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2038: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2039: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2040: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2041: @*/
2042: PetscErrorCode VecGetArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2043: {
2045: PetscInt N;
2051: VecGetLocalSize(x,&N);
2052: if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
2053: VecGetArray(x,a);
2054: *a -= mstart;
2055: return(0);
2056: }
2060: /*@C
2061: VecRestoreArray1d - Restores a vector after VecGetArray1d() has been called.
2063: Logically Collective
2065: Input Parameters:
2066: + x - the vector
2067: . m - first dimension of two dimensional array
2068: . mstart - first index you will use in first coordinate direction (often 0)
2069: - a - location of pointer to array obtained from VecGetArray21()
2071: Level: developer
2073: Notes:
2074: For regular PETSc vectors this routine does not involve any copies. For
2075: any special vectors that do not store local vector data in a contiguous
2076: array, this routine will copy the data back into the underlying
2077: vector data structure from the array obtained with VecGetArray1d().
2079: This routine actually zeros out the a pointer.
2081: Concepts: vector^accessing local values as 1d array
2083: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2084: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2085: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
2086: @*/
2087: PetscErrorCode VecRestoreArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2088: {
2094: VecRestoreArray(x,NULL);
2095: return(0);
2096: }
2101: /*@C
2102: VecGetArray3d - Returns a pointer to a 3d contiguous array that contains this
2103: processor's portion of the vector data. You MUST call VecRestoreArray3d()
2104: when you no longer need access to the array.
2106: Logically Collective
2108: Input Parameter:
2109: + x - the vector
2110: . m - first dimension of three dimensional array
2111: . n - second dimension of three dimensional array
2112: . p - third dimension of three dimensional array
2113: . mstart - first index you will use in first coordinate direction (often 0)
2114: . nstart - first index in the second coordinate direction (often 0)
2115: - pstart - first index in the third coordinate direction (often 0)
2117: Output Parameter:
2118: . a - location to put pointer to the array
2120: Level: developer
2122: Notes:
2123: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
2124: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2125: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
2126: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
2128: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2130: Concepts: vector^accessing local values as 3d array
2132: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2133: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2134: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2135: @*/
2136: PetscErrorCode VecGetArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
2137: {
2139: PetscInt i,N,j;
2140: PetscScalar *aa,**b;
2146: VecGetLocalSize(x,&N);
2147: 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);
2148: VecGetArray(x,&aa);
2150: PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
2151: b = (PetscScalar**)((*a) + m);
2152: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
2153: for (i=0; i<m; i++)
2154: for (j=0; j<n; j++)
2155: b[i*n+j] = aa + i*n*p + j*p - pstart;
2157: *a -= mstart;
2158: return(0);
2159: }
2163: /*@C
2164: VecRestoreArray3d - Restores a vector after VecGetArray3d() has been called.
2166: Logically Collective
2168: Input Parameters:
2169: + x - the vector
2170: . m - first dimension of three dimensional array
2171: . n - second dimension of the three dimensional array
2172: . p - third dimension of the three dimensional array
2173: . mstart - first index you will use in first coordinate direction (often 0)
2174: . nstart - first index in the second coordinate direction (often 0)
2175: . pstart - first index in the third coordinate direction (often 0)
2176: - a - location of pointer to array obtained from VecGetArray3d()
2178: Level: developer
2180: Notes:
2181: For regular PETSc vectors this routine does not involve any copies. For
2182: any special vectors that do not store local vector data in a contiguous
2183: array, this routine will copy the data back into the underlying
2184: vector data structure from the array obtained with VecGetArray().
2186: This routine actually zeros out the a pointer.
2188: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2189: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2190: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
2191: @*/
2192: PetscErrorCode VecRestoreArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
2193: {
2195: void *dummy;
2201: dummy = (void*)(*a + mstart);
2202: PetscFree(dummy);
2203: VecRestoreArray(x,NULL);
2204: return(0);
2205: }
2209: /*@C
2210: VecGetArray4d - Returns a pointer to a 4d contiguous array that contains this
2211: processor's portion of the vector data. You MUST call VecRestoreArray4d()
2212: when you no longer need access to the array.
2214: Logically Collective
2216: Input Parameter:
2217: + x - the vector
2218: . m - first dimension of four dimensional array
2219: . n - second dimension of four dimensional array
2220: . p - third dimension of four dimensional array
2221: . q - fourth dimension of four dimensional array
2222: . mstart - first index you will use in first coordinate direction (often 0)
2223: . nstart - first index in the second coordinate direction (often 0)
2224: . pstart - first index in the third coordinate direction (often 0)
2225: - qstart - first index in the fourth coordinate direction (often 0)
2227: Output Parameter:
2228: . a - location to put pointer to the array
2230: Level: beginner
2232: Notes:
2233: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
2234: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2235: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
2236: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
2238: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2240: Concepts: vector^accessing local values as 3d array
2242: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2243: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2244: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2245: @*/
2246: PetscErrorCode VecGetArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
2247: {
2249: PetscInt i,N,j,k;
2250: PetscScalar *aa,***b,**c;
2256: VecGetLocalSize(x,&N);
2257: 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);
2258: VecGetArray(x,&aa);
2260: PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
2261: b = (PetscScalar***)((*a) + m);
2262: c = (PetscScalar**)(b + m*n);
2263: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
2264: for (i=0; i<m; i++)
2265: for (j=0; j<n; j++)
2266: b[i*n+j] = c + i*n*p + j*p - pstart;
2267: for (i=0; i<m; i++)
2268: for (j=0; j<n; j++)
2269: for (k=0; k<p; k++)
2270: c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
2271: *a -= mstart;
2272: return(0);
2273: }
2277: /*@C
2278: VecRestoreArray4d - Restores a vector after VecGetArray3d() has been called.
2280: Logically Collective
2282: Input Parameters:
2283: + x - the vector
2284: . m - first dimension of four dimensional array
2285: . n - second dimension of the four dimensional array
2286: . p - third dimension of the four dimensional array
2287: . q - fourth dimension of the four dimensional array
2288: . mstart - first index you will use in first coordinate direction (often 0)
2289: . nstart - first index in the second coordinate direction (often 0)
2290: . pstart - first index in the third coordinate direction (often 0)
2291: . qstart - first index in the fourth coordinate direction (often 0)
2292: - a - location of pointer to array obtained from VecGetArray4d()
2294: Level: beginner
2296: Notes:
2297: For regular PETSc vectors this routine does not involve any copies. For
2298: any special vectors that do not store local vector data in a contiguous
2299: array, this routine will copy the data back into the underlying
2300: vector data structure from the array obtained with VecGetArray().
2302: This routine actually zeros out the a pointer.
2304: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2305: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2306: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
2307: @*/
2308: PetscErrorCode VecRestoreArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
2309: {
2311: void *dummy;
2317: dummy = (void*)(*a + mstart);
2318: PetscFree(dummy);
2319: VecRestoreArray(x,NULL);
2320: return(0);
2321: }