Actual source code: rvector.c
1: /*
2: Provides the interface functions for vector operations that have PetscScalar/PetscReal in the signature
3: These are the vector functions the user calls.
4: */
5: #include "petsc/private/sfimpl.h"
6: #include "petscsystypes.h"
7: #include <petsc/private/vecimpl.h>
9: PetscInt VecGetSubVectorSavedStateId = -1;
11: #if PetscDefined(USE_DEBUG)
12: // this is a no-op '0' macro in optimized builds
13: PetscErrorCode VecValidValues_Internal(Vec vec, PetscInt argnum, PetscBool begin)
14: {
15: PetscFunctionBegin;
16: if (vec->petscnative || vec->ops->getarray) {
17: PetscInt n;
18: const PetscScalar *x;
19: PetscOffloadMask mask;
21: PetscCall(VecGetOffloadMask(vec, &mask));
22: if (!PetscOffloadHost(mask)) PetscFunctionReturn(PETSC_SUCCESS);
23: PetscCall(VecGetLocalSize(vec, &n));
24: PetscCall(VecGetArrayRead(vec, &x));
25: for (PetscInt i = 0; i < n; i++) {
26: if (begin) {
27: PetscCheck(!PetscIsInfOrNanScalar(x[i]), PETSC_COMM_SELF, PETSC_ERR_FP, "Vec entry at local location %" PetscInt_FMT " is not-a-number or infinite at beginning of function: Parameter number %" PetscInt_FMT, i, argnum);
28: } else {
29: PetscCheck(!PetscIsInfOrNanScalar(x[i]), PETSC_COMM_SELF, PETSC_ERR_FP, "Vec entry at local location %" PetscInt_FMT " is not-a-number or infinite at end of function: Parameter number %" PetscInt_FMT, i, argnum);
30: }
31: }
32: PetscCall(VecRestoreArrayRead(vec, &x));
33: }
34: PetscFunctionReturn(PETSC_SUCCESS);
35: }
36: #endif
38: /*@
39: VecMaxPointwiseDivide - Computes the maximum of the componentwise division `max = max_i abs(x[i]/y[i])`.
41: Logically Collective
43: Input Parameters:
44: + x - the numerators
45: - y - the denominators
47: Output Parameter:
48: . max - the result
50: Level: advanced
52: Notes:
53: `x` and `y` may be the same vector
55: if a particular `y[i]` is zero, it is treated as 1 in the above formula
57: .seealso: [](chapter_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMax()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`
58: @*/
59: PetscErrorCode VecMaxPointwiseDivide(Vec x, Vec y, PetscReal *max)
60: {
61: PetscFunctionBegin;
67: PetscCheckSameTypeAndComm(x, 1, y, 2);
68: VecCheckSameSize(x, 1, y, 2);
69: VecCheckAssembled(x);
70: VecCheckAssembled(y);
71: PetscCall(VecLockReadPush(x));
72: PetscCall(VecLockReadPush(y));
73: PetscUseTypeMethod(x, maxpointwisedivide, y, max);
74: PetscCall(VecLockReadPop(x));
75: PetscCall(VecLockReadPop(y));
76: PetscFunctionReturn(PETSC_SUCCESS);
77: }
79: /*@
80: VecDot - Computes the vector dot product.
82: Collective
84: Input Parameters:
85: + x - first vector
86: - y - second vector
88: Output Parameter:
89: . val - the dot product
91: Performance Issues:
92: .vb
93: per-processor memory bandwidth
94: interprocessor latency
95: work load imbalance that causes certain processes to arrive much earlier than others
96: .ve
98: Level: intermediate
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: .seealso: [](chapter_vectors), `Vec`, `VecMDot()`, `VecTDot()`, `VecNorm()`, `VecDotBegin()`, `VecDotEnd()`, `VecDotRealPart()`
112: @*/
113: PetscErrorCode VecDot(Vec x, Vec y, PetscScalar *val)
114: {
115: PetscFunctionBegin;
121: PetscCheckSameTypeAndComm(x, 1, y, 2);
122: VecCheckSameSize(x, 1, y, 2);
123: VecCheckAssembled(x);
124: VecCheckAssembled(y);
126: PetscCall(VecLockReadPush(x));
127: PetscCall(VecLockReadPush(y));
128: PetscCall(PetscLogEventBegin(VEC_Dot, x, y, 0, 0));
129: PetscUseTypeMethod(x, dot, y, val);
130: PetscCall(PetscLogEventEnd(VEC_Dot, x, y, 0, 0));
131: PetscCall(VecLockReadPop(x));
132: PetscCall(VecLockReadPop(y));
133: PetscFunctionReturn(PETSC_SUCCESS);
134: }
136: /*@
137: VecDotRealPart - Computes the real part of the vector dot product.
139: Collective
141: Input Parameters:
142: + x - first vector
143: - y - second vector
145: Output Parameter:
146: . val - the real part of the dot product;
148: Level: intermediate
150: Performance Issues:
151: .vb
152: per-processor memory bandwidth
153: interprocessor latency
154: work load imbalance that causes certain processes to arrive much earlier than others
155: .ve
157: Notes for Users of Complex Numbers:
158: See `VecDot()` for more details on the definition of the dot product for complex numbers
160: For real numbers this returns the same value as `VecDot()`
162: 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
163: the space R^{2n} (that is a vector of 2n components with the real or imaginary part of the complex numbers for components)
165: Developer Note:
166: This is not currently optimized to compute only the real part of the dot product.
168: .seealso: [](chapter_vectors), `Vec`, `VecMDot()`, `VecTDot()`, `VecNorm()`, `VecDotBegin()`, `VecDotEnd()`, `VecDot()`, `VecDotNorm2()`
169: @*/
170: PetscErrorCode VecDotRealPart(Vec x, Vec y, PetscReal *val)
171: {
172: PetscScalar fdot;
174: PetscFunctionBegin;
175: PetscCall(VecDot(x, y, &fdot));
176: *val = PetscRealPart(fdot);
177: PetscFunctionReturn(PETSC_SUCCESS);
178: }
180: /*@
181: VecNorm - Computes the vector norm.
183: Collective
185: Input Parameters:
186: + x - the vector
187: - type - the type of the norm requested
189: Output Parameter:
190: . val - the norm
192: Values of NormType:
193: + `NORM_1` - sum_i |x[i]|
194: . `NORM_2` - sqrt(sum_i |x[i]|^2)
195: . `NORM_INFINITY` - max_i |x[i]|
196: - `NORM_1_AND_2` - computes efficiently both `NORM_1` and `NORM_2` and stores them each in an output array
198: Level: intermediate
200: Notes:
201: For complex numbers `NORM_1` will return the traditional 1 norm of the 2 norm of the complex numbers; that is the 1
202: norm of the absolute values of the complex entries. In PETSc 3.6 and earlier releases it returned the 1 norm of
203: the 1 norm of the complex entries (what is returned by the BLAS routine asum()). Both are valid norms but most
204: people expect the former.
206: This routine stashes the computed norm value, repeated calls before the vector entries are changed are then rapid since the
207: precomputed value is immediately available. Certain vector operations such as `VecSet()` store the norms so the value is
208: immediately available and does not need to be explicitly computed. `VecScale()` updates any stashed norm values, thus calls after `VecScale()`
209: do not need to explicitly recompute the norm.
211: Performance Issues:
212: + per-processor memory bandwidth - limits the speed of the computation of local portion of the norm
213: . interprocessor latency - limits the accumulation of the result across ranks, .i.e. MPI_Allreduce() time
214: . number of ranks - the time for the result will grow with the log base 2 of the number of ranks sharing the vector
215: - work load imbalance - the rank with the largest number of vector entries will limit the speed up
217: .seealso: [](chapter_vectors), `Vec`, `NormType`, `VecDot()`, `VecTDot()`, `VecDotBegin()`, `VecDotEnd()`, `VecNormAvailable()`,
218: `VecNormBegin()`, `VecNormEnd()`, `NormType()`
219: @*/
220: PetscErrorCode VecNorm(Vec x, NormType type, PetscReal *val)
221: {
222: PetscBool flg = PETSC_TRUE;
224: PetscFunctionBegin;
227: VecCheckAssembled(x);
231: /* Cached data? */
232: PetscCall(VecNormAvailable(x, type, &flg, val));
233: if (flg) PetscFunctionReturn(PETSC_SUCCESS);
235: PetscCall(VecLockReadPush(x));
236: PetscCall(PetscLogEventBegin(VEC_Norm, x, 0, 0, 0));
237: PetscUseTypeMethod(x, norm, type, val);
238: PetscCall(PetscLogEventEnd(VEC_Norm, x, 0, 0, 0));
239: PetscCall(VecLockReadPop(x));
241: if (type != NORM_1_AND_2) PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[type], *val));
242: PetscFunctionReturn(PETSC_SUCCESS);
243: }
245: /*@
246: VecNormAvailable - Returns the vector norm if it is already known. That is, it has been previously computed and cached in the vector
248: Not Collective
250: Input Parameters:
251: + x - the vector
252: - type - one of `NORM_1` (sum_i |x[i]|), `NORM_2` sqrt(sum_i (x[i])^2), `NORM_INFINITY` max_i |x[i]|. Also available
253: `NORM_1_AND_2`, which computes both norms and stores them
254: in a two element array.
256: Output Parameters:
257: + available - `PETSC_TRUE` if the val returned is valid
258: - val - the norm
260: Level: intermediate
262: Performance Issues:
263: .vb
264: per-processor memory bandwidth
265: interprocessor latency
266: work load imbalance that causes certain processes to arrive much earlier than others
267: .ve
269: Developer Note:
270: `PETSC_HAVE_SLOW_BLAS_NORM2` will cause a C (loop unrolled) version of the norm to be used, rather
271: than the BLAS. This should probably only be used when one is using the FORTRAN BLAS routines
272: (as opposed to vendor provided) because the FORTRAN BLAS `NRM2()` routine is very slow.
274: .seealso: [](chapter_vectors), `Vec`, `VecDot()`, `VecTDot()`, `VecNorm()`, `VecDotBegin()`, `VecDotEnd()`,
275: `VecNormBegin()`, `VecNormEnd()`
276: @*/
277: PetscErrorCode VecNormAvailable(Vec x, NormType type, PetscBool *available, PetscReal *val)
278: {
279: PetscFunctionBegin;
285: if (type == NORM_1_AND_2) {
286: *available = PETSC_FALSE;
287: } else {
288: PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[type], *val, *available));
289: }
290: PetscFunctionReturn(PETSC_SUCCESS);
291: }
293: /*@
294: VecNormalize - Normalizes a vector by its 2-norm.
296: Collective
298: Input Parameter:
299: . x - the vector
301: Output Parameter:
302: . val - the vector norm before normalization. May be `NULL` if the value is not needed.
304: Level: intermediate
306: .seealso: [](chapter_vectors), `Vec`, `VecNorm()`, `NORM_2`, `NormType`
307: @*/
308: PetscErrorCode VecNormalize(Vec x, PetscReal *val)
309: {
310: PetscReal norm;
312: PetscFunctionBegin;
315: PetscCall(VecSetErrorIfLocked(x, 1));
317: PetscCall(PetscLogEventBegin(VEC_Normalize, x, 0, 0, 0));
318: PetscCall(VecNorm(x, NORM_2, &norm));
319: if (norm == 0.0) {
320: PetscCall(PetscInfo(x, "Vector of zero norm can not be normalized; Returning only the zero norm\n"));
321: } else if (norm != 1.0) {
322: PetscCall(VecScale(x, 1.0 / norm));
323: }
324: PetscCall(PetscLogEventEnd(VEC_Normalize, x, 0, 0, 0));
325: if (val) *val = norm;
326: PetscFunctionReturn(PETSC_SUCCESS);
327: }
329: /*@C
330: VecMax - Determines the vector component with maximum real part and its location.
332: Collective
334: Input Parameter:
335: . x - the vector
337: Output Parameters:
338: + p - the index of `val` (pass `NULL` if you don't want this) in the vector
339: - val - the maximum component
341: Level: intermediate
343: Notes:
344: Returns the value `PETSC_MIN_REAL` and negative `p` if the vector is of length 0.
346: Returns the smallest index with the maximum value
348: .seealso: [](chapter_vectors), `Vec`, `VecNorm()`, `VecMin()`
349: @*/
350: PetscErrorCode VecMax(Vec x, PetscInt *p, PetscReal *val)
351: {
352: PetscFunctionBegin;
355: VecCheckAssembled(x);
358: PetscCall(VecLockReadPush(x));
359: PetscCall(PetscLogEventBegin(VEC_Max, x, 0, 0, 0));
360: PetscUseTypeMethod(x, max, p, val);
361: PetscCall(PetscLogEventEnd(VEC_Max, x, 0, 0, 0));
362: PetscCall(VecLockReadPop(x));
363: PetscFunctionReturn(PETSC_SUCCESS);
364: }
366: /*@C
367: VecMin - Determines the vector component with minimum real part and its location.
369: Collective
371: Input Parameter:
372: . x - the vector
374: Output Parameters:
375: + p - the index of `val` (pass `NULL` if you don't want this location) in the vector
376: - val - the minimum component
378: Level: intermediate
380: Notes:
381: Returns the value `PETSC_MAX_REAL` and negative `p` if the vector is of length 0.
383: This returns the smallest index with the minimum value
385: .seealso: [](chapter_vectors), `Vec`, `VecMax()`
386: @*/
387: PetscErrorCode VecMin(Vec x, PetscInt *p, PetscReal *val)
388: {
389: PetscFunctionBegin;
392: VecCheckAssembled(x);
395: PetscCall(VecLockReadPush(x));
396: PetscCall(PetscLogEventBegin(VEC_Min, x, 0, 0, 0));
397: PetscUseTypeMethod(x, min, p, val);
398: PetscCall(PetscLogEventEnd(VEC_Min, x, 0, 0, 0));
399: PetscCall(VecLockReadPop(x));
400: PetscFunctionReturn(PETSC_SUCCESS);
401: }
403: /*@
404: VecTDot - Computes an indefinite vector dot product. That is, this
405: routine does NOT use the complex conjugate.
407: Collective
409: Input Parameters:
410: + x - first vector
411: - y - second vector
413: Output Parameter:
414: . val - the dot product
416: Level: intermediate
418: Notes for Users of Complex Numbers:
419: For complex vectors, VecTDot() computes the indefinite form
420: $ val = (x,y) = y^T x,
421: where y^T denotes the transpose of y.
423: Use VecDot() for the inner product
424: $ val = (x,y) = y^H x,
425: where y^H denotes the conjugate transpose of y.
427: .seealso: [](chapter_vectors), `Vec`, `VecDot()`, `VecMTDot()`
428: @*/
429: PetscErrorCode VecTDot(Vec x, Vec y, PetscScalar *val)
430: {
431: PetscFunctionBegin;
437: PetscCheckSameTypeAndComm(x, 1, y, 2);
438: VecCheckSameSize(x, 1, y, 2);
439: VecCheckAssembled(x);
440: VecCheckAssembled(y);
442: PetscCall(VecLockReadPush(x));
443: PetscCall(VecLockReadPush(y));
444: PetscCall(PetscLogEventBegin(VEC_TDot, x, y, 0, 0));
445: PetscUseTypeMethod(x, tdot, y, val);
446: PetscCall(PetscLogEventEnd(VEC_TDot, x, y, 0, 0));
447: PetscCall(VecLockReadPop(x));
448: PetscCall(VecLockReadPop(y));
449: PetscFunctionReturn(PETSC_SUCCESS);
450: }
452: /*@
453: VecScale - Scales a vector.
455: Not Collective
457: Input Parameters:
458: + x - the vector
459: - alpha - the scalar
461: Level: intermediate
463: Note:
464: For a vector with n components, `VecScale()` computes x[i] = alpha * x[i], for i=1,...,n.
466: .seealso: [](chapter_vectors), `Vec`, `VecSet()`
467: @*/
468: PetscErrorCode VecScale(Vec x, PetscScalar alpha)
469: {
470: PetscReal norms[4];
471: PetscBool flgs[4];
473: PetscFunctionBegin;
476: VecCheckAssembled(x);
477: PetscCall(VecSetErrorIfLocked(x, 1));
478: if (alpha == (PetscScalar)1.0) PetscFunctionReturn(PETSC_SUCCESS);
480: /* get current stashed norms */
481: for (PetscInt i = 0; i < 4; i++) PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], norms[i], flgs[i]));
483: PetscCall(PetscLogEventBegin(VEC_Scale, x, 0, 0, 0));
484: PetscUseTypeMethod(x, scale, alpha);
485: PetscCall(PetscLogEventEnd(VEC_Scale, x, 0, 0, 0));
487: PetscCall(PetscObjectStateIncrease((PetscObject)x));
488: /* put the scaled stashed norms back into the Vec */
489: for (PetscInt i = 0; i < 4; i++) {
490: if (flgs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[i], PetscAbsScalar(alpha) * norms[i]));
491: }
492: PetscFunctionReturn(PETSC_SUCCESS);
493: }
495: /*@
496: VecSet - Sets all components of a vector to a single scalar value.
498: Logically Collective
500: Input Parameters:
501: + x - the vector
502: - alpha - the scalar
504: Level: beginner
506: Notes:
507: For a vector of dimension n, `VecSet()` sets x[i] = alpha, for i=1,...,n,
508: so that all vector entries then equal the identical
509: scalar value, `alpha`. Use the more general routine
510: `VecSetValues()` to set different vector entries.
512: You CANNOT call this after you have called `VecSetValues()` but before you call
513: `VecAssemblyBegin()`
515: .seealso: [](chapter_vectors), `Vec`, `VecSetValues()`, `VecSetValuesBlocked()`, `VecSetRandom()`
516: @*/
517: PetscErrorCode VecSet(Vec x, PetscScalar alpha)
518: {
519: PetscFunctionBegin;
522: VecCheckAssembled(x);
524: PetscCall(VecSetErrorIfLocked(x, 1));
526: PetscCall(PetscLogEventBegin(VEC_Set, x, 0, 0, 0));
527: PetscUseTypeMethod(x, set, alpha);
528: PetscCall(PetscLogEventEnd(VEC_Set, x, 0, 0, 0));
529: PetscCall(PetscObjectStateIncrease((PetscObject)x));
531: /* norms can be simply set (if |alpha|*N not too large) */
533: {
534: PetscReal val = PetscAbsScalar(alpha);
535: const PetscInt N = x->map->N;
537: if (N == 0) {
538: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_1], 0.0l));
539: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_INFINITY], 0.0));
540: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_2], 0.0));
541: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_FROBENIUS], 0.0));
542: } else if (val > PETSC_MAX_REAL / N) {
543: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_INFINITY], val));
544: } else {
545: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_1], N * val));
546: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_INFINITY], val));
547: val *= PetscSqrtReal((PetscReal)N);
548: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_2], val));
549: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_FROBENIUS], val));
550: }
551: }
552: PetscFunctionReturn(PETSC_SUCCESS);
553: }
555: /*@
556: VecAXPY - Computes `y = alpha x + y`.
558: Logically Collective
560: Input Parameters:
561: + alpha - the scalar
562: . x - vector scale by `alpha`
563: - y - vector accumulated into
565: Output Parameter:
566: . y - output vector
568: Level: intermediate
570: Notes:
571: This routine is optimized for alpha of 0.0, otherwise it calls the BLAS routine
572: .vb
573: VecAXPY(y,alpha,x) y = alpha x + y
574: VecAYPX(y,beta,x) y = x + beta y
575: VecAXPBY(y,alpha,beta,x) y = alpha x + beta y
576: VecWAXPY(w,alpha,x,y) w = alpha x + y
577: VecAXPBYPCZ(w,alpha,beta,gamma,x,y) z = alpha x + beta y + gamma z
578: VecMAXPY(y,nv,alpha[],x[]) y = sum alpha[i] x[i] + y
579: .ve
581: .seealso: [](chapter_vectors), `Vec`, `VecAYPX()`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPBYPCZ()`, `VecAXPBY()`
582: @*/
583: PetscErrorCode VecAXPY(Vec y, PetscScalar alpha, Vec x)
584: {
585: PetscFunctionBegin;
590: PetscCheckSameTypeAndComm(x, 3, y, 1);
591: VecCheckSameSize(x, 3, y, 1);
592: VecCheckAssembled(x);
593: VecCheckAssembled(y);
595: if (alpha == (PetscScalar)0.0) PetscFunctionReturn(PETSC_SUCCESS);
596: PetscCall(VecSetErrorIfLocked(y, 1));
597: if (x == y) {
598: PetscCall(VecScale(y, alpha + 1.0));
599: PetscFunctionReturn(PETSC_SUCCESS);
600: }
601: PetscCall(VecLockReadPush(x));
602: PetscCall(PetscLogEventBegin(VEC_AXPY, x, y, 0, 0));
603: PetscUseTypeMethod(y, axpy, alpha, x);
604: PetscCall(PetscLogEventEnd(VEC_AXPY, x, y, 0, 0));
605: PetscCall(VecLockReadPop(x));
606: PetscCall(PetscObjectStateIncrease((PetscObject)y));
607: PetscFunctionReturn(PETSC_SUCCESS);
608: }
610: /*@
611: VecAYPX - Computes `y = x + beta y`.
613: Logically Collective
615: Input Parameters:
616: + beta - the scalar
617: . x - the unscaled vector
618: - y - the vector to be scaled
620: Output Parameter:
621: . y - output vector
623: Level: intermediate
625: Developer Note:
626: The implementation is optimized for `beta` of -1.0, 0.0, and 1.0
628: .seealso: [](chapter_vectors), `Vec`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBYPCZ()`, `VecAXPBY()`
629: @*/
630: PetscErrorCode VecAYPX(Vec y, PetscScalar beta, Vec x)
631: {
632: PetscFunctionBegin;
637: PetscCheckSameTypeAndComm(x, 3, y, 1);
638: VecCheckSameSize(x, 1, y, 3);
639: VecCheckAssembled(x);
640: VecCheckAssembled(y);
642: PetscCall(VecSetErrorIfLocked(y, 1));
643: if (x == y) {
644: PetscCall(VecScale(y, beta + 1.0));
645: PetscFunctionReturn(PETSC_SUCCESS);
646: }
647: PetscCall(VecLockReadPush(x));
648: if (beta == (PetscScalar)0.0) {
649: PetscCall(VecCopy(x, y));
650: } else {
651: PetscCall(PetscLogEventBegin(VEC_AYPX, x, y, 0, 0));
652: PetscUseTypeMethod(y, aypx, beta, x);
653: PetscCall(PetscLogEventEnd(VEC_AYPX, x, y, 0, 0));
654: PetscCall(PetscObjectStateIncrease((PetscObject)y));
655: }
656: PetscCall(VecLockReadPop(x));
657: PetscFunctionReturn(PETSC_SUCCESS);
658: }
660: /*@
661: VecAXPBY - Computes `y = alpha x + beta y`.
663: Logically Collective
665: Input Parameters:
666: + alpha - first scalar
667: . beta - second scalar
668: . x - the first scaled vector
669: - y - the second scaled vector
671: Output Parameter:
672: . y - output vector
674: Level: intermediate
676: Developer Note:
677: The implementation is optimized for `alpha` and/or `beta` values of 0.0 and 1.0
679: .seealso: [](chapter_vectors), `Vec`, `VecAYPX()`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBYPCZ()`
680: @*/
681: PetscErrorCode VecAXPBY(Vec y, PetscScalar alpha, PetscScalar beta, Vec x)
682: {
683: PetscFunctionBegin;
688: PetscCheckSameTypeAndComm(x, 4, y, 1);
689: VecCheckSameSize(y, 1, x, 4);
690: VecCheckAssembled(x);
691: VecCheckAssembled(y);
694: if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)1.0) PetscFunctionReturn(PETSC_SUCCESS);
695: if (x == y) {
696: PetscCall(VecScale(y, alpha + beta));
697: PetscFunctionReturn(PETSC_SUCCESS);
698: }
700: PetscCall(VecSetErrorIfLocked(y, 1));
701: PetscCall(VecLockReadPush(x));
702: PetscCall(PetscLogEventBegin(VEC_AXPY, y, x, 0, 0));
703: PetscUseTypeMethod(y, axpby, alpha, beta, x);
704: PetscCall(PetscLogEventEnd(VEC_AXPY, y, x, 0, 0));
705: PetscCall(PetscObjectStateIncrease((PetscObject)y));
706: PetscCall(VecLockReadPop(x));
707: PetscFunctionReturn(PETSC_SUCCESS);
708: }
710: /*@
711: VecAXPBYPCZ - Computes `z = alpha x + beta y + gamma z`
713: Logically Collective
715: Input Parameters:
716: + alpha - first scalar
717: . beta - second scalar
718: . gamma - third scalar
719: . x - first vector
720: . y - second vector
721: - z - third vector
723: Output Parameter:
724: . z - output vector
726: Level: intermediate
728: Note:
729: `x`, `y` and `z` must be different vectors
731: Developer Note:
732: The implementation is optimized for `alpha` of 1.0 and `gamma` of 1.0 or 0.0
734: .seealso: [](chapter_vectors), `Vec`, `VecAYPX()`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBY()`
735: @*/
736: PetscErrorCode VecAXPBYPCZ(Vec z, PetscScalar alpha, PetscScalar beta, PetscScalar gamma, Vec x, Vec y)
737: {
738: PetscFunctionBegin;
745: PetscCheckSameTypeAndComm(x, 5, y, 6);
746: PetscCheckSameTypeAndComm(x, 5, z, 1);
747: VecCheckSameSize(x, 1, y, 5);
748: VecCheckSameSize(x, 1, z, 6);
749: PetscCheck(x != y && x != z, PetscObjectComm((PetscObject)x), PETSC_ERR_ARG_IDN, "x, y, and z must be different vectors");
750: PetscCheck(y != z, PetscObjectComm((PetscObject)y), PETSC_ERR_ARG_IDN, "x, y, and z must be different vectors");
751: VecCheckAssembled(x);
752: VecCheckAssembled(y);
753: VecCheckAssembled(z);
757: if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)0.0 && gamma == (PetscScalar)1.0) PetscFunctionReturn(PETSC_SUCCESS);
759: PetscCall(VecSetErrorIfLocked(z, 1));
760: PetscCall(VecLockReadPush(x));
761: PetscCall(VecLockReadPush(y));
762: PetscCall(PetscLogEventBegin(VEC_AXPBYPCZ, x, y, z, 0));
763: PetscUseTypeMethod(z, axpbypcz, alpha, beta, gamma, x, y);
764: PetscCall(PetscLogEventEnd(VEC_AXPBYPCZ, x, y, z, 0));
765: PetscCall(PetscObjectStateIncrease((PetscObject)z));
766: PetscCall(VecLockReadPop(x));
767: PetscCall(VecLockReadPop(y));
768: PetscFunctionReturn(PETSC_SUCCESS);
769: }
771: /*@
772: VecWAXPY - Computes `w = alpha x + y`.
774: Logically Collective
776: Input Parameters:
777: + alpha - the scalar
778: . x - first vector, multiplied by `alpha`
779: - y - second vector
781: Output Parameter:
782: . w - the result
784: Level: intermediate
786: Note:
787: `w` cannot be either `x` or `y`, but `x` and `y` can be the same
789: Developer Note:
790: The implementation is optimized for alpha of -1.0, 0.0, and 1.0
792: .seealso: [](chapter_vectors), `Vec`, `VecAXPY()`, `VecAYPX()`, `VecAXPBY()`, `VecMAXPY()`, `VecAXPBYPCZ()`
793: @*/
794: PetscErrorCode VecWAXPY(Vec w, PetscScalar alpha, Vec x, Vec y)
795: {
796: PetscFunctionBegin;
803: PetscCheckSameTypeAndComm(x, 3, y, 4);
804: PetscCheckSameTypeAndComm(y, 4, w, 1);
805: VecCheckSameSize(x, 3, y, 4);
806: VecCheckSameSize(x, 3, w, 1);
807: PetscCheck(w != y, PETSC_COMM_SELF, PETSC_ERR_SUP, "Result vector w cannot be same as input vector y, suggest VecAXPY()");
808: PetscCheck(w != x, PETSC_COMM_SELF, PETSC_ERR_SUP, "Result vector w cannot be same as input vector x, suggest VecAYPX()");
809: VecCheckAssembled(x);
810: VecCheckAssembled(y);
812: PetscCall(VecSetErrorIfLocked(w, 1));
814: PetscCall(VecLockReadPush(x));
815: PetscCall(VecLockReadPush(y));
816: if (alpha == (PetscScalar)0.0) {
817: PetscCall(VecCopy(y, w));
818: } else {
819: PetscCall(PetscLogEventBegin(VEC_WAXPY, x, y, w, 0));
820: PetscUseTypeMethod(w, waxpy, alpha, x, y);
821: PetscCall(PetscLogEventEnd(VEC_WAXPY, x, y, w, 0));
822: PetscCall(PetscObjectStateIncrease((PetscObject)w));
823: }
824: PetscCall(VecLockReadPop(x));
825: PetscCall(VecLockReadPop(y));
826: PetscFunctionReturn(PETSC_SUCCESS);
827: }
829: /*@C
830: VecSetValues - Inserts or adds values into certain locations of a vector.
832: Not Collective
834: Input Parameters:
835: + x - vector to insert in
836: . ni - number of elements to add
837: . ix - indices where to add
838: . y - array of values
839: - iora - either `INSERT_VALUES` to replace the current values or `ADD_VALUES` to add values to any existing entries
841: Level: beginner
843: Notes:
844: .vb
845: `VecSetValues()` sets x[ix[i]] = y[i], for i=0,...,ni-1.
846: .ve
848: Calls to `VecSetValues()` with the `INSERT_VALUES` and `ADD_VALUES`
849: options cannot be mixed without intervening calls to the assembly
850: routines.
852: These values may be cached, so `VecAssemblyBegin()` and `VecAssemblyEnd()`
853: MUST be called after all calls to `VecSetValues()` have been completed.
855: VecSetValues() uses 0-based indices in Fortran as well as in C.
857: If you call `VecSetOption`(x, `VEC_IGNORE_NEGATIVE_INDICES`,`PETSC_TRUE`),
858: negative indices may be passed in ix. These rows are
859: simply ignored. This allows easily inserting element load matrices
860: with homogeneous Dirchlet boundary conditions that you don't want represented
861: in the vector.
863: .seealso: [](chapter_vectors), `Vec`, `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: {
868: PetscFunctionBeginHot;
870: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
875: PetscCall(PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0));
876: PetscUseTypeMethod(x, setvalues, ni, ix, y, iora);
877: PetscCall(PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0));
878: PetscCall(PetscObjectStateIncrease((PetscObject)x));
879: PetscFunctionReturn(PETSC_SUCCESS);
880: }
882: /*@C
883: VecGetValues - Gets values from certain locations of a vector. Currently
884: can only get values on the same processor on which they are owned
886: Not Collective
888: Input Parameters:
889: + x - vector to get values from
890: . ni - number of elements to get
891: - ix - indices where to get them from (in global 1d numbering)
893: Output Parameter:
894: . y - array of values
896: Level: beginner
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 if `VecSetValues()` or related routine has been called
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: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`
912: @*/
913: PetscErrorCode VecGetValues(Vec x, PetscInt ni, const PetscInt ix[], PetscScalar y[])
914: {
915: PetscFunctionBegin;
917: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
921: VecCheckAssembled(x);
922: PetscUseTypeMethod(x, getvalues, ni, ix, y);
923: PetscFunctionReturn(PETSC_SUCCESS);
924: }
926: /*@C
927: VecSetValuesBlocked - Inserts or adds blocks of values into certain locations of a vector.
929: Not Collective
931: Input Parameters:
932: + x - vector to insert in
933: . ni - number of blocks to add
934: . ix - indices where to add in block count, rather than element count
935: . y - array of values
936: - iora - either `INSERT_VALUES` replaces existing entries with new values, `ADD_VALUES`, adds values to any existing entries
938: Level: intermediate
940: Notes:
941: `VecSetValuesBlocked()` sets x[bs*ix[i]+j] = y[bs*i+j],
942: for j=0,...,bs-1, for i=0,...,ni-1. where bs was set with VecSetBlockSize().
944: Calls to `VecSetValuesBlocked()` with the `INSERT_VALUES` and `ADD_VALUES`
945: options cannot be mixed without intervening calls to the assembly
946: routines.
948: These values may be cached, so `VecAssemblyBegin()` and `VecAssemblyEnd()`
949: MUST be called after all calls to `VecSetValuesBlocked()` have been completed.
951: `VecSetValuesBlocked()` uses 0-based indices in Fortran as well as in C.
953: Negative indices may be passed in ix, these rows are
954: simply ignored. This allows easily inserting element load matrices
955: with homogeneous Dirchlet boundary conditions that you don't want represented
956: in the vector.
958: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValuesBlockedLocal()`,
959: `VecSetValues()`
960: @*/
961: PetscErrorCode VecSetValuesBlocked(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
962: {
963: PetscFunctionBeginHot;
965: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
970: PetscCall(PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0));
971: PetscUseTypeMethod(x, setvaluesblocked, ni, ix, y, iora);
972: PetscCall(PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0));
973: PetscCall(PetscObjectStateIncrease((PetscObject)x));
974: PetscFunctionReturn(PETSC_SUCCESS);
975: }
977: /*@C
978: VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
979: using a local ordering of the nodes.
981: Not Collective
983: Input Parameters:
984: + x - vector to insert in
985: . ni - number of elements to add
986: . ix - indices where to add
987: . y - array of values
988: - iora - either `INSERT_VALUES` replaces existing entries with new values, `ADD_VALUES` adds values to any existing entries
990: Level: intermediate
992: Notes:
993: `VecSetValuesLocal()` sets x[ix[i]] = y[i], for i=0,...,ni-1.
995: Calls to `VecSetValues()` with the `INSERT_VALUES` and `ADD_VALUES`
996: options cannot be mixed without intervening calls to the assembly
997: routines.
999: These values may be cached, so `VecAssemblyBegin()` and `VecAssemblyEnd()`
1000: MUST be called after all calls to `VecSetValuesLocal()` have been completed.
1002: `VecSetValuesLocal()` uses 0-based indices in Fortran as well as in C.
1004: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`, `VecSetLocalToGlobalMapping()`,
1005: `VecSetValuesBlockedLocal()`
1006: @*/
1007: PetscErrorCode VecSetValuesLocal(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
1008: {
1009: PetscInt lixp[128], *lix = lixp;
1011: PetscFunctionBeginHot;
1013: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
1018: PetscCall(PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0));
1019: if (!x->ops->setvalueslocal) {
1020: if (x->map->mapping) {
1021: if (ni > 128) PetscCall(PetscMalloc1(ni, &lix));
1022: PetscCall(ISLocalToGlobalMappingApply(x->map->mapping, ni, (PetscInt *)ix, lix));
1023: PetscUseTypeMethod(x, setvalues, ni, lix, y, iora);
1024: if (ni > 128) PetscCall(PetscFree(lix));
1025: } else PetscUseTypeMethod(x, setvalues, ni, ix, y, iora);
1026: } else PetscUseTypeMethod(x, setvalueslocal, ni, ix, y, iora);
1027: PetscCall(PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0));
1028: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1029: PetscFunctionReturn(PETSC_SUCCESS);
1030: }
1032: /*@
1033: VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
1034: using a local ordering of the nodes.
1036: Not Collective
1038: Input Parameters:
1039: + x - vector to insert in
1040: . ni - number of blocks to add
1041: . ix - indices where to add in block count, not element count
1042: . y - array of values
1043: - iora - either `INSERT_VALUES` replaces existing entries with new values, `ADD_VALUES` adds values to any existing entries
1045: Level: intermediate
1047: Notes:
1048: `VecSetValuesBlockedLocal()` sets x[bs*ix[i]+j] = y[bs*i+j],
1049: for j=0,..bs-1, for i=0,...,ni-1, where bs has been set with `VecSetBlockSize()`.
1051: Calls to `VecSetValuesBlockedLocal()` with the `INSERT_VALUES` and `ADD_VALUES`
1052: options cannot be mixed without intervening calls to the assembly
1053: routines.
1055: These values may be cached, so `VecAssemblyBegin()` and `VecAssemblyEnd()`
1056: MUST be called after all calls to `VecSetValuesBlockedLocal()` have been completed.
1058: `VecSetValuesBlockedLocal()` uses 0-based indices in Fortran as well as in C.
1060: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`, `VecSetValuesBlocked()`,
1061: `VecSetLocalToGlobalMapping()`
1062: @*/
1063: PetscErrorCode VecSetValuesBlockedLocal(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
1064: {
1065: PetscInt lixp[128], *lix = lixp;
1067: PetscFunctionBeginHot;
1069: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
1073: PetscCall(PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0));
1074: if (x->map->mapping) {
1075: if (ni > 128) PetscCall(PetscMalloc1(ni, &lix));
1076: PetscCall(ISLocalToGlobalMappingApplyBlock(x->map->mapping, ni, (PetscInt *)ix, lix));
1077: PetscUseTypeMethod(x, setvaluesblocked, ni, lix, y, iora);
1078: if (ni > 128) PetscCall(PetscFree(lix));
1079: } else {
1080: PetscUseTypeMethod(x, setvaluesblocked, ni, ix, y, iora);
1081: }
1082: PetscCall(PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0));
1083: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1084: PetscFunctionReturn(PETSC_SUCCESS);
1085: }
1087: static PetscErrorCode VecMXDot_Private(Vec x, PetscInt nv, const Vec y[], PetscScalar result[], PetscErrorCode (*mxdot)(Vec, PetscInt, const Vec[], PetscScalar[]), PetscLogEvent event)
1088: {
1089: PetscFunctionBegin;
1092: VecCheckAssembled(x);
1094: if (!nv) PetscFunctionReturn(PETSC_SUCCESS);
1096: for (PetscInt i = 0; i < nv; ++i) {
1099: PetscCheckSameTypeAndComm(x, 1, y[i], 3);
1100: VecCheckSameSize(x, 1, y[i], 3);
1101: VecCheckAssembled(y[i]);
1102: PetscCall(VecLockReadPush(y[i]));
1103: }
1107: PetscCall(VecLockReadPush(x));
1108: PetscCall(PetscLogEventBegin(event, x, *y, 0, 0));
1109: PetscCall((*mxdot)(x, nv, y, result));
1110: PetscCall(PetscLogEventEnd(event, x, *y, 0, 0));
1111: PetscCall(VecLockReadPop(x));
1112: for (PetscInt i = 0; i < nv; ++i) PetscCall(VecLockReadPop(y[i]));
1113: PetscFunctionReturn(PETSC_SUCCESS);
1114: }
1116: /*@
1117: VecMTDot - Computes indefinite vector multiple dot products.
1118: That is, it does NOT use the complex conjugate.
1120: Collective
1122: Input Parameters:
1123: + x - one vector
1124: . nv - number of vectors
1125: - y - array of vectors. Note that vectors are pointers
1127: Output Parameter:
1128: . val - array of the dot products
1130: Level: intermediate
1132: Notes for Users of Complex Numbers:
1133: For complex vectors, `VecMTDot()` computes the indefinite form
1134: $ val = (x,y) = y^T x,
1135: where y^T denotes the transpose of y.
1137: Use `VecMDot()` for the inner product
1138: $ val = (x,y) = y^H x,
1139: where y^H denotes the conjugate transpose of y.
1141: .seealso: [](chapter_vectors), `Vec`, `VecMDot()`, `VecTDot()`
1142: @*/
1143: PetscErrorCode VecMTDot(Vec x, PetscInt nv, const Vec y[], PetscScalar val[])
1144: {
1145: PetscFunctionBegin;
1147: PetscCall(VecMXDot_Private(x, nv, y, val, x->ops->mtdot, VEC_MTDot));
1148: PetscFunctionReturn(PETSC_SUCCESS);
1149: }
1151: /*@
1152: VecMDot - Computes multiple vector dot products.
1154: Collective
1156: Input Parameters:
1157: + x - one vector
1158: . nv - number of vectors
1159: - y - array of vectors.
1161: Output Parameter:
1162: . val - array of the dot products (does not allocate the array)
1164: Level: intermediate
1166: Notes for Users of Complex Numbers:
1167: For complex vectors, `VecMDot()` computes
1168: $ val = (x,y) = y^H x,
1169: where y^H denotes the conjugate transpose of y.
1171: Use `VecMTDot()` for the indefinite form
1172: $ val = (x,y) = y^T x,
1173: where y^T denotes the transpose of y.
1175: .seealso: [](chapter_vectors), `Vec`, `VecMTDot()`, `VecDot()`
1176: @*/
1177: PetscErrorCode VecMDot(Vec x, PetscInt nv, const Vec y[], PetscScalar val[])
1178: {
1179: PetscFunctionBegin;
1181: PetscCall(VecMXDot_Private(x, nv, y, val, x->ops->mdot, VEC_MDot));
1182: PetscFunctionReturn(PETSC_SUCCESS);
1183: }
1185: /*@
1186: VecMAXPY - Computes `y = y + sum alpha[i] x[i]`
1188: Logically Collective
1190: Input Parameters:
1191: + nv - number of scalars and x-vectors
1192: . alpha - array of scalars
1193: . y - one vector
1194: - x - array of vectors
1196: Level: intermediate
1198: Note:
1199: `y` cannot be any of the `x` vectors
1201: .seealso: [](chapter_vectors), `Vec`, `VecAYPX()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBYPCZ()`, `VecAXPBY()`
1202: @*/
1203: PetscErrorCode VecMAXPY(Vec y, PetscInt nv, const PetscScalar alpha[], Vec x[])
1204: {
1205: PetscFunctionBegin;
1207: VecCheckAssembled(y);
1209: PetscCall(VecSetErrorIfLocked(y, 1));
1210: PetscCheck(nv >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of vectors (given %" PetscInt_FMT ") cannot be negative", nv);
1211: if (nv) {
1212: PetscInt zeros = 0;
1216: for (PetscInt i = 0; i < nv; ++i) {
1220: PetscCheckSameTypeAndComm(y, 1, x[i], 4);
1221: VecCheckSameSize(y, 1, x[i], 4);
1222: PetscCheck(y != x[i], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Array of vectors 'x' cannot contain y, found x[%" PetscInt_FMT "] == y", i);
1223: VecCheckAssembled(x[i]);
1224: PetscCall(VecLockReadPush(x[i]));
1225: zeros += alpha[i] == (PetscScalar)0.0;
1226: }
1228: if (zeros < nv) {
1229: PetscCall(PetscLogEventBegin(VEC_MAXPY, y, *x, 0, 0));
1230: PetscUseTypeMethod(y, maxpy, nv, alpha, x);
1231: PetscCall(PetscLogEventEnd(VEC_MAXPY, y, *x, 0, 0));
1232: PetscCall(PetscObjectStateIncrease((PetscObject)y));
1233: }
1235: for (PetscInt i = 0; i < nv; ++i) PetscCall(VecLockReadPop(x[i]));
1236: }
1237: PetscFunctionReturn(PETSC_SUCCESS);
1238: }
1240: /*@
1241: VecConcatenate - Creates a new vector that is a vertical concatenation of all the given array of vectors
1242: in the order they appear in the array. The concatenated vector resides on the same
1243: communicator and is the same type as the source vectors.
1245: Collective
1247: Input Parameters:
1248: + nx - number of vectors to be concatenated
1249: - X - array containing the vectors to be concatenated in the order of concatenation
1251: Output Parameters:
1252: + Y - concatenated vector
1253: - x_is - array of index sets corresponding to the concatenated components of `Y` (pass `NULL` if not needed)
1255: Level: advanced
1257: Notes:
1258: Concatenation is similar to the functionality of a `VECNEST` object; they both represent combination of
1259: different vector spaces. However, concatenated vectors do not store any information about their
1260: sub-vectors and own their own data. Consequently, this function provides index sets to enable the
1261: manipulation of data in the concatenated vector that corresponds to the original components at creation.
1263: This is a useful tool for outer loop algorithms, particularly constrained optimizers, where the solver
1264: has to operate on combined vector spaces and cannot utilize `VECNEST` objects due to incompatibility with
1265: bound projections.
1267: .seealso: [](chapter_vectors), `Vec`, `VECNEST`, `VECSCATTER`, `VecScatterCreate()`
1268: @*/
1269: PetscErrorCode VecConcatenate(PetscInt nx, const Vec X[], Vec *Y, IS *x_is[])
1270: {
1271: MPI_Comm comm;
1272: VecType vec_type;
1273: Vec Ytmp, Xtmp;
1274: IS *is_tmp;
1275: PetscInt i, shift = 0, Xnl, Xng, Xbegin;
1277: PetscFunctionBegin;
1283: if ((*X)->ops->concatenate) {
1284: /* use the dedicated concatenation function if available */
1285: PetscCall((*(*X)->ops->concatenate)(nx, X, Y, x_is));
1286: } else {
1287: /* loop over vectors and start creating IS */
1288: comm = PetscObjectComm((PetscObject)(*X));
1289: PetscCall(VecGetType(*X, &vec_type));
1290: PetscCall(PetscMalloc1(nx, &is_tmp));
1291: for (i = 0; i < nx; i++) {
1292: PetscCall(VecGetSize(X[i], &Xng));
1293: PetscCall(VecGetLocalSize(X[i], &Xnl));
1294: PetscCall(VecGetOwnershipRange(X[i], &Xbegin, NULL));
1295: PetscCall(ISCreateStride(comm, Xnl, shift + Xbegin, 1, &is_tmp[i]));
1296: shift += Xng;
1297: }
1298: /* create the concatenated vector */
1299: PetscCall(VecCreate(comm, &Ytmp));
1300: PetscCall(VecSetType(Ytmp, vec_type));
1301: PetscCall(VecSetSizes(Ytmp, PETSC_DECIDE, shift));
1302: PetscCall(VecSetUp(Ytmp));
1303: /* copy data from X array to Y and return */
1304: for (i = 0; i < nx; i++) {
1305: PetscCall(VecGetSubVector(Ytmp, is_tmp[i], &Xtmp));
1306: PetscCall(VecCopy(X[i], Xtmp));
1307: PetscCall(VecRestoreSubVector(Ytmp, is_tmp[i], &Xtmp));
1308: }
1309: *Y = Ytmp;
1310: if (x_is) {
1311: *x_is = is_tmp;
1312: } else {
1313: for (i = 0; i < nx; i++) PetscCall(ISDestroy(&is_tmp[i]));
1314: PetscCall(PetscFree(is_tmp));
1315: }
1316: }
1317: PetscFunctionReturn(PETSC_SUCCESS);
1318: }
1320: /* A helper function for VecGetSubVector to check if we can implement it with no-copy (i.e. the subvector shares
1321: memory with the original vector), and the block size of the subvector.
1323: Input Parameters:
1324: + X - the original vector
1325: - is - the index set of the subvector
1327: Output Parameters:
1328: + contig - PETSC_TRUE if the index set refers to contiguous entries on this process, else PETSC_FALSE
1329: . start - start of contiguous block, as an offset from the start of the ownership range of the original vector
1330: - blocksize - the block size of the subvector
1332: */
1333: PetscErrorCode VecGetSubVectorContiguityAndBS_Private(Vec X, IS is, PetscBool *contig, PetscInt *start, PetscInt *blocksize)
1334: {
1335: PetscInt gstart, gend, lstart;
1336: PetscBool red[2] = {PETSC_TRUE /*contiguous*/, PETSC_TRUE /*validVBS*/};
1337: PetscInt n, N, ibs, vbs, bs = -1;
1339: PetscFunctionBegin;
1340: PetscCall(ISGetLocalSize(is, &n));
1341: PetscCall(ISGetSize(is, &N));
1342: PetscCall(ISGetBlockSize(is, &ibs));
1343: PetscCall(VecGetBlockSize(X, &vbs));
1344: PetscCall(VecGetOwnershipRange(X, &gstart, &gend));
1345: PetscCall(ISContiguousLocal(is, gstart, gend, &lstart, &red[0]));
1346: /* block size is given by IS if ibs > 1; otherwise, check the vector */
1347: if (ibs > 1) {
1348: PetscCall(MPIU_Allreduce(MPI_IN_PLACE, red, 1, MPIU_BOOL, MPI_LAND, PetscObjectComm((PetscObject)is)));
1349: bs = ibs;
1350: } else {
1351: if (n % vbs || vbs == 1) red[1] = PETSC_FALSE; /* this process invalidate the collectiveness of block size */
1352: PetscCall(MPIU_Allreduce(MPI_IN_PLACE, red, 2, MPIU_BOOL, MPI_LAND, PetscObjectComm((PetscObject)is)));
1353: if (red[0] && red[1]) bs = vbs; /* all processes have a valid block size and the access will be contiguous */
1354: }
1356: *contig = red[0];
1357: *start = lstart;
1358: *blocksize = bs;
1359: PetscFunctionReturn(PETSC_SUCCESS);
1360: }
1362: /* A helper function for VecGetSubVector, to be used when we have to build a standalone subvector through VecScatter
1364: Input Parameters:
1365: + X - the original vector
1366: . is - the index set of the subvector
1367: - bs - the block size of the subvector, gotten from VecGetSubVectorContiguityAndBS_Private()
1369: Output Parameter:
1370: . Z - the subvector, which will compose the VecScatter context on output
1371: */
1372: PetscErrorCode VecGetSubVectorThroughVecScatter_Private(Vec X, IS is, PetscInt bs, Vec *Z)
1373: {
1374: PetscInt n, N;
1375: VecScatter vscat;
1376: Vec Y;
1378: PetscFunctionBegin;
1379: PetscCall(ISGetLocalSize(is, &n));
1380: PetscCall(ISGetSize(is, &N));
1381: PetscCall(VecCreate(PetscObjectComm((PetscObject)is), &Y));
1382: PetscCall(VecSetSizes(Y, n, N));
1383: PetscCall(VecSetBlockSize(Y, bs));
1384: PetscCall(VecSetType(Y, ((PetscObject)X)->type_name));
1385: PetscCall(VecScatterCreate(X, is, Y, NULL, &vscat));
1386: PetscCall(VecScatterBegin(vscat, X, Y, INSERT_VALUES, SCATTER_FORWARD));
1387: PetscCall(VecScatterEnd(vscat, X, Y, INSERT_VALUES, SCATTER_FORWARD));
1388: PetscCall(PetscObjectCompose((PetscObject)Y, "VecGetSubVector_Scatter", (PetscObject)vscat));
1389: PetscCall(VecScatterDestroy(&vscat));
1390: *Z = Y;
1391: PetscFunctionReturn(PETSC_SUCCESS);
1392: }
1394: /*@
1395: VecGetSubVector - Gets a vector representing part of another vector
1397: Collective
1399: Input Parameters:
1400: + X - vector from which to extract a subvector
1401: - is - index set representing portion of `X` to extract
1403: Output Parameter:
1404: . Y - subvector corresponding to `is`
1406: Level: advanced
1408: Notes:
1409: The subvector `Y` should be returned with `VecRestoreSubVector()`.
1410: `X` and must be defined on the same communicator
1412: This function may return a subvector without making a copy, therefore it is not safe to use the original vector while
1413: modifying the subvector. Other non-overlapping subvectors can still be obtained from X using this function.
1415: The resulting subvector inherits the block size from `is` if greater than one. Otherwise, the block size is guessed from the block size of the original `X`.
1417: .seealso: [](chapter_vectors), `Vec`, `IS`, `VECNEST`, `MatCreateSubMatrix()`
1418: @*/
1419: PetscErrorCode VecGetSubVector(Vec X, IS is, Vec *Y)
1420: {
1421: Vec Z;
1423: PetscFunctionBegin;
1426: PetscCheckSameComm(X, 1, is, 2);
1428: if (X->ops->getsubvector) {
1429: PetscUseTypeMethod(X, getsubvector, is, &Z);
1430: } else { /* Default implementation currently does no caching */
1431: PetscBool contig;
1432: PetscInt n, N, start, bs;
1434: PetscCall(ISGetLocalSize(is, &n));
1435: PetscCall(ISGetSize(is, &N));
1436: PetscCall(VecGetSubVectorContiguityAndBS_Private(X, is, &contig, &start, &bs));
1437: if (contig) { /* We can do a no-copy implementation */
1438: const PetscScalar *x;
1439: PetscInt state = 0;
1440: PetscBool isstd, iscuda, iship;
1442: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &isstd, VECSEQ, VECMPI, VECSTANDARD, ""));
1443: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &iscuda, VECSEQCUDA, VECMPICUDA, ""));
1444: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &iship, VECSEQHIP, VECMPIHIP, ""));
1445: if (iscuda) {
1446: #if defined(PETSC_HAVE_CUDA)
1447: const PetscScalar *x_d;
1448: PetscMPIInt size;
1449: PetscOffloadMask flg;
1451: PetscCall(VecCUDAGetArrays_Private(X, &x, &x_d, &flg));
1452: PetscCheck(flg != PETSC_OFFLOAD_UNALLOCATED, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not for PETSC_OFFLOAD_UNALLOCATED");
1453: PetscCheck(!n || x || x_d, PETSC_COMM_SELF, PETSC_ERR_SUP, "Missing vector data");
1454: if (x) x += start;
1455: if (x_d) x_d += start;
1456: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)X), &size));
1457: if (size == 1) {
1458: PetscCall(VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)X), bs, n, x, x_d, &Z));
1459: } else {
1460: PetscCall(VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)X), bs, n, N, x, x_d, &Z));
1461: }
1462: Z->offloadmask = flg;
1463: #endif
1464: } else if (iship) {
1465: #if defined(PETSC_HAVE_HIP)
1466: const PetscScalar *x_d;
1467: PetscMPIInt size;
1468: PetscOffloadMask flg;
1470: PetscCall(VecHIPGetArrays_Private(X, &x, &x_d, &flg));
1471: PetscCheck(flg != PETSC_OFFLOAD_UNALLOCATED, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not for PETSC_OFFLOAD_UNALLOCATED");
1472: PetscCheck(!n || x || x_d, PETSC_COMM_SELF, PETSC_ERR_SUP, "Missing vector data");
1473: if (x) x += start;
1474: if (x_d) x_d += start;
1475: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)X), &size));
1476: if (size == 1) {
1477: PetscCall(VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)X), bs, n, x, x_d, &Z));
1478: } else {
1479: PetscCall(VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)X), bs, n, N, x, x_d, &Z));
1480: }
1481: Z->offloadmask = flg;
1482: #endif
1483: } else if (isstd) {
1484: PetscMPIInt size;
1486: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)X), &size));
1487: PetscCall(VecGetArrayRead(X, &x));
1488: if (x) x += start;
1489: if (size == 1) {
1490: PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)X), bs, n, x, &Z));
1491: } else {
1492: PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)X), bs, n, N, x, &Z));
1493: }
1494: PetscCall(VecRestoreArrayRead(X, &x));
1495: } else { /* default implementation: use place array */
1496: PetscCall(VecGetArrayRead(X, &x));
1497: PetscCall(VecCreate(PetscObjectComm((PetscObject)X), &Z));
1498: PetscCall(VecSetType(Z, ((PetscObject)X)->type_name));
1499: PetscCall(VecSetSizes(Z, n, N));
1500: PetscCall(VecSetBlockSize(Z, bs));
1501: PetscCall(VecPlaceArray(Z, x ? x + start : NULL));
1502: PetscCall(VecRestoreArrayRead(X, &x));
1503: }
1505: /* this is relevant only in debug mode */
1506: PetscCall(VecLockGet(X, &state));
1507: if (state) PetscCall(VecLockReadPush(Z));
1508: Z->ops->placearray = NULL;
1509: Z->ops->replacearray = NULL;
1510: } else { /* Have to create a scatter and do a copy */
1511: PetscCall(VecGetSubVectorThroughVecScatter_Private(X, is, bs, &Z));
1512: }
1513: }
1514: /* Record the state when the subvector was gotten so we know whether its values need to be put back */
1515: if (VecGetSubVectorSavedStateId < 0) PetscCall(PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId));
1516: PetscCall(PetscObjectComposedDataSetInt((PetscObject)Z, VecGetSubVectorSavedStateId, 1));
1517: *Y = Z;
1518: PetscFunctionReturn(PETSC_SUCCESS);
1519: }
1521: /*@
1522: VecRestoreSubVector - Restores a subvector extracted using `VecGetSubVector()`
1524: Collective
1526: Input Parameters:
1527: + X - vector from which subvector was obtained
1528: . is - index set representing the subset of `X`
1529: - Y - subvector being restored
1531: Level: advanced
1533: .seealso: [](chapter_vectors), `Vec`, `IS`, `VecGetSubVector()`
1534: @*/
1535: PetscErrorCode VecRestoreSubVector(Vec X, IS is, Vec *Y)
1536: {
1537: PETSC_UNUSED PetscObjectState dummystate = 0;
1538: PetscBool unchanged;
1540: PetscFunctionBegin;
1543: PetscCheckSameComm(X, 1, is, 2);
1547: if (X->ops->restoresubvector) PetscUseTypeMethod(X, restoresubvector, is, Y);
1548: else {
1549: PetscCall(PetscObjectComposedDataGetInt((PetscObject)*Y, VecGetSubVectorSavedStateId, dummystate, unchanged));
1550: if (!unchanged) { /* If Y's state has not changed since VecGetSubVector(), we only need to destroy Y */
1551: VecScatter scatter;
1552: PetscInt state;
1554: PetscCall(VecLockGet(X, &state));
1555: PetscCheck(state == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Vec X is locked for read-only or read/write access");
1557: PetscCall(PetscObjectQuery((PetscObject)*Y, "VecGetSubVector_Scatter", (PetscObject *)&scatter));
1558: if (scatter) {
1559: PetscCall(VecScatterBegin(scatter, *Y, X, INSERT_VALUES, SCATTER_REVERSE));
1560: PetscCall(VecScatterEnd(scatter, *Y, X, INSERT_VALUES, SCATTER_REVERSE));
1561: } else {
1562: PetscBool iscuda, iship;
1563: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &iscuda, VECSEQCUDA, VECMPICUDA, ""));
1564: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &iship, VECSEQHIP, VECMPIHIP, ""));
1566: if (iscuda) {
1567: #if defined(PETSC_HAVE_CUDA)
1568: PetscOffloadMask ymask = (*Y)->offloadmask;
1570: /* The offloadmask of X dictates where to move memory
1571: If X GPU data is valid, then move Y data on GPU if needed
1572: Otherwise, move back to the CPU */
1573: switch (X->offloadmask) {
1574: case PETSC_OFFLOAD_BOTH:
1575: if (ymask == PETSC_OFFLOAD_CPU) {
1576: PetscCall(VecCUDAResetArray(*Y));
1577: } else if (ymask == PETSC_OFFLOAD_GPU) {
1578: X->offloadmask = PETSC_OFFLOAD_GPU;
1579: }
1580: break;
1581: case PETSC_OFFLOAD_GPU:
1582: if (ymask == PETSC_OFFLOAD_CPU) PetscCall(VecCUDAResetArray(*Y));
1583: break;
1584: case PETSC_OFFLOAD_CPU:
1585: if (ymask == PETSC_OFFLOAD_GPU) PetscCall(VecResetArray(*Y));
1586: break;
1587: case PETSC_OFFLOAD_UNALLOCATED:
1588: case PETSC_OFFLOAD_KOKKOS:
1589: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "This should not happen");
1590: }
1591: #endif
1592: } else if (iship) {
1593: #if defined(PETSC_HAVE_HIP)
1594: PetscOffloadMask ymask = (*Y)->offloadmask;
1596: /* The offloadmask of X dictates where to move memory
1597: If X GPU data is valid, then move Y data on GPU if needed
1598: Otherwise, move back to the CPU */
1599: switch (X->offloadmask) {
1600: case PETSC_OFFLOAD_BOTH:
1601: if (ymask == PETSC_OFFLOAD_CPU) {
1602: PetscCall(VecHIPResetArray(*Y));
1603: } else if (ymask == PETSC_OFFLOAD_GPU) {
1604: X->offloadmask = PETSC_OFFLOAD_GPU;
1605: }
1606: break;
1607: case PETSC_OFFLOAD_GPU:
1608: if (ymask == PETSC_OFFLOAD_CPU) PetscCall(VecHIPResetArray(*Y));
1609: break;
1610: case PETSC_OFFLOAD_CPU:
1611: if (ymask == PETSC_OFFLOAD_GPU) PetscCall(VecResetArray(*Y));
1612: break;
1613: case PETSC_OFFLOAD_UNALLOCATED:
1614: case PETSC_OFFLOAD_KOKKOS:
1615: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "This should not happen");
1616: }
1617: #endif
1618: } else {
1619: /* If OpenCL vecs updated the device memory, this triggers a copy on the CPU */
1620: PetscCall(VecResetArray(*Y));
1621: }
1622: PetscCall(PetscObjectStateIncrease((PetscObject)X));
1623: }
1624: }
1625: }
1626: PetscCall(VecDestroy(Y));
1627: PetscFunctionReturn(PETSC_SUCCESS);
1628: }
1630: /*@
1631: VecCreateLocalVector - Creates a vector object suitable for use with `VecGetLocalVector()` and friends. You must call `VecDestroy()` when the
1632: vector is no longer needed.
1634: Not Collective.
1636: Input parameter:
1637: . v - The vector for which the local vector is desired.
1639: Output parameter:
1640: . w - Upon exit this contains the local vector.
1642: Level: beginner
1644: .seealso: [](chapter_vectors), `Vec`, `VecGetLocalVectorRead()`, `VecRestoreLocalVectorRead()`, `VecGetLocalVector()`, `VecRestoreLocalVector()`
1645: @*/
1646: PetscErrorCode VecCreateLocalVector(Vec v, Vec *w)
1647: {
1648: PetscMPIInt size;
1650: PetscFunctionBegin;
1653: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)v), &size));
1654: if (size == 1) PetscCall(VecDuplicate(v, w));
1655: else if (v->ops->createlocalvector) PetscUseTypeMethod(v, createlocalvector, w);
1656: else {
1657: VecType type;
1658: PetscInt n;
1660: PetscCall(VecCreate(PETSC_COMM_SELF, w));
1661: PetscCall(VecGetLocalSize(v, &n));
1662: PetscCall(VecSetSizes(*w, n, n));
1663: PetscCall(VecGetBlockSize(v, &n));
1664: PetscCall(VecSetBlockSize(*w, n));
1665: PetscCall(VecGetType(v, &type));
1666: PetscCall(VecSetType(*w, type));
1667: }
1668: PetscFunctionReturn(PETSC_SUCCESS);
1669: }
1671: /*@
1672: VecGetLocalVectorRead - Maps the local portion of a vector into a
1673: vector.
1675: Not Collective.
1677: Input parameter:
1678: . v - The vector for which the local vector is desired.
1680: Output parameter:
1681: . w - Upon exit this contains the local vector.
1683: Level: beginner
1685: Notes:
1686: You must call `VecRestoreLocalVectorRead()` when the local
1687: vector is no longer needed.
1689: This function is similar to `VecGetArrayRead()` which maps the local
1690: portion into a raw pointer. `VecGetLocalVectorRead()` is usually
1691: almost as efficient as `VecGetArrayRead()` but in certain circumstances
1692: `VecGetLocalVectorRead()` can be much more efficient than
1693: `VecGetArrayRead()`. This is because the construction of a contiguous
1694: array representing the vector data required by `VecGetArrayRead()` can
1695: be an expensive operation for certain vector types. For example, for
1696: GPU vectors `VecGetArrayRead()` requires that the data between device
1697: and host is synchronized.
1699: Unlike `VecGetLocalVector()`, this routine is not collective and
1700: preserves cached information.
1702: .seealso: [](chapter_vectors), `Vec`, `VecCreateLocalVector()`, `VecRestoreLocalVectorRead()`, `VecGetLocalVector()`, `VecGetArrayRead()`, `VecGetArray()`
1703: @*/
1704: PetscErrorCode VecGetLocalVectorRead(Vec v, Vec w)
1705: {
1706: PetscFunctionBegin;
1709: VecCheckSameLocalSize(v, 1, w, 2);
1710: if (v->ops->getlocalvectorread) {
1711: PetscUseTypeMethod(v, getlocalvectorread, w);
1712: } else {
1713: PetscScalar *a;
1715: PetscCall(VecGetArrayRead(v, (const PetscScalar **)&a));
1716: PetscCall(VecPlaceArray(w, a));
1717: }
1718: PetscCall(PetscObjectStateIncrease((PetscObject)w));
1719: PetscCall(VecLockReadPush(v));
1720: PetscCall(VecLockReadPush(w));
1721: PetscFunctionReturn(PETSC_SUCCESS);
1722: }
1724: /*@
1725: VecRestoreLocalVectorRead - Unmaps the local portion of a vector
1726: previously mapped into a vector using `VecGetLocalVectorRead()`.
1728: Not Collective.
1730: Input parameter:
1731: + v - The local portion of this vector was previously mapped into `w` using `VecGetLocalVectorRead()`.
1732: - w - The vector into which the local portion of `v` was mapped.
1734: Level: beginner
1736: .seealso: [](chapter_vectors), `Vec`, `VecCreateLocalVector()`, `VecGetLocalVectorRead()`, `VecGetLocalVector()`, `VecGetArrayRead()`, `VecGetArray()`
1737: @*/
1738: PetscErrorCode VecRestoreLocalVectorRead(Vec v, Vec w)
1739: {
1740: PetscFunctionBegin;
1743: if (v->ops->restorelocalvectorread) {
1744: PetscUseTypeMethod(v, restorelocalvectorread, w);
1745: } else {
1746: const PetscScalar *a;
1748: PetscCall(VecGetArrayRead(w, &a));
1749: PetscCall(VecRestoreArrayRead(v, &a));
1750: PetscCall(VecResetArray(w));
1751: }
1752: PetscCall(VecLockReadPop(v));
1753: PetscCall(VecLockReadPop(w));
1754: PetscCall(PetscObjectStateIncrease((PetscObject)w));
1755: PetscFunctionReturn(PETSC_SUCCESS);
1756: }
1758: /*@
1759: VecGetLocalVector - Maps the local portion of a vector into a
1760: vector.
1762: Collective
1764: Input parameter:
1765: . v - The vector for which the local vector is desired.
1767: Output parameter:
1768: . w - Upon exit this contains the local vector.
1770: Level: beginner
1772: Notes:
1773: You must call `VecRestoreLocalVector()` when the local
1774: vector is no longer needed.
1776: This function is similar to `VecGetArray()` which maps the local
1777: portion into a raw pointer. `VecGetLocalVector()` is usually about as
1778: efficient as `VecGetArray()` but in certain circumstances
1779: `VecGetLocalVector()` can be much more efficient than `VecGetArray()`.
1780: This is because the construction of a contiguous array representing
1781: the vector data required by `VecGetArray()` can be an expensive
1782: operation for certain vector types. For example, for GPU vectors
1783: `VecGetArray()` requires that the data between device and host is
1784: synchronized.
1786: .seealso: [](chapter_vectors), `Vec`, `VecCreateLocalVector()`, `VecRestoreLocalVector()`, `VecGetLocalVectorRead()`, `VecGetArrayRead()`, `VecGetArray()`
1787: @*/
1788: PetscErrorCode VecGetLocalVector(Vec v, Vec w)
1789: {
1790: PetscFunctionBegin;
1793: VecCheckSameLocalSize(v, 1, w, 2);
1794: if (v->ops->getlocalvector) {
1795: PetscUseTypeMethod(v, getlocalvector, w);
1796: } else {
1797: PetscScalar *a;
1799: PetscCall(VecGetArray(v, &a));
1800: PetscCall(VecPlaceArray(w, a));
1801: }
1802: PetscCall(PetscObjectStateIncrease((PetscObject)w));
1803: PetscFunctionReturn(PETSC_SUCCESS);
1804: }
1806: /*@
1807: VecRestoreLocalVector - Unmaps the local portion of a vector
1808: previously mapped into a vector using `VecGetLocalVector()`.
1810: Logically Collective.
1812: Input parameter:
1813: + v - The local portion of this vector was previously mapped into `w` using `VecGetLocalVector()`.
1814: - w - The vector into which the local portion of `v` was mapped.
1816: Level: beginner
1818: .seealso: [](chapter_vectors), `Vec`, `VecCreateLocalVector()`, `VecGetLocalVector()`, `VecGetLocalVectorRead()`, `VecRestoreLocalVectorRead()`, `LocalVectorRead()`, `VecGetArrayRead()`, `VecGetArray()`
1819: @*/
1820: PetscErrorCode VecRestoreLocalVector(Vec v, Vec w)
1821: {
1822: PetscFunctionBegin;
1825: if (v->ops->restorelocalvector) {
1826: PetscUseTypeMethod(v, restorelocalvector, w);
1827: } else {
1828: PetscScalar *a;
1829: PetscCall(VecGetArray(w, &a));
1830: PetscCall(VecRestoreArray(v, &a));
1831: PetscCall(VecResetArray(w));
1832: }
1833: PetscCall(PetscObjectStateIncrease((PetscObject)w));
1834: PetscCall(PetscObjectStateIncrease((PetscObject)v));
1835: PetscFunctionReturn(PETSC_SUCCESS);
1836: }
1838: /*@C
1839: VecGetArray - Returns a pointer to a contiguous array that contains this
1840: processor's portion of the vector data. For the standard PETSc
1841: vectors, `VecGetArray()` returns a pointer to the local data array and
1842: does not use any copies. If the underlying vector data is not stored
1843: in a contiguous array this routine will copy the data to a contiguous
1844: array and return a pointer to that. You MUST call `VecRestoreArray()`
1845: when you no longer need access to the array.
1847: Logically Collective
1849: Input Parameter:
1850: . x - the vector
1852: Output Parameter:
1853: . a - location to put pointer to the array
1855: Level: beginner
1857: Fortran Note:
1858: `VecGetArray()` Fortran binding is deprecated (since PETSc 3.19), use `VecGetArrayF90()`
1860: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecGetArrayReadF90()`, `VecPlaceArray()`, `VecGetArray2d()`,
1861: `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayWrite()`, `VecRestoreArrayWrite()`
1862: @*/
1863: PetscErrorCode VecGetArray(Vec x, PetscScalar **a)
1864: {
1865: PetscFunctionBegin;
1867: PetscCall(VecSetErrorIfLocked(x, 1));
1868: if (x->ops->getarray) { /* The if-else order matters! VECNEST, VECCUDA etc should have ops->getarray while VECCUDA etc are petscnative */
1869: PetscUseTypeMethod(x, getarray, a);
1870: } else if (x->petscnative) { /* VECSTANDARD */
1871: *a = *((PetscScalar **)x->data);
1872: } else SETERRQ(PetscObjectComm((PetscObject)x), PETSC_ERR_SUP, "Cannot get array for vector type \"%s\"", ((PetscObject)x)->type_name);
1873: PetscFunctionReturn(PETSC_SUCCESS);
1874: }
1876: /*@C
1877: VecRestoreArray - Restores a vector after `VecGetArray()` has been called and the array is no longer needed
1879: Logically Collective
1881: Input Parameters:
1882: + x - the vector
1883: - a - location of pointer to array obtained from `VecGetArray()`
1885: Level: beginner
1887: Fortran Note:
1888: `VecRestoreArray()` Fortran binding is deprecated (since PETSc 3.19), use `VecRestoreArrayF90()`
1890: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArrayRead()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecRestoreArrayReadF90()`, `VecPlaceArray()`, `VecRestoreArray2d()`,
1891: `VecGetArrayPair()`, `VecRestoreArrayPair()`
1892: @*/
1893: PetscErrorCode VecRestoreArray(Vec x, PetscScalar **a)
1894: {
1895: PetscFunctionBegin;
1898: if (x->ops->restorearray) {
1899: PetscUseTypeMethod(x, restorearray, a);
1900: } else PetscCheck(x->petscnative, PetscObjectComm((PetscObject)x), PETSC_ERR_SUP, "Cannot restore array for vector type \"%s\"", ((PetscObject)x)->type_name);
1901: if (a) *a = NULL;
1902: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1903: PetscFunctionReturn(PETSC_SUCCESS);
1904: }
1905: /*@C
1906: VecGetArrayRead - Get read-only pointer to contiguous array containing this processor's portion of the vector data.
1908: Not Collective
1910: Input Parameter:
1911: . x - the vector
1913: Output Parameter:
1914: . a - the array
1916: Level: beginner
1918: Notes:
1919: The array must be returned using a matching call to `VecRestoreArrayRead()`.
1921: Unlike `VecGetArray()`, preserves cached information like vector norms.
1923: Standard PETSc vectors use contiguous storage so that this routine does not perform a copy. Other vector
1924: implementations may require a copy, but such implementations should cache the contiguous representation so that
1925: only one copy is performed when this routine is called multiple times in sequence.
1927: Fortran Note:
1928: `VecGetArrayRead()` Fortran binding is deprecated (since PETSc 3.19), use `VecGetArrayReadF90()`
1930: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayReadF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
1931: @*/
1932: PetscErrorCode VecGetArrayRead(Vec x, const PetscScalar **a)
1933: {
1934: PetscFunctionBegin;
1937: if (x->ops->getarrayread) {
1938: PetscUseTypeMethod(x, getarrayread, a);
1939: } else if (x->ops->getarray) {
1940: PetscObjectState state;
1942: /* VECNEST, VECCUDA, VECKOKKOS etc */
1943: // x->ops->getarray may bump the object state, but since we know this is a read-only get
1944: // we can just undo that
1945: PetscCall(PetscObjectStateGet((PetscObject)x, &state));
1946: PetscUseTypeMethod(x, getarray, (PetscScalar **)a);
1947: PetscCall(PetscObjectStateSet((PetscObject)x, state));
1948: } else if (x->petscnative) {
1949: /* VECSTANDARD */
1950: *a = *((PetscScalar **)x->data);
1951: } else SETERRQ(PetscObjectComm((PetscObject)x), PETSC_ERR_SUP, "Cannot get array read for vector type \"%s\"", ((PetscObject)x)->type_name);
1952: PetscFunctionReturn(PETSC_SUCCESS);
1953: }
1955: /*@C
1956: VecRestoreArrayRead - Restore array obtained with `VecGetArrayRead()`
1958: Not Collective
1960: Input Parameters:
1961: + vec - the vector
1962: - array - the array
1964: Level: beginner
1966: Fortran Note:
1967: `VecRestoreArrayRead()` Fortran binding is deprecated (since PETSc 3.19), use `VecRestoreArrayReadF90()`
1969: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayReadF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
1970: @*/
1971: PetscErrorCode VecRestoreArrayRead(Vec x, const PetscScalar **a)
1972: {
1973: PetscFunctionBegin;
1976: if (x->petscnative) { /* VECSTANDARD, VECCUDA, VECKOKKOS etc */
1977: /* nothing */
1978: } else if (x->ops->restorearrayread) { /* VECNEST */
1979: PetscUseTypeMethod(x, restorearrayread, a);
1980: } else { /* No one? */
1981: PetscObjectState state;
1983: // x->ops->restorearray may bump the object state, but since we know this is a read-restore
1984: // we can just undo that
1985: PetscCall(PetscObjectStateGet((PetscObject)x, &state));
1986: PetscUseTypeMethod(x, restorearray, (PetscScalar **)a);
1987: PetscCall(PetscObjectStateSet((PetscObject)x, state));
1988: }
1989: if (a) *a = NULL;
1990: PetscFunctionReturn(PETSC_SUCCESS);
1991: }
1993: /*@C
1994: VecGetArrayWrite - Returns a pointer to a contiguous array that WILL contain this
1995: processor's portion of the vector data. The values in this array are NOT valid, the caller of this
1996: routine is responsible for putting values into the array; any values it does not set will be invalid
1998: Logically Collective
2000: Input Parameter:
2001: . x - the vector
2003: Output Parameter:
2004: . a - location to put pointer to the array
2006: Level: intermediate
2008: Note:
2009: The array must be returned using a matching call to `VecRestoreArrayRead()`.
2011: For vectors associated with GPUs, the host and device vectors are not synchronized before giving access. If you need correct
2012: values in the array use `VecGetArray()`
2014: Fortran Note:
2015: `VecGetArrayWrite()` Fortran binding is deprecated (since PETSc 3.19), use `VecGetArrayWriteF90()`
2017: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayWriteF90()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecGetArrayReadF90()`, `VecPlaceArray()`, `VecGetArray2d()`,
2018: `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArray()`, `VecRestoreArrayWrite()`
2019: @*/
2020: PetscErrorCode VecGetArrayWrite(Vec x, PetscScalar **a)
2021: {
2022: PetscFunctionBegin;
2025: PetscCall(VecSetErrorIfLocked(x, 1));
2026: if (x->ops->getarraywrite) {
2027: PetscUseTypeMethod(x, getarraywrite, a);
2028: } else {
2029: PetscCall(VecGetArray(x, a));
2030: }
2031: PetscFunctionReturn(PETSC_SUCCESS);
2032: }
2034: /*@C
2035: VecRestoreArrayWrite - Restores a vector after `VecGetArrayWrite()` has been called.
2037: Logically Collective
2039: Input Parameters:
2040: + x - the vector
2041: - a - location of pointer to array obtained from `VecGetArray()`
2043: Level: beginner
2045: Fortran Note:
2046: `VecRestoreArrayWrite()` Fortran binding is deprecated (since PETSc 3.19), use `VecRestoreArrayWriteF90()`
2048: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayWriteF90()`, `VecGetArray()`, `VecRestoreArrayRead()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecRestoreArrayReadF90()`, `VecPlaceArray()`, `VecRestoreArray2d()`,
2049: `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayWrite()`
2050: @*/
2051: PetscErrorCode VecRestoreArrayWrite(Vec x, PetscScalar **a)
2052: {
2053: PetscFunctionBegin;
2056: if (x->ops->restorearraywrite) {
2057: PetscUseTypeMethod(x, restorearraywrite, a);
2058: } else if (x->ops->restorearray) {
2059: PetscUseTypeMethod(x, restorearray, a);
2060: }
2061: if (a) *a = NULL;
2062: PetscCall(PetscObjectStateIncrease((PetscObject)x));
2063: PetscFunctionReturn(PETSC_SUCCESS);
2064: }
2066: /*@C
2067: VecGetArrays - Returns a pointer to the arrays in a set of vectors
2068: that were created by a call to `VecDuplicateVecs()`.
2070: Logically Collective; No Fortran Support
2072: Input Parameters:
2073: + x - the vectors
2074: - n - the number of vectors
2076: Output Parameter:
2077: . a - location to put pointer to the array
2079: Level: intermediate
2081: Note:
2082: You MUST call `VecRestoreArrays()` when you no longer need access to the arrays.
2084: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArrays()`
2085: @*/
2086: PetscErrorCode VecGetArrays(const Vec x[], PetscInt n, PetscScalar **a[])
2087: {
2088: PetscInt i;
2089: PetscScalar **q;
2091: PetscFunctionBegin;
2095: PetscCheck(n > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Must get at least one array n = %" PetscInt_FMT, n);
2096: PetscCall(PetscMalloc1(n, &q));
2097: for (i = 0; i < n; ++i) PetscCall(VecGetArray(x[i], &q[i]));
2098: *a = q;
2099: PetscFunctionReturn(PETSC_SUCCESS);
2100: }
2102: /*@C
2103: VecRestoreArrays - Restores a group of vectors after `VecGetArrays()`
2104: has been called.
2106: Logically Collective; No Fortran Support
2108: Input Parameters:
2109: + x - the vector
2110: . n - the number of vectors
2111: - a - location of pointer to arrays obtained from `VecGetArrays()`
2113: Notes:
2114: For regular PETSc vectors this routine does not involve any copies. For
2115: any special vectors that do not store local vector data in a contiguous
2116: array, this routine will copy the data back into the underlying
2117: vector data structure from the arrays obtained with `VecGetArrays()`.
2119: Level: intermediate
2121: .seealso: [](chapter_vectors), `Vec`, `VecGetArrays()`, `VecRestoreArray()`
2122: @*/
2123: PetscErrorCode VecRestoreArrays(const Vec x[], PetscInt n, PetscScalar **a[])
2124: {
2125: PetscInt i;
2126: PetscScalar **q = *a;
2128: PetscFunctionBegin;
2133: for (i = 0; i < n; ++i) PetscCall(VecRestoreArray(x[i], &q[i]));
2134: PetscCall(PetscFree(q));
2135: PetscFunctionReturn(PETSC_SUCCESS);
2136: }
2138: /*@C
2139: VecGetArrayAndMemType - Like `VecGetArray()`, but if this is a standard device vector (e.g., `VECCUDA`), the returned pointer will be a device
2140: pointer to the device memory that contains this processor's portion of the vector data. Device data is guaranteed to have the latest value.
2141: Otherwise, when this is a host vector (e.g., `VECMPI`), this routine functions the same as `VecGetArray()` and returns a host pointer.
2143: For `VECKOKKOS`, if Kokkos is configured without device (e.g., use serial or openmp), per this function, the vector works like `VECSEQ`/`VECMPI`;
2144: otherwise, it works like `VECCUDA` or `VECHIP` etc.
2146: Logically Collective; No Fortran Support
2148: Input Parameter:
2149: . x - the vector
2151: Output Parameters:
2152: + a - location to put pointer to the array
2153: - mtype - memory type of the array
2155: Level: beginner
2157: Note:
2158: Use `VecRestoreArrayAndMemType()` when the array access is no longer needed
2160: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayAndMemType()`, `VecGetArrayReadAndMemType()`, `VecGetArrayWriteAndMemType()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecGetArrayReadF90()`,
2161: `VecPlaceArray()`, `VecGetArray2d()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayWrite()`, `VecRestoreArrayWrite()`
2162: @*/
2163: PetscErrorCode VecGetArrayAndMemType(Vec x, PetscScalar **a, PetscMemType *mtype)
2164: {
2165: PetscFunctionBegin;
2170: PetscCall(VecSetErrorIfLocked(x, 1));
2171: if (x->ops->getarrayandmemtype) {
2172: /* VECCUDA, VECKOKKOS etc */
2173: PetscUseTypeMethod(x, getarrayandmemtype, a, mtype);
2174: } else {
2175: /* VECSTANDARD, VECNEST, VECVIENNACL */
2176: PetscCall(VecGetArray(x, a));
2177: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2178: }
2179: PetscFunctionReturn(PETSC_SUCCESS);
2180: }
2182: /*@C
2183: VecRestoreArrayAndMemType - Restores a vector after `VecGetArrayAndMemType()` has been called.
2185: Logically Collective; No Fortran Support
2187: Input Parameters:
2188: + x - the vector
2189: - a - location of pointer to array obtained from `VecGetArrayAndMemType()`
2191: Level: beginner
2193: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayAndMemType()`, `VecGetArray()`, `VecRestoreArrayRead()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecRestoreArrayReadF90()`,
2194: `VecPlaceArray()`, `VecRestoreArray2d()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
2195: @*/
2196: PetscErrorCode VecRestoreArrayAndMemType(Vec x, PetscScalar **a)
2197: {
2198: PetscFunctionBegin;
2202: if (x->ops->restorearrayandmemtype) {
2203: /* VECCUDA, VECKOKKOS etc */
2204: PetscUseTypeMethod(x, restorearrayandmemtype, a);
2205: } else {
2206: /* VECNEST, VECVIENNACL */
2207: PetscCall(VecRestoreArray(x, a));
2208: } /* VECSTANDARD does nothing */
2209: if (a) *a = NULL;
2210: PetscCall(PetscObjectStateIncrease((PetscObject)x));
2211: PetscFunctionReturn(PETSC_SUCCESS);
2212: }
2214: /*@C
2215: VecGetArrayReadAndMemType - Like `VecGetArrayRead()`, but if the input vector is a device vector, it will return a read-only device pointer.
2216: The returned pointer is guaranteed to point to up-to-date data. For host vectors, it functions as `VecGetArrayRead()`.
2218: Not Collective; No Fortran Support
2220: Input Parameter:
2221: . x - the vector
2223: Output Parameters:
2224: + a - the array
2225: - mtype - memory type of the array
2227: Level: beginner
2229: Notes:
2230: The array must be returned using a matching call to `VecRestoreArrayReadAndMemType()`.
2232: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayReadAndMemType()`, `VecGetArrayAndMemType()`, `VecGetArrayWriteAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayAndMemType()`
2233: @*/
2234: PetscErrorCode VecGetArrayReadAndMemType(Vec x, const PetscScalar **a, PetscMemType *mtype)
2235: {
2236: PetscFunctionBegin;
2241: if (x->ops->getarrayreadandmemtype) {
2242: /* VECCUDA/VECHIP though they are also petscnative */
2243: PetscUseTypeMethod(x, getarrayreadandmemtype, a, mtype);
2244: } else if (x->ops->getarrayandmemtype) {
2245: /* VECKOKKOS */
2246: PetscObjectState state;
2248: // see VecGetArrayRead() for why
2249: PetscCall(PetscObjectStateGet((PetscObject)x, &state));
2250: PetscUseTypeMethod(x, getarrayandmemtype, (PetscScalar **)a, mtype);
2251: PetscCall(PetscObjectStateSet((PetscObject)x, state));
2252: } else {
2253: PetscCall(VecGetArrayRead(x, a));
2254: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2255: }
2256: PetscFunctionReturn(PETSC_SUCCESS);
2257: }
2259: /*@C
2260: VecRestoreArrayReadAndMemType - Restore array obtained with `VecGetArrayReadAndMemType()`
2262: Not Collective; No Fortran Support
2264: Input Parameters:
2265: + vec - the vector
2266: - array - the array
2268: Level: beginner
2270: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayReadAndMemType()`, `VecRestoreArrayAndMemType()`, `VecRestoreArrayWriteAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
2271: @*/
2272: PetscErrorCode VecRestoreArrayReadAndMemType(Vec x, const PetscScalar **a)
2273: {
2274: PetscFunctionBegin;
2278: if (x->ops->restorearrayreadandmemtype) {
2279: /* VECCUDA/VECHIP */
2280: PetscUseTypeMethod(x, restorearrayreadandmemtype, a);
2281: } else if (!x->petscnative) {
2282: /* VECNEST */
2283: PetscCall(VecRestoreArrayRead(x, a));
2284: }
2285: if (a) *a = NULL;
2286: PetscFunctionReturn(PETSC_SUCCESS);
2287: }
2289: /*@C
2290: VecGetArrayWriteAndMemType - Like `VecGetArrayWrite()`, but if this is a device vector it will always return
2291: a device pointer to the device memory that contains this processor's portion of the vector data.
2293: Not Collective; No Fortran Support
2295: Input Parameter:
2296: . x - the vector
2298: Output Parameters:
2299: + a - the array
2300: - mtype - memory type of the array
2302: Level: beginner
2304: Note:
2305: The array must be returned using a matching call to `VecRestoreArrayWriteAndMemType()`, where it will label the device memory as most recent.
2307: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayWriteAndMemType()`, `VecGetArrayReadAndMemType()`, `VecGetArrayAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`,
2308: @*/
2309: PetscErrorCode VecGetArrayWriteAndMemType(Vec x, PetscScalar **a, PetscMemType *mtype)
2310: {
2311: PetscFunctionBegin;
2314: PetscCall(VecSetErrorIfLocked(x, 1));
2317: if (x->ops->getarraywriteandmemtype) {
2318: /* VECCUDA, VECHIP, VECKOKKOS etc, though they are also petscnative */
2319: PetscUseTypeMethod(x, getarraywriteandmemtype, a, mtype);
2320: } else if (x->ops->getarrayandmemtype) {
2321: PetscCall(VecGetArrayAndMemType(x, a, mtype));
2322: } else {
2323: /* VECNEST, VECVIENNACL */
2324: PetscCall(VecGetArrayWrite(x, a));
2325: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2326: }
2327: PetscFunctionReturn(PETSC_SUCCESS);
2328: }
2330: /*@C
2331: VecRestoreArrayWriteAndMemType - Restore array obtained with `VecGetArrayWriteAndMemType()`
2333: Not Collective; No Fortran Support
2335: Input Parameters:
2336: + vec - the vector
2337: - array - the array
2339: Level: beginner
2341: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayWriteAndMemType()`, `VecRestoreArrayAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
2342: @*/
2343: PetscErrorCode VecRestoreArrayWriteAndMemType(Vec x, PetscScalar **a)
2344: {
2345: PetscFunctionBegin;
2348: PetscCall(VecSetErrorIfLocked(x, 1));
2350: if (x->ops->restorearraywriteandmemtype) {
2351: /* VECCUDA/VECHIP */
2352: PetscMemType PETSC_UNUSED mtype; // since this function doesn't accept a memtype?
2353: PetscUseTypeMethod(x, restorearraywriteandmemtype, a, &mtype);
2354: } else if (x->ops->restorearrayandmemtype) {
2355: PetscCall(VecRestoreArrayAndMemType(x, a));
2356: } else {
2357: PetscCall(VecRestoreArray(x, a));
2358: }
2359: if (a) *a = NULL;
2360: PetscFunctionReturn(PETSC_SUCCESS);
2361: }
2363: /*@
2364: VecPlaceArray - Allows one to replace the array in a vector with an
2365: array provided by the user. This is useful to avoid copying an array
2366: into a vector.
2368: Not Collective; No Fortran Support
2370: Input Parameters:
2371: + vec - the vector
2372: - array - the array
2374: Level: developer
2376: Notes:
2377: Use `VecReplaceArray()` instead to permanently replace the array
2379: You can return to the original array with a call to `VecResetArray()`. `vec` does not take
2380: ownership of `array` in any way.
2382: The user must free `array` themselves but be careful not to
2383: do so before the vector has either been destroyed, had its original array restored with
2384: `VecResetArray()` or permanently replaced with `VecReplaceArray()`.
2386: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecResetArray()`
2387: @*/
2388: PetscErrorCode VecPlaceArray(Vec vec, const PetscScalar array[])
2389: {
2390: PetscFunctionBegin;
2394: PetscUseTypeMethod(vec, placearray, array);
2395: PetscCall(PetscObjectStateIncrease((PetscObject)vec));
2396: PetscFunctionReturn(PETSC_SUCCESS);
2397: }
2399: /*@C
2400: VecReplaceArray - Allows one to replace the array in a vector with an
2401: array provided by the user. This is useful to avoid copying an array
2402: into a vector.
2404: Not Collective; No Fortran Support
2406: Input Parameters:
2407: + vec - the vector
2408: - array - the array
2410: Level: developer
2412: Notes:
2413: This permanently replaces the array and frees the memory associated
2414: with the old array. Use `VecPlaceArray()` to temporarily replace the array.
2416: The memory passed in MUST be obtained with `PetscMalloc()` and CANNOT be
2417: freed by the user. It will be freed when the vector is destroyed.
2419: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecPlaceArray()`, `VecResetArray()`
2420: @*/
2421: PetscErrorCode VecReplaceArray(Vec vec, const PetscScalar array[])
2422: {
2423: PetscFunctionBegin;
2426: PetscUseTypeMethod(vec, replacearray, array);
2427: PetscCall(PetscObjectStateIncrease((PetscObject)vec));
2428: PetscFunctionReturn(PETSC_SUCCESS);
2429: }
2431: /*MC
2432: VecDuplicateVecsF90 - Creates several vectors of the same type as an existing vector
2433: and makes them accessible via a Fortran pointer.
2435: Synopsis:
2436: VecDuplicateVecsF90(Vec x,PetscInt n,{Vec, pointer :: y(:)},integer ierr)
2438: Collective
2440: Input Parameters:
2441: + x - a vector to mimic
2442: - n - the number of vectors to obtain
2444: Output Parameters:
2445: + y - Fortran pointer to the array of vectors
2446: - ierr - error code
2448: Example of Usage:
2449: .vb
2450: #include <petsc/finclude/petscvec.h>
2451: use petscvec
2453: Vec x
2454: Vec, pointer :: y(:)
2455: ....
2456: call VecDuplicateVecsF90(x,2,y,ierr)
2457: call VecSet(y(2),alpha,ierr)
2458: call VecSet(y(2),alpha,ierr)
2459: ....
2460: call VecDestroyVecsF90(2,y,ierr)
2461: .ve
2463: Level: beginner
2465: Note:
2466: Use `VecDestroyVecsF90()` to free the space.
2468: .seealso: [](chapter_vectors), `Vec`, `VecDestroyVecsF90()`, `VecDuplicateVecs()`
2469: M*/
2471: /*MC
2472: VecRestoreArrayF90 - Restores a vector to a usable state after a call to
2473: `VecGetArrayF90()`.
2475: Synopsis:
2476: VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2478: Logically Collective
2480: Input Parameters:
2481: + x - vector
2482: - xx_v - the Fortran pointer to the array
2484: Output Parameter:
2485: . ierr - error code
2487: Example of Usage:
2488: .vb
2489: #include <petsc/finclude/petscvec.h>
2490: use petscvec
2492: PetscScalar, pointer :: xx_v(:)
2493: ....
2494: call VecGetArrayF90(x,xx_v,ierr)
2495: xx_v(3) = a
2496: call VecRestoreArrayF90(x,xx_v,ierr)
2497: .ve
2499: Level: beginner
2501: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrayReadF90()`
2502: M*/
2504: /*MC
2505: VecDestroyVecsF90 - Frees a block of vectors obtained with `VecDuplicateVecsF90()`.
2507: Synopsis:
2508: VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)
2510: Collective
2512: Input Parameters:
2513: + n - the number of vectors previously obtained
2514: - x - pointer to array of vector pointers
2516: Output Parameter:
2517: . ierr - error code
2519: Level: beginner
2521: .seealso: [](chapter_vectors), `Vec`, `VecDestroyVecs()`, `VecDuplicateVecsF90()`
2522: M*/
2524: /*MC
2525: VecGetArrayF90 - Accesses a vector array from Fortran. For default PETSc
2526: vectors, `VecGetArrayF90()` returns a pointer to the local data array. Otherwise,
2527: this routine is implementation dependent. You MUST call `VecRestoreArrayF90()`
2528: when you no longer need access to the array.
2530: Synopsis:
2531: VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2533: Logically Collective
2535: Input Parameter:
2536: . x - vector
2538: Output Parameters:
2539: + xx_v - the Fortran pointer to the array
2540: - ierr - error code
2542: Example of Usage:
2543: .vb
2544: #include <petsc/finclude/petscvec.h>
2545: use petscvec
2547: PetscScalar, pointer :: xx_v(:)
2548: ....
2549: call VecGetArrayF90(x,xx_v,ierr)
2550: xx_v(3) = a
2551: call VecRestoreArrayF90(x,xx_v,ierr)
2552: .ve
2554: Level: beginner
2556: Note:
2557: If you ONLY intend to read entries from the array and not change any entries you should use `VecGetArrayReadF90()`.
2559: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayReadF90()`
2560: M*/
2562: /*MC
2563: VecGetArrayReadF90 - Accesses a read only array from Fortran. For default PETSc
2564: vectors, `VecGetArrayF90()` returns a pointer to the local data array. Otherwise,
2565: this routine is implementation dependent. You MUST call `VecRestoreArrayReadF90()`
2566: when you no longer need access to the array.
2568: Synopsis:
2569: VecGetArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2571: Logically Collective
2573: Input Parameter:
2574: . x - vector
2576: Output Parameters:
2577: + xx_v - the Fortran pointer to the array
2578: - ierr - error code
2580: Example of Usage:
2581: .vb
2582: #include <petsc/finclude/petscvec.h>
2583: use petscvec
2585: PetscScalar, pointer :: xx_v(:)
2586: ....
2587: call VecGetArrayReadF90(x,xx_v,ierr)
2588: a = xx_v(3)
2589: call VecRestoreArrayReadF90(x,xx_v,ierr)
2590: .ve
2592: Level: beginner
2594: Note:
2595: If you intend to write entries into the array you must use `VecGetArrayF90()`.
2597: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayReadF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecRestoreArrayRead()`, `VecGetArrayF90()`
2598: M*/
2600: /*MC
2601: VecRestoreArrayReadF90 - Restores a readonly vector to a usable state after a call to
2602: `VecGetArrayReadF90()`.
2604: Synopsis:
2605: VecRestoreArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2607: Logically Collective
2609: Input Parameters:
2610: + x - vector
2611: - xx_v - the Fortran pointer to the array
2613: Output Parameter:
2614: . ierr - error code
2616: Example of Usage:
2617: .vb
2618: #include <petsc/finclude/petscvec.h>
2619: use petscvec
2621: PetscScalar, pointer :: xx_v(:)
2622: ....
2623: call VecGetArrayReadF90(x,xx_v,ierr)
2624: a = xx_v(3)
2625: call VecRestoreArrayReadF90(x,xx_v,ierr)
2626: .ve
2628: Level: beginner
2630: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayReadF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecRestoreArrayRead()`, `VecRestoreArrayF90()`
2631: M*/
2633: /*@C
2634: VecGetArray2d - Returns a pointer to a 2d contiguous array that contains this
2635: processor's portion of the vector data. You MUST call `VecRestoreArray2d()`
2636: when you no longer need access to the array.
2638: Logically Collective
2640: Input Parameters:
2641: + x - the vector
2642: . m - first dimension of two dimensional array
2643: . n - second dimension of two dimensional array
2644: . mstart - first index you will use in first coordinate direction (often 0)
2645: - nstart - first index in the second coordinate direction (often 0)
2647: Output Parameter:
2648: . a - location to put pointer to the array
2650: Level: developer
2652: Notes:
2653: For a vector obtained from `DMCreateLocalVector()` mstart and nstart are likely
2654: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2655: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
2656: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray2d()`.
2658: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2660: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2661: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
2662: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2663: @*/
2664: PetscErrorCode VecGetArray2d(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
2665: {
2666: PetscInt i, N;
2667: PetscScalar *aa;
2669: PetscFunctionBegin;
2673: PetscCall(VecGetLocalSize(x, &N));
2674: PetscCheck(m * n == N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local array size %" PetscInt_FMT " does not match 2d array dimensions %" PetscInt_FMT " by %" PetscInt_FMT, N, m, n);
2675: PetscCall(VecGetArray(x, &aa));
2677: PetscCall(PetscMalloc1(m, a));
2678: for (i = 0; i < m; i++) (*a)[i] = aa + i * n - nstart;
2679: *a -= mstart;
2680: PetscFunctionReturn(PETSC_SUCCESS);
2681: }
2683: /*@C
2684: VecGetArray2dWrite - Returns a pointer to a 2d contiguous array that will contain this
2685: processor's portion of the vector data. You MUST call `VecRestoreArray2dWrite()`
2686: when you no longer need access to the array.
2688: Logically Collective
2690: Input Parameters:
2691: + x - the vector
2692: . m - first dimension of two dimensional array
2693: . n - second dimension of two dimensional array
2694: . mstart - first index you will use in first coordinate direction (often 0)
2695: - nstart - first index in the second coordinate direction (often 0)
2697: Output Parameter:
2698: . a - location to put pointer to the array
2700: Level: developer
2702: Notes:
2703: For a vector obtained from `DMCreateLocalVector()` mstart and nstart are likely
2704: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2705: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
2706: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray2d()`.
2708: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2710: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2711: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
2712: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2713: @*/
2714: PetscErrorCode VecGetArray2dWrite(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
2715: {
2716: PetscInt i, N;
2717: PetscScalar *aa;
2719: PetscFunctionBegin;
2723: PetscCall(VecGetLocalSize(x, &N));
2724: PetscCheck(m * n == N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local array size %" PetscInt_FMT " does not match 2d array dimensions %" PetscInt_FMT " by %" PetscInt_FMT, N, m, n);
2725: PetscCall(VecGetArrayWrite(x, &aa));
2727: PetscCall(PetscMalloc1(m, a));
2728: for (i = 0; i < m; i++) (*a)[i] = aa + i * n - nstart;
2729: *a -= mstart;
2730: PetscFunctionReturn(PETSC_SUCCESS);
2731: }
2733: /*@C
2734: VecRestoreArray2d - Restores a vector after `VecGetArray2d()` has been called.
2736: Logically Collective
2738: Input Parameters:
2739: + x - the vector
2740: . m - first dimension of two dimensional array
2741: . n - second dimension of the two dimensional array
2742: . mstart - first index you will use in first coordinate direction (often 0)
2743: . nstart - first index in the second coordinate direction (often 0)
2744: - a - location of pointer to array obtained from `VecGetArray2d()`
2746: Level: developer
2748: Notes:
2749: For regular PETSc vectors this routine does not involve any copies. For
2750: any special vectors that do not store local vector data in a contiguous
2751: array, this routine will copy the data back into the underlying
2752: vector data structure from the array obtained with `VecGetArray()`.
2754: This routine actually zeros out the a pointer.
2756: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
2757: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
2758: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2759: @*/
2760: PetscErrorCode VecRestoreArray2d(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
2761: {
2762: void *dummy;
2764: PetscFunctionBegin;
2768: dummy = (void *)(*a + mstart);
2769: PetscCall(PetscFree(dummy));
2770: PetscCall(VecRestoreArray(x, NULL));
2771: PetscFunctionReturn(PETSC_SUCCESS);
2772: }
2774: /*@C
2775: VecRestoreArray2dWrite - Restores a vector after VecGetArray2dWrite`()` has been called.
2777: Logically Collective
2779: Input Parameters:
2780: + x - the vector
2781: . m - first dimension of two dimensional array
2782: . n - second dimension of the two dimensional array
2783: . mstart - first index you will use in first coordinate direction (often 0)
2784: . nstart - first index in the second coordinate direction (often 0)
2785: - a - location of pointer to array obtained from `VecGetArray2d()`
2787: Level: developer
2789: Notes:
2790: For regular PETSc vectors this routine does not involve any copies. For
2791: any special vectors that do not store local vector data in a contiguous
2792: array, this routine will copy the data back into the underlying
2793: vector data structure from the array obtained with `VecGetArray()`.
2795: This routine actually zeros out the a pointer.
2797: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
2798: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
2799: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2800: @*/
2801: PetscErrorCode VecRestoreArray2dWrite(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
2802: {
2803: void *dummy;
2805: PetscFunctionBegin;
2809: dummy = (void *)(*a + mstart);
2810: PetscCall(PetscFree(dummy));
2811: PetscCall(VecRestoreArrayWrite(x, NULL));
2812: PetscFunctionReturn(PETSC_SUCCESS);
2813: }
2815: /*@C
2816: VecGetArray1d - Returns a pointer to a 1d contiguous array that contains this
2817: processor's portion of the vector data. You MUST call `VecRestoreArray1d()`
2818: when you no longer need access to the array.
2820: Logically Collective
2822: Input Parameters:
2823: + x - the vector
2824: . m - first dimension of two dimensional array
2825: - mstart - first index you will use in first coordinate direction (often 0)
2827: Output Parameter:
2828: . a - location to put pointer to the array
2830: Level: developer
2832: Notes:
2833: For a vector obtained from `DMCreateLocalVector()` mstart are likely
2834: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2835: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`.
2837: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2839: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2840: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
2841: `VecGetArray2d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2842: @*/
2843: PetscErrorCode VecGetArray1d(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
2844: {
2845: PetscInt N;
2847: PetscFunctionBegin;
2851: PetscCall(VecGetLocalSize(x, &N));
2852: PetscCheck(m == N, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local array size %" PetscInt_FMT " does not match 1d array dimensions %" PetscInt_FMT, N, m);
2853: PetscCall(VecGetArray(x, a));
2854: *a -= mstart;
2855: PetscFunctionReturn(PETSC_SUCCESS);
2856: }
2858: /*@C
2859: VecGetArray1dWrite - Returns a pointer to a 1d contiguous array that will contain this
2860: processor's portion of the vector data. You MUST call `VecRestoreArray1dWrite()`
2861: when you no longer need access to the array.
2863: Logically Collective
2865: Input Parameters:
2866: + x - the vector
2867: . m - first dimension of two dimensional array
2868: - mstart - first index you will use in first coordinate direction (often 0)
2870: Output Parameter:
2871: . a - location to put pointer to the array
2873: Level: developer
2875: Notes:
2876: For a vector obtained from `DMCreateLocalVector()` mstart are likely
2877: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2878: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`.
2880: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2882: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2883: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
2884: `VecGetArray2d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2885: @*/
2886: PetscErrorCode VecGetArray1dWrite(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
2887: {
2888: PetscInt N;
2890: PetscFunctionBegin;
2894: PetscCall(VecGetLocalSize(x, &N));
2895: PetscCheck(m == N, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local array size %" PetscInt_FMT " does not match 1d array dimensions %" PetscInt_FMT, N, m);
2896: PetscCall(VecGetArrayWrite(x, a));
2897: *a -= mstart;
2898: PetscFunctionReturn(PETSC_SUCCESS);
2899: }
2901: /*@C
2902: VecRestoreArray1d - Restores a vector after `VecGetArray1d()` has been called.
2904: Logically Collective
2906: Input Parameters:
2907: + x - the vector
2908: . m - first dimension of two dimensional array
2909: . mstart - first index you will use in first coordinate direction (often 0)
2910: - a - location of pointer to array obtained from `VecGetArray1d()`
2912: Level: developer
2914: Notes:
2915: For regular PETSc vectors this routine does not involve any copies. For
2916: any special vectors that do not store local vector data in a contiguous
2917: array, this routine will copy the data back into the underlying
2918: vector data structure from the array obtained with `VecGetArray1d()`.
2920: This routine actually zeros out the a pointer.
2922: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
2923: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
2924: `VecGetArray1d()`, `VecRestoreArray2d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2925: @*/
2926: PetscErrorCode VecRestoreArray1d(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
2927: {
2928: PetscFunctionBegin;
2931: PetscCall(VecRestoreArray(x, NULL));
2932: PetscFunctionReturn(PETSC_SUCCESS);
2933: }
2935: /*@C
2936: VecRestoreArray1dWrite - Restores a vector after `VecGetArray1dWrite()` has been called.
2938: Logically Collective
2940: Input Parameters:
2941: + x - the vector
2942: . m - first dimension of two dimensional array
2943: . mstart - first index you will use in first coordinate direction (often 0)
2944: - a - location of pointer to array obtained from `VecGetArray1d()`
2946: Level: developer
2948: Notes:
2949: For regular PETSc vectors this routine does not involve any copies. For
2950: any special vectors that do not store local vector data in a contiguous
2951: array, this routine will copy the data back into the underlying
2952: vector data structure from the array obtained with `VecGetArray1d()`.
2954: This routine actually zeros out the a pointer.
2956: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
2957: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
2958: `VecGetArray1d()`, `VecRestoreArray2d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2959: @*/
2960: PetscErrorCode VecRestoreArray1dWrite(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
2961: {
2962: PetscFunctionBegin;
2965: PetscCall(VecRestoreArrayWrite(x, NULL));
2966: PetscFunctionReturn(PETSC_SUCCESS);
2967: }
2969: /*@C
2970: VecGetArray3d - Returns a pointer to a 3d contiguous array that contains this
2971: processor's portion of the vector data. You MUST call `VecRestoreArray3d()`
2972: when you no longer need access to the array.
2974: Logically Collective
2976: Input Parameters:
2977: + x - the vector
2978: . m - first dimension of three dimensional array
2979: . n - second dimension of three dimensional array
2980: . p - third dimension of three dimensional array
2981: . mstart - first index you will use in first coordinate direction (often 0)
2982: . nstart - first index in the second coordinate direction (often 0)
2983: - pstart - first index in the third coordinate direction (often 0)
2985: Output Parameter:
2986: . a - location to put pointer to the array
2988: Level: developer
2990: Notes:
2991: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
2992: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2993: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
2994: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
2996: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2998: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2999: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3000: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3001: @*/
3002: PetscErrorCode VecGetArray3d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3003: {
3004: PetscInt i, N, j;
3005: PetscScalar *aa, **b;
3007: PetscFunctionBegin;
3011: PetscCall(VecGetLocalSize(x, &N));
3012: PetscCheck(m * n * p == N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local array size %" PetscInt_FMT " does not match 3d array dimensions %" PetscInt_FMT " by %" PetscInt_FMT " by %" PetscInt_FMT, N, m, n, p);
3013: PetscCall(VecGetArray(x, &aa));
3015: PetscCall(PetscMalloc(m * sizeof(PetscScalar **) + m * n * sizeof(PetscScalar *), a));
3016: b = (PetscScalar **)((*a) + m);
3017: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3018: for (i = 0; i < m; i++)
3019: for (j = 0; j < n; j++) b[i * n + j] = aa + i * n * p + j * p - pstart;
3020: *a -= mstart;
3021: PetscFunctionReturn(PETSC_SUCCESS);
3022: }
3024: /*@C
3025: VecGetArray3dWrite - Returns a pointer to a 3d contiguous array that will contain this
3026: processor's portion of the vector data. You MUST call `VecRestoreArray3dWrite()`
3027: when you no longer need access to the array.
3029: Logically Collective
3031: Input Parameters:
3032: + x - the vector
3033: . m - first dimension of three dimensional array
3034: . n - second dimension of three dimensional array
3035: . p - third dimension of three dimensional array
3036: . mstart - first index you will use in first coordinate direction (often 0)
3037: . nstart - first index in the second coordinate direction (often 0)
3038: - pstart - first index in the third coordinate direction (often 0)
3040: Output Parameter:
3041: . a - location to put pointer to the array
3043: Level: developer
3045: Notes:
3046: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3047: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3048: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3049: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
3051: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3053: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3054: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3055: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3056: @*/
3057: PetscErrorCode VecGetArray3dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3058: {
3059: PetscInt i, N, j;
3060: PetscScalar *aa, **b;
3062: PetscFunctionBegin;
3066: PetscCall(VecGetLocalSize(x, &N));
3067: PetscCheck(m * n * p == N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local array size %" PetscInt_FMT " does not match 3d array dimensions %" PetscInt_FMT " by %" PetscInt_FMT " by %" PetscInt_FMT, N, m, n, p);
3068: PetscCall(VecGetArrayWrite(x, &aa));
3070: PetscCall(PetscMalloc(m * sizeof(PetscScalar **) + m * n * sizeof(PetscScalar *), a));
3071: b = (PetscScalar **)((*a) + m);
3072: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3073: for (i = 0; i < m; i++)
3074: for (j = 0; j < n; j++) b[i * n + j] = aa + i * n * p + j * p - pstart;
3076: *a -= mstart;
3077: PetscFunctionReturn(PETSC_SUCCESS);
3078: }
3080: /*@C
3081: VecRestoreArray3d - Restores a vector after `VecGetArray3d()` has been called.
3083: Logically Collective
3085: Input Parameters:
3086: + x - the vector
3087: . m - first dimension of three dimensional array
3088: . n - second dimension of the three dimensional array
3089: . p - third dimension of the three dimensional array
3090: . mstart - first index you will use in first coordinate direction (often 0)
3091: . nstart - first index in the second coordinate direction (often 0)
3092: . pstart - first index in the third coordinate direction (often 0)
3093: - a - location of pointer to array obtained from VecGetArray3d()
3095: Level: developer
3097: Notes:
3098: For regular PETSc vectors this routine does not involve any copies. For
3099: any special vectors that do not store local vector data in a contiguous
3100: array, this routine will copy the data back into the underlying
3101: vector data structure from the array obtained with `VecGetArray()`.
3103: This routine actually zeros out the a pointer.
3105: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3106: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3107: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3108: @*/
3109: PetscErrorCode VecRestoreArray3d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3110: {
3111: void *dummy;
3113: PetscFunctionBegin;
3117: dummy = (void *)(*a + mstart);
3118: PetscCall(PetscFree(dummy));
3119: PetscCall(VecRestoreArray(x, NULL));
3120: PetscFunctionReturn(PETSC_SUCCESS);
3121: }
3123: /*@C
3124: VecRestoreArray3dWrite - Restores a vector after `VecGetArray3dWrite()` has been called.
3126: Logically Collective
3128: Input Parameters:
3129: + x - the vector
3130: . m - first dimension of three dimensional array
3131: . n - second dimension of the three dimensional array
3132: . p - third dimension of the three dimensional array
3133: . mstart - first index you will use in first coordinate direction (often 0)
3134: . nstart - first index in the second coordinate direction (often 0)
3135: . pstart - first index in the third coordinate direction (often 0)
3136: - a - location of pointer to array obtained from VecGetArray3d()
3138: Level: developer
3140: Notes:
3141: For regular PETSc vectors this routine does not involve any copies. For
3142: any special vectors that do not store local vector data in a contiguous
3143: array, this routine will copy the data back into the underlying
3144: vector data structure from the array obtained with `VecGetArray()`.
3146: This routine actually zeros out the a pointer.
3148: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3149: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3150: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3151: @*/
3152: PetscErrorCode VecRestoreArray3dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3153: {
3154: void *dummy;
3156: PetscFunctionBegin;
3160: dummy = (void *)(*a + mstart);
3161: PetscCall(PetscFree(dummy));
3162: PetscCall(VecRestoreArrayWrite(x, NULL));
3163: PetscFunctionReturn(PETSC_SUCCESS);
3164: }
3166: /*@C
3167: VecGetArray4d - Returns a pointer to a 4d contiguous array that contains this
3168: processor's portion of the vector data. You MUST call `VecRestoreArray4d()`
3169: when you no longer need access to the array.
3171: Logically Collective
3173: Input Parameters:
3174: + x - the vector
3175: . m - first dimension of four dimensional array
3176: . n - second dimension of four dimensional array
3177: . p - third dimension of four dimensional array
3178: . q - fourth dimension of four dimensional array
3179: . mstart - first index you will use in first coordinate direction (often 0)
3180: . nstart - first index in the second coordinate direction (often 0)
3181: . pstart - first index in the third coordinate direction (often 0)
3182: - qstart - first index in the fourth coordinate direction (often 0)
3184: Output Parameter:
3185: . a - location to put pointer to the array
3187: Level: beginner
3189: Notes:
3190: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3191: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3192: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3193: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
3195: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3197: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3198: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3199: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3200: @*/
3201: PetscErrorCode VecGetArray4d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3202: {
3203: PetscInt i, N, j, k;
3204: PetscScalar *aa, ***b, **c;
3206: PetscFunctionBegin;
3210: PetscCall(VecGetLocalSize(x, &N));
3211: PetscCheck(m * n * p * q == N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local array size %" PetscInt_FMT " does not match 4d array dimensions %" PetscInt_FMT " by %" PetscInt_FMT " by %" PetscInt_FMT " by %" PetscInt_FMT, N, m, n, p, q);
3212: PetscCall(VecGetArray(x, &aa));
3214: PetscCall(PetscMalloc(m * sizeof(PetscScalar ***) + m * n * sizeof(PetscScalar **) + m * n * p * sizeof(PetscScalar *), a));
3215: b = (PetscScalar ***)((*a) + m);
3216: c = (PetscScalar **)(b + m * n);
3217: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3218: for (i = 0; i < m; i++)
3219: for (j = 0; j < n; j++) b[i * n + j] = c + i * n * p + j * p - pstart;
3220: for (i = 0; i < m; i++)
3221: for (j = 0; j < n; j++)
3222: for (k = 0; k < p; k++) c[i * n * p + j * p + k] = aa + i * n * p * q + j * p * q + k * q - qstart;
3223: *a -= mstart;
3224: PetscFunctionReturn(PETSC_SUCCESS);
3225: }
3227: /*@C
3228: VecGetArray4dWrite - Returns a pointer to a 4d contiguous array that will contain this
3229: processor's portion of the vector data. You MUST call `VecRestoreArray4dWrite()`
3230: when you no longer need access to the array.
3232: Logically Collective
3234: Input Parameters:
3235: + x - the vector
3236: . m - first dimension of four dimensional array
3237: . n - second dimension of four dimensional array
3238: . p - third dimension of four dimensional array
3239: . q - fourth dimension of four dimensional array
3240: . mstart - first index you will use in first coordinate direction (often 0)
3241: . nstart - first index in the second coordinate direction (often 0)
3242: . pstart - first index in the third coordinate direction (often 0)
3243: - qstart - first index in the fourth coordinate direction (often 0)
3245: Output Parameter:
3246: . a - location to put pointer to the array
3248: Level: beginner
3250: Notes:
3251: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3252: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3253: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3254: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
3256: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3258: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3259: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3260: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3261: @*/
3262: PetscErrorCode VecGetArray4dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3263: {
3264: PetscInt i, N, j, k;
3265: PetscScalar *aa, ***b, **c;
3267: PetscFunctionBegin;
3271: PetscCall(VecGetLocalSize(x, &N));
3272: PetscCheck(m * n * p * q == N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local array size %" PetscInt_FMT " does not match 4d array dimensions %" PetscInt_FMT " by %" PetscInt_FMT " by %" PetscInt_FMT " by %" PetscInt_FMT, N, m, n, p, q);
3273: PetscCall(VecGetArrayWrite(x, &aa));
3275: PetscCall(PetscMalloc(m * sizeof(PetscScalar ***) + m * n * sizeof(PetscScalar **) + m * n * p * sizeof(PetscScalar *), a));
3276: b = (PetscScalar ***)((*a) + m);
3277: c = (PetscScalar **)(b + m * n);
3278: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3279: for (i = 0; i < m; i++)
3280: for (j = 0; j < n; j++) b[i * n + j] = c + i * n * p + j * p - pstart;
3281: for (i = 0; i < m; i++)
3282: for (j = 0; j < n; j++)
3283: for (k = 0; k < p; k++) c[i * n * p + j * p + k] = aa + i * n * p * q + j * p * q + k * q - qstart;
3284: *a -= mstart;
3285: PetscFunctionReturn(PETSC_SUCCESS);
3286: }
3288: /*@C
3289: VecRestoreArray4d - Restores a vector after `VecGetArray4d()` has been called.
3291: Logically Collective
3293: Input Parameters:
3294: + x - the vector
3295: . m - first dimension of four dimensional array
3296: . n - second dimension of the four dimensional array
3297: . p - third dimension of the four dimensional array
3298: . q - fourth dimension of the four dimensional array
3299: . mstart - first index you will use in first coordinate direction (often 0)
3300: . nstart - first index in the second coordinate direction (often 0)
3301: . pstart - first index in the third coordinate direction (often 0)
3302: . qstart - first index in the fourth coordinate direction (often 0)
3303: - a - location of pointer to array obtained from VecGetArray4d()
3305: Level: beginner
3307: Notes:
3308: For regular PETSc vectors this routine does not involve any copies. For
3309: any special vectors that do not store local vector data in a contiguous
3310: array, this routine will copy the data back into the underlying
3311: vector data structure from the array obtained with `VecGetArray()`.
3313: This routine actually zeros out the a pointer.
3315: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3316: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3317: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3318: @*/
3319: PetscErrorCode VecRestoreArray4d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3320: {
3321: void *dummy;
3323: PetscFunctionBegin;
3327: dummy = (void *)(*a + mstart);
3328: PetscCall(PetscFree(dummy));
3329: PetscCall(VecRestoreArray(x, NULL));
3330: PetscFunctionReturn(PETSC_SUCCESS);
3331: }
3333: /*@C
3334: VecRestoreArray4dWrite - Restores a vector after `VecGetArray4dWrite()` has been called.
3336: Logically Collective
3338: Input Parameters:
3339: + x - the vector
3340: . m - first dimension of four dimensional array
3341: . n - second dimension of the four dimensional array
3342: . p - third dimension of the four dimensional array
3343: . q - fourth dimension of the four dimensional array
3344: . mstart - first index you will use in first coordinate direction (often 0)
3345: . nstart - first index in the second coordinate direction (often 0)
3346: . pstart - first index in the third coordinate direction (often 0)
3347: . qstart - first index in the fourth coordinate direction (often 0)
3348: - a - location of pointer to array obtained from `VecGetArray4d()`
3350: Level: beginner
3352: Notes:
3353: For regular PETSc vectors this routine does not involve any copies. For
3354: any special vectors that do not store local vector data in a contiguous
3355: array, this routine will copy the data back into the underlying
3356: vector data structure from the array obtained with `VecGetArray()`.
3358: This routine actually zeros out the a pointer.
3360: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3361: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3362: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3363: @*/
3364: PetscErrorCode VecRestoreArray4dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3365: {
3366: void *dummy;
3368: PetscFunctionBegin;
3372: dummy = (void *)(*a + mstart);
3373: PetscCall(PetscFree(dummy));
3374: PetscCall(VecRestoreArrayWrite(x, NULL));
3375: PetscFunctionReturn(PETSC_SUCCESS);
3376: }
3378: /*@C
3379: VecGetArray2dRead - Returns a pointer to a 2d contiguous array that contains this
3380: processor's portion of the vector data. You MUST call `VecRestoreArray2dRead()`
3381: when you no longer need access to the array.
3383: Logically Collective
3385: Input Parameters:
3386: + x - the vector
3387: . m - first dimension of two dimensional array
3388: . n - second dimension of two dimensional array
3389: . mstart - first index you will use in first coordinate direction (often 0)
3390: - nstart - first index in the second coordinate direction (often 0)
3392: Output Parameter:
3393: . a - location to put pointer to the array
3395: Level: developer
3397: Notes:
3398: For a vector obtained from `DMCreateLocalVector()` mstart and nstart are likely
3399: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3400: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3401: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray2d()`.
3403: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3405: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3406: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3407: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3408: @*/
3409: PetscErrorCode VecGetArray2dRead(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
3410: {
3411: PetscInt i, N;
3412: const PetscScalar *aa;
3414: PetscFunctionBegin;
3418: PetscCall(VecGetLocalSize(x, &N));
3419: PetscCheck(m * n == N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local array size %" PetscInt_FMT " does not match 2d array dimensions %" PetscInt_FMT " by %" PetscInt_FMT, N, m, n);
3420: PetscCall(VecGetArrayRead(x, &aa));
3422: PetscCall(PetscMalloc1(m, a));
3423: for (i = 0; i < m; i++) (*a)[i] = (PetscScalar *)aa + i * n - nstart;
3424: *a -= mstart;
3425: PetscFunctionReturn(PETSC_SUCCESS);
3426: }
3428: /*@C
3429: VecRestoreArray2dRead - Restores a vector after `VecGetArray2dRead()` has been called.
3431: Logically Collective
3433: Input Parameters:
3434: + x - the vector
3435: . m - first dimension of two dimensional array
3436: . n - second dimension of the two dimensional array
3437: . mstart - first index you will use in first coordinate direction (often 0)
3438: . nstart - first index in the second coordinate direction (often 0)
3439: - a - location of pointer to array obtained from VecGetArray2d()
3441: Level: developer
3443: Notes:
3444: For regular PETSc vectors this routine does not involve any copies. For
3445: any special vectors that do not store local vector data in a contiguous
3446: array, this routine will copy the data back into the underlying
3447: vector data structure from the array obtained with `VecGetArray()`.
3449: This routine actually zeros out the a pointer.
3451: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3452: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3453: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3454: @*/
3455: PetscErrorCode VecRestoreArray2dRead(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
3456: {
3457: void *dummy;
3459: PetscFunctionBegin;
3463: dummy = (void *)(*a + mstart);
3464: PetscCall(PetscFree(dummy));
3465: PetscCall(VecRestoreArrayRead(x, NULL));
3466: PetscFunctionReturn(PETSC_SUCCESS);
3467: }
3469: /*@C
3470: VecGetArray1dRead - Returns a pointer to a 1d contiguous array that contains this
3471: processor's portion of the vector data. You MUST call `VecRestoreArray1dRead()`
3472: when you no longer need access to the array.
3474: Logically Collective
3476: Input Parameters:
3477: + x - the vector
3478: . m - first dimension of two dimensional array
3479: - mstart - first index you will use in first coordinate direction (often 0)
3481: Output Parameter:
3482: . a - location to put pointer to the array
3484: Level: developer
3486: Notes:
3487: For a vector obtained from `DMCreateLocalVector()` mstart are likely
3488: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3489: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`.
3491: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3493: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3494: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3495: `VecGetArray2d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3496: @*/
3497: PetscErrorCode VecGetArray1dRead(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
3498: {
3499: PetscInt N;
3501: PetscFunctionBegin;
3505: PetscCall(VecGetLocalSize(x, &N));
3506: PetscCheck(m == N, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local array size %" PetscInt_FMT " does not match 1d array dimensions %" PetscInt_FMT, N, m);
3507: PetscCall(VecGetArrayRead(x, (const PetscScalar **)a));
3508: *a -= mstart;
3509: PetscFunctionReturn(PETSC_SUCCESS);
3510: }
3512: /*@C
3513: VecRestoreArray1dRead - Restores a vector after `VecGetArray1dRead()` has been called.
3515: Logically Collective
3517: Input Parameters:
3518: + x - the vector
3519: . m - first dimension of two dimensional array
3520: . mstart - first index you will use in first coordinate direction (often 0)
3521: - a - location of pointer to array obtained from `VecGetArray1dRead()`
3523: Level: developer
3525: Notes:
3526: For regular PETSc vectors this routine does not involve any copies. For
3527: any special vectors that do not store local vector data in a contiguous
3528: array, this routine will copy the data back into the underlying
3529: vector data structure from the array obtained with `VecGetArray1dRead()`.
3531: This routine actually zeros out the a pointer.
3533: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3534: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3535: `VecGetArray1d()`, `VecRestoreArray2d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3536: @*/
3537: PetscErrorCode VecRestoreArray1dRead(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
3538: {
3539: PetscFunctionBegin;
3542: PetscCall(VecRestoreArrayRead(x, NULL));
3543: PetscFunctionReturn(PETSC_SUCCESS);
3544: }
3546: /*@C
3547: VecGetArray3dRead - Returns a pointer to a 3d contiguous array that contains this
3548: processor's portion of the vector data. You MUST call `VecRestoreArray3dRead()`
3549: when you no longer need access to the array.
3551: Logically Collective
3553: Input Parameters:
3554: + x - the vector
3555: . m - first dimension of three dimensional array
3556: . n - second dimension of three dimensional array
3557: . p - third dimension of three dimensional array
3558: . mstart - first index you will use in first coordinate direction (often 0)
3559: . nstart - first index in the second coordinate direction (often 0)
3560: - pstart - first index in the third coordinate direction (often 0)
3562: Output Parameter:
3563: . a - location to put pointer to the array
3565: Level: developer
3567: Notes:
3568: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3569: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3570: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3571: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3dRead()`.
3573: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3575: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3576: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3577: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3578: @*/
3579: PetscErrorCode VecGetArray3dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3580: {
3581: PetscInt i, N, j;
3582: const PetscScalar *aa;
3583: PetscScalar **b;
3585: PetscFunctionBegin;
3589: PetscCall(VecGetLocalSize(x, &N));
3590: PetscCheck(m * n * p == N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local array size %" PetscInt_FMT " does not match 3d array dimensions %" PetscInt_FMT " by %" PetscInt_FMT " by %" PetscInt_FMT, N, m, n, p);
3591: PetscCall(VecGetArrayRead(x, &aa));
3593: PetscCall(PetscMalloc(m * sizeof(PetscScalar **) + m * n * sizeof(PetscScalar *), a));
3594: b = (PetscScalar **)((*a) + m);
3595: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3596: for (i = 0; i < m; i++)
3597: for (j = 0; j < n; j++) b[i * n + j] = (PetscScalar *)aa + i * n * p + j * p - pstart;
3598: *a -= mstart;
3599: PetscFunctionReturn(PETSC_SUCCESS);
3600: }
3602: /*@C
3603: VecRestoreArray3dRead - Restores a vector after `VecGetArray3dRead()` has been called.
3605: Logically Collective
3607: Input Parameters:
3608: + x - the vector
3609: . m - first dimension of three dimensional array
3610: . n - second dimension of the three dimensional array
3611: . p - third dimension of the three dimensional array
3612: . mstart - first index you will use in first coordinate direction (often 0)
3613: . nstart - first index in the second coordinate direction (often 0)
3614: . pstart - first index in the third coordinate direction (often 0)
3615: - a - location of pointer to array obtained from `VecGetArray3dRead()`
3617: Level: developer
3619: Notes:
3620: For regular PETSc vectors this routine does not involve any copies. For
3621: any special vectors that do not store local vector data in a contiguous
3622: array, this routine will copy the data back into the underlying
3623: vector data structure from the array obtained with `VecGetArray()`.
3625: This routine actually zeros out the a pointer.
3627: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3628: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3629: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3630: @*/
3631: PetscErrorCode VecRestoreArray3dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3632: {
3633: void *dummy;
3635: PetscFunctionBegin;
3639: dummy = (void *)(*a + mstart);
3640: PetscCall(PetscFree(dummy));
3641: PetscCall(VecRestoreArrayRead(x, NULL));
3642: PetscFunctionReturn(PETSC_SUCCESS);
3643: }
3645: /*@C
3646: VecGetArray4dRead - Returns a pointer to a 4d contiguous array that contains this
3647: processor's portion of the vector data. You MUST call `VecRestoreArray4dRead()`
3648: when you no longer need access to the array.
3650: Logically Collective
3652: Input Parameters:
3653: + x - the vector
3654: . m - first dimension of four dimensional array
3655: . n - second dimension of four dimensional array
3656: . p - third dimension of four dimensional array
3657: . q - fourth dimension of four dimensional array
3658: . mstart - first index you will use in first coordinate direction (often 0)
3659: . nstart - first index in the second coordinate direction (often 0)
3660: . pstart - first index in the third coordinate direction (often 0)
3661: - qstart - first index in the fourth coordinate direction (often 0)
3663: Output Parameter:
3664: . a - location to put pointer to the array
3666: Level: beginner
3668: Notes:
3669: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3670: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3671: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3672: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
3674: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3676: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3677: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3678: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3679: @*/
3680: PetscErrorCode VecGetArray4dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3681: {
3682: PetscInt i, N, j, k;
3683: const PetscScalar *aa;
3684: PetscScalar ***b, **c;
3686: PetscFunctionBegin;
3690: PetscCall(VecGetLocalSize(x, &N));
3691: PetscCheck(m * n * p * q == N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local array size %" PetscInt_FMT " does not match 4d array dimensions %" PetscInt_FMT " by %" PetscInt_FMT " by %" PetscInt_FMT " by %" PetscInt_FMT, N, m, n, p, q);
3692: PetscCall(VecGetArrayRead(x, &aa));
3694: PetscCall(PetscMalloc(m * sizeof(PetscScalar ***) + m * n * sizeof(PetscScalar **) + m * n * p * sizeof(PetscScalar *), a));
3695: b = (PetscScalar ***)((*a) + m);
3696: c = (PetscScalar **)(b + m * n);
3697: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3698: for (i = 0; i < m; i++)
3699: for (j = 0; j < n; j++) b[i * n + j] = c + i * n * p + j * p - pstart;
3700: for (i = 0; i < m; i++)
3701: for (j = 0; j < n; j++)
3702: for (k = 0; k < p; k++) c[i * n * p + j * p + k] = (PetscScalar *)aa + i * n * p * q + j * p * q + k * q - qstart;
3703: *a -= mstart;
3704: PetscFunctionReturn(PETSC_SUCCESS);
3705: }
3707: /*@C
3708: VecRestoreArray4dRead - Restores a vector after `VecGetArray4d()` has been called.
3710: Logically Collective
3712: Input Parameters:
3713: + x - the vector
3714: . m - first dimension of four dimensional array
3715: . n - second dimension of the four dimensional array
3716: . p - third dimension of the four dimensional array
3717: . q - fourth dimension of the four dimensional array
3718: . mstart - first index you will use in first coordinate direction (often 0)
3719: . nstart - first index in the second coordinate direction (often 0)
3720: . pstart - first index in the third coordinate direction (often 0)
3721: . qstart - first index in the fourth coordinate direction (often 0)
3722: - a - location of pointer to array obtained from `VecGetArray4dRead()`
3724: Level: beginner
3726: Notes:
3727: For regular PETSc vectors this routine does not involve any copies. For
3728: any special vectors that do not store local vector data in a contiguous
3729: array, this routine will copy the data back into the underlying
3730: vector data structure from the array obtained with `VecGetArray()`.
3732: This routine actually zeros out the a pointer.
3734: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3735: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3736: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3737: @*/
3738: PetscErrorCode VecRestoreArray4dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3739: {
3740: void *dummy;
3742: PetscFunctionBegin;
3746: dummy = (void *)(*a + mstart);
3747: PetscCall(PetscFree(dummy));
3748: PetscCall(VecRestoreArrayRead(x, NULL));
3749: PetscFunctionReturn(PETSC_SUCCESS);
3750: }
3752: #if defined(PETSC_USE_DEBUG)
3754: /*@
3755: VecLockGet - Gets the current lock status of a vector
3757: Logically Collective
3759: Input Parameter:
3760: . x - the vector
3762: Output Parameter:
3763: . state - greater than zero indicates the vector is locked for read; less then zero indicates the vector is
3764: locked for write; equal to zero means the vector is unlocked, that is, it is free to read or write.
3766: Level: advanced
3768: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPush()`, `VecLockReadPop()`
3769: @*/
3770: PetscErrorCode VecLockGet(Vec x, PetscInt *state)
3771: {
3772: PetscFunctionBegin;
3774: *state = x->lock;
3775: PetscFunctionReturn(PETSC_SUCCESS);
3776: }
3778: PetscErrorCode VecLockGetLocation(Vec x, const char *file[], const char *func[], int *line)
3779: {
3780: PetscFunctionBegin;
3785: #if !PetscDefined(HAVE_THREADSAFETY)
3786: {
3787: const int index = x->lockstack.currentsize - 1;
3789: PetscCheck(index >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Corrupted vec lock stack, have negative index %d", index);
3790: *file = x->lockstack.file[index];
3791: *func = x->lockstack.function[index];
3792: *line = x->lockstack.line[index];
3793: }
3794: #else
3795: *file = NULL;
3796: *func = NULL;
3797: *line = 0;
3798: #endif
3799: PetscFunctionReturn(PETSC_SUCCESS);
3800: }
3802: /*@
3803: VecLockReadPush - Pushes a read-only lock on a vector to prevent it from being written to
3805: Logically Collective
3807: Input Parameter:
3808: . x - the vector
3810: Level: intermediate
3812: Notes:
3813: If this is set then calls to `VecGetArray()` or `VecSetValues()` or any other routines that change the vectors values will generate an error.
3815: The call can be nested, i.e., called multiple times on the same vector, but each `VecLockReadPush()` has to have one matching
3816: `VecLockReadPop()`, which removes the latest read-only lock.
3818: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPop()`, `VecLockGet()`
3819: @*/
3820: PetscErrorCode VecLockReadPush(Vec x)
3821: {
3822: PetscFunctionBegin;
3824: PetscCheck(x->lock++ >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Vector is already locked for exclusive write access but you want to read it");
3825: #if !PetscDefined(HAVE_THREADSAFETY)
3826: {
3827: const char *file, *func;
3828: int index, line;
3830: if ((index = petscstack.currentsize - 2) == -1) {
3831: // vec was locked "outside" of petsc, either in user-land or main. the error message will
3832: // now show this function as the culprit, but it will include the stacktrace
3833: file = "unknown user-file";
3834: func = "unknown_user_function";
3835: line = 0;
3836: } else {
3837: PetscCheck(index >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected petscstack, have negative index %d", index);
3838: file = petscstack.file[index];
3839: func = petscstack.function[index];
3840: line = petscstack.line[index];
3841: }
3842: PetscStackPush_Private(x->lockstack, file, func, line, petscstack.petscroutine[index], PETSC_FALSE);
3843: }
3844: #endif
3845: PetscFunctionReturn(PETSC_SUCCESS);
3846: }
3848: /*@
3849: VecLockReadPop - Pops a read-only lock from a vector
3851: Logically Collective
3853: Input Parameter:
3854: . x - the vector
3856: Level: intermediate
3858: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPush()`, `VecLockGet()`
3859: @*/
3860: PetscErrorCode VecLockReadPop(Vec x)
3861: {
3862: PetscFunctionBegin;
3864: PetscCheck(--x->lock >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Vector has been unlocked from read-only access too many times");
3865: #if !PetscDefined(HAVE_THREADSAFETY)
3866: {
3867: const char *previous = x->lockstack.function[x->lockstack.currentsize - 1];
3869: PetscStackPop_Private(x->lockstack, previous);
3870: }
3871: #endif
3872: PetscFunctionReturn(PETSC_SUCCESS);
3873: }
3875: /*@C
3876: VecLockWriteSet - Lock or unlock a vector for exclusive read/write access
3878: Logically Collective
3880: Input Parameters:
3881: + x - the vector
3882: - flg - `PETSC_TRUE` to lock the vector for exclusive read/write access; `PETSC_FALSE` to unlock it.
3884: Level: intermediate
3886: Notes:
3887: The function is useful in split-phase computations, which usually have a begin phase and an end phase.
3888: One can call `VecLockWriteSet`(x,`PETSC_TRUE`) in the begin phase to lock a vector for exclusive
3889: access, and call `VecLockWriteSet`(x,`PETSC_FALSE`) in the end phase to unlock the vector from exclusive
3890: access. In this way, one is ensured no other operations can access the vector in between. The code may like
3892: .vb
3893: VecGetArray(x,&xdata); // begin phase
3894: VecLockWriteSet(v,PETSC_TRUE);
3896: Other operations, which can not access x anymore (they can access xdata, of course)
3898: VecRestoreArray(x,&vdata); // end phase
3899: VecLockWriteSet(v,PETSC_FALSE);
3900: .ve
3902: The call can not be nested on the same vector, in other words, one can not call `VecLockWriteSet`(x,`PETSC_TRUE`)
3903: again before calling `VecLockWriteSet`(v,`PETSC_FALSE`).
3905: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPush()`, `VecLockReadPop()`, `VecLockGet()`
3906: @*/
3907: PetscErrorCode VecLockWriteSet(Vec x, PetscBool flg)
3908: {
3909: PetscFunctionBegin;
3911: if (flg) {
3912: PetscCheck(x->lock <= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Vector is already locked for read-only access but you want to write it");
3913: PetscCheck(x->lock >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Vector is already locked for exclusive write access but you want to write it");
3914: x->lock = -1;
3915: } else {
3916: PetscCheck(x->lock == -1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Vector is not locked for exclusive write access but you want to unlock it from that");
3917: x->lock = 0;
3918: }
3919: PetscFunctionReturn(PETSC_SUCCESS);
3920: }
3922: /*@
3923: VecLockPush - Pushes a read-only lock on a vector to prevent it from being written to
3925: Level: deprecated
3927: .seealso: [](chapter_vectors), `Vec`, `VecLockReadPush()`
3928: @*/
3929: PetscErrorCode VecLockPush(Vec x)
3930: {
3931: PetscFunctionBegin;
3932: PetscCall(VecLockReadPush(x));
3933: PetscFunctionReturn(PETSC_SUCCESS);
3934: }
3936: /*@
3937: VecLockPop - Pops a read-only lock from a vector
3939: Level: deprecated
3941: .seealso: [](chapter_vectors), `Vec`, `VecLockReadPop()`
3942: @*/
3943: PetscErrorCode VecLockPop(Vec x)
3944: {
3945: PetscFunctionBegin;
3946: PetscCall(VecLockReadPop(x));
3947: PetscFunctionReturn(PETSC_SUCCESS);
3948: }
3950: #endif