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, y - the vectors
46: Output Parameter:
47: . max - the result
49: Level: advanced
51: Notes:
52: `x` and `y` may be the same vector
54: if a particular `y[i]` is zero, it is treated as 1 in the above formula
56: .seealso: [](chapter_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMax()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`
57: @*/
58: PetscErrorCode VecMaxPointwiseDivide(Vec x, Vec y, PetscReal *max)
59: {
60: PetscFunctionBegin;
66: PetscCheckSameTypeAndComm(x, 1, y, 2);
67: VecCheckSameSize(x, 1, y, 2);
68: VecCheckAssembled(x);
69: VecCheckAssembled(y);
70: PetscCall(VecLockReadPush(x));
71: PetscCall(VecLockReadPush(y));
72: PetscUseTypeMethod(x, maxpointwisedivide, y, max);
73: PetscCall(VecLockReadPop(x));
74: PetscCall(VecLockReadPop(y));
75: PetscFunctionReturn(PETSC_SUCCESS);
76: }
78: /*@
79: VecDot - Computes the vector dot product.
81: Collective
83: Input Parameters:
84: . x, y - the vectors
86: Output Parameter:
87: . val - the dot product
89: Performance Issues:
90: .vb
91: per-processor memory bandwidth
92: interprocessor latency
93: work load imbalance that causes certain processes to arrive much earlier than others
94: .ve
96: Level: intermediate
98: Notes for Users of Complex Numbers:
99: For complex vectors, `VecDot()` computes
100: $ val = (x,y) = y^H x,
101: where y^H denotes the conjugate transpose of y. Note that this corresponds to the usual "mathematicians" complex
102: inner product where the SECOND argument gets the complex conjugate. Since the `BLASdot()` complex conjugates the first
103: first argument we call the `BLASdot()` with the arguments reversed.
105: Use `VecTDot()` for the indefinite form
106: $ val = (x,y) = y^T x,
107: where y^T denotes the transpose of y.
109: .seealso: [](chapter_vectors), `Vec`, `VecMDot()`, `VecTDot()`, `VecNorm()`, `VecDotBegin()`, `VecDotEnd()`, `VecDotRealPart()`
110: @*/
111: PetscErrorCode VecDot(Vec x, Vec y, PetscScalar *val)
112: {
113: PetscFunctionBegin;
119: PetscCheckSameTypeAndComm(x, 1, y, 2);
120: VecCheckSameSize(x, 1, y, 2);
121: VecCheckAssembled(x);
122: VecCheckAssembled(y);
124: PetscCall(VecLockReadPush(x));
125: PetscCall(VecLockReadPush(y));
126: PetscCall(PetscLogEventBegin(VEC_Dot, x, y, 0, 0));
127: PetscUseTypeMethod(x, dot, y, val);
128: PetscCall(PetscLogEventEnd(VEC_Dot, x, y, 0, 0));
129: PetscCall(VecLockReadPop(x));
130: PetscCall(VecLockReadPop(y));
131: PetscFunctionReturn(PETSC_SUCCESS);
132: }
134: /*@
135: VecDotRealPart - Computes the real part of the vector dot product.
137: Collective
139: Input Parameters:
140: . x, y - the vectors
142: Output Parameter:
143: . val - the real part of the dot product;
145: Level: intermediate
147: Performance Issues:
148: .vb
149: per-processor memory bandwidth
150: interprocessor latency
151: work load imbalance that causes certain processes to arrive much earlier than others
152: .ve
154: Notes for Users of Complex Numbers:
155: See `VecDot()` for more details on the definition of the dot product for complex numbers
157: For real numbers this returns the same value as `VecDot()`
159: 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
160: the space R^{2n} (that is a vector of 2n components with the real or imaginary part of the complex numbers for components)
162: Developer Note:
163: This is not currently optimized to compute only the real part of the dot product.
165: .seealso: [](chapter_vectors), `Vec`, `VecMDot()`, `VecTDot()`, `VecNorm()`, `VecDotBegin()`, `VecDotEnd()`, `VecDot()`, `VecDotNorm2()`
166: @*/
167: PetscErrorCode VecDotRealPart(Vec x, Vec y, PetscReal *val)
168: {
169: PetscScalar fdot;
171: PetscFunctionBegin;
172: PetscCall(VecDot(x, y, &fdot));
173: *val = PetscRealPart(fdot);
174: PetscFunctionReturn(PETSC_SUCCESS);
175: }
177: /*@
178: VecNorm - Computes the vector norm.
180: Collective
182: Input Parameters:
183: + x - the vector
184: - type - the type of the norm requested
186: Output Parameter:
187: . val - the norm
189: Values of NormType:
190: + `NORM_1` - sum_i |x[i]|
191: . `NORM_2` - sqrt(sum_i |x[i]|^2)
192: . `NORM_INFINITY` - max_i |x[i]|
193: - `NORM_1_AND_2` - computes efficiently both `NORM_1` and `NORM_2` and stores them each in an output array
195: Level: intermediate
197: Notes:
198: For complex numbers `NORM_1` will return the traditional 1 norm of the 2 norm of the complex numbers; that is the 1
199: norm of the absolute values of the complex entries. In PETSc 3.6 and earlier releases it returned the 1 norm of
200: the 1 norm of the complex entries (what is returned by the BLAS routine asum()). Both are valid norms but most
201: people expect the former.
203: This routine stashes the computed norm value, repeated calls before the vector entries are changed are then rapid since the
204: precomputed value is immediately available. Certain vector operations such as `VecSet()` store the norms so the value is
205: immediately available and does not need to be explicitly computed. `VecScale()` updates any stashed norm values, thus calls after `VecScale()`
206: do not need to explicitly recompute the norm.
208: Performance Issues:
209: + per-processor memory bandwidth - limits the speed of the computation of local portion of the norm
210: . interprocessor latency - limits the accumulation of the result across ranks, .i.e. MPI_Allreduce() time
211: . number of ranks - the time for the result will grow with the log base 2 of the number of ranks sharing the vector
212: - work load imbalance - the rank with the largest number of vector entries will limit the speed up
214: .seealso: [](chapter_vectors), `Vec`, `NormType`, `VecDot()`, `VecTDot()`, `VecDotBegin()`, `VecDotEnd()`, `VecNormAvailable()`,
215: `VecNormBegin()`, `VecNormEnd()`, `NormType()`
216: @*/
217: PetscErrorCode VecNorm(Vec x, NormType type, PetscReal *val)
218: {
219: PetscBool flg = PETSC_TRUE;
221: PetscFunctionBegin;
224: VecCheckAssembled(x);
228: /* Cached data? */
229: PetscCall(VecNormAvailable(x, type, &flg, val));
230: if (flg) PetscFunctionReturn(PETSC_SUCCESS);
232: PetscCall(VecLockReadPush(x));
233: PetscCall(PetscLogEventBegin(VEC_Norm, x, 0, 0, 0));
234: PetscUseTypeMethod(x, norm, type, val);
235: PetscCall(PetscLogEventEnd(VEC_Norm, x, 0, 0, 0));
236: PetscCall(VecLockReadPop(x));
238: if (type != NORM_1_AND_2) PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[type], *val));
239: PetscFunctionReturn(PETSC_SUCCESS);
240: }
242: /*@
243: VecNormAvailable - Returns the vector norm if it is already known. That is, it has been previously computed and cached in the vector
245: Not Collective
247: Input Parameters:
248: + x - the vector
249: - 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
250: `NORM_1_AND_2`, which computes both norms and stores them
251: in a two element array.
253: Output Parameters:
254: + available - `PETSC_TRUE` if the val returned is valid
255: - val - the norm
257: Level: intermediate
259: Performance Issues:
260: .vb
261: per-processor memory bandwidth
262: interprocessor latency
263: work load imbalance that causes certain processes to arrive much earlier than others
264: .ve
266: Developer Note:
267: `PETSC_HAVE_SLOW_BLAS_NORM2` will cause a C (loop unrolled) version of the norm to be used, rather
268: than the BLAS. This should probably only be used when one is using the FORTRAN BLAS routines
269: (as opposed to vendor provided) because the FORTRAN BLAS `NRM2()` routine is very slow.
271: .seealso: [](chapter_vectors), `Vec`, `VecDot()`, `VecTDot()`, `VecNorm()`, `VecDotBegin()`, `VecDotEnd()`,
272: `VecNormBegin()`, `VecNormEnd()`
273: @*/
274: PetscErrorCode VecNormAvailable(Vec x, NormType type, PetscBool *available, PetscReal *val)
275: {
276: PetscFunctionBegin;
282: if (type == NORM_1_AND_2) {
283: *available = PETSC_FALSE;
284: } else {
285: PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[type], *val, *available));
286: }
287: PetscFunctionReturn(PETSC_SUCCESS);
288: }
290: /*@
291: VecNormalize - Normalizes a vector by its 2-norm.
293: Collective
295: Input Parameter:
296: . x - the vector
298: Output Parameter:
299: . val - the vector norm before normalization. May be `NULL` if the value is not needed.
301: Level: intermediate
303: .seealso: [](chapter_vectors), `Vec`, `VecNorm()`, `NORM_2`, `NormType`
304: @*/
305: PetscErrorCode VecNormalize(Vec x, PetscReal *val)
306: {
307: PetscReal norm;
309: PetscFunctionBegin;
312: PetscCall(VecSetErrorIfLocked(x, 1));
314: PetscCall(PetscLogEventBegin(VEC_Normalize, x, 0, 0, 0));
315: PetscCall(VecNorm(x, NORM_2, &norm));
316: if (norm == 0.0) {
317: PetscCall(PetscInfo(x, "Vector of zero norm can not be normalized; Returning only the zero norm\n"));
318: } else if (norm != 1.0) {
319: PetscCall(VecScale(x, 1.0 / norm));
320: }
321: PetscCall(PetscLogEventEnd(VEC_Normalize, x, 0, 0, 0));
322: if (val) *val = norm;
323: PetscFunctionReturn(PETSC_SUCCESS);
324: }
326: /*@C
327: VecMax - Determines the vector component with maximum real part and its location.
329: Collective
331: Input Parameter:
332: . x - the vector
334: Output Parameters:
335: + p - the index of `val` (pass `NULL` if you don't want this) in the vector
336: - val - the maximum component
338: Level: intermediate
340: Notes:
341: Returns the value `PETSC_MIN_REAL` and negative `p` if the vector is of length 0.
343: Returns the smallest index with the maximum value
345: .seealso: [](chapter_vectors), `Vec`, `VecNorm()`, `VecMin()`
346: @*/
347: PetscErrorCode VecMax(Vec x, PetscInt *p, PetscReal *val)
348: {
349: PetscFunctionBegin;
352: VecCheckAssembled(x);
355: PetscCall(VecLockReadPush(x));
356: PetscCall(PetscLogEventBegin(VEC_Max, x, 0, 0, 0));
357: PetscUseTypeMethod(x, max, p, val);
358: PetscCall(PetscLogEventEnd(VEC_Max, x, 0, 0, 0));
359: PetscCall(VecLockReadPop(x));
360: PetscFunctionReturn(PETSC_SUCCESS);
361: }
363: /*@C
364: VecMin - Determines the vector component with minimum real part and its location.
366: Collective
368: Input Parameter:
369: . x - the vector
371: Output Parameters:
372: + p - the index of `val` (pass `NULL` if you don't want this location) in the vector
373: - val - the minimum component
375: Level: intermediate
377: Notes:
378: Returns the value `PETSC_MAX_REAL` and negative `p` if the vector is of length 0.
380: This returns the smallest index with the minimum value
382: .seealso: [](chapter_vectors), `Vec`, `VecMax()`
383: @*/
384: PetscErrorCode VecMin(Vec x, PetscInt *p, PetscReal *val)
385: {
386: PetscFunctionBegin;
389: VecCheckAssembled(x);
392: PetscCall(VecLockReadPush(x));
393: PetscCall(PetscLogEventBegin(VEC_Min, x, 0, 0, 0));
394: PetscUseTypeMethod(x, min, p, val);
395: PetscCall(PetscLogEventEnd(VEC_Min, x, 0, 0, 0));
396: PetscCall(VecLockReadPop(x));
397: PetscFunctionReturn(PETSC_SUCCESS);
398: }
400: /*@
401: VecTDot - Computes an indefinite vector dot product. That is, this
402: routine does NOT use the complex conjugate.
404: Collective
406: Input Parameters:
407: . x, y - the vectors
409: Output Parameter:
410: . val - the dot product
412: Level: intermediate
414: Notes for Users of Complex Numbers:
415: For complex vectors, VecTDot() computes the indefinite form
416: $ val = (x,y) = y^T x,
417: where y^T denotes the transpose of y.
419: Use VecDot() for the inner product
420: $ val = (x,y) = y^H x,
421: where y^H denotes the conjugate transpose of y.
423: .seealso: [](chapter_vectors), `Vec`, `VecDot()`, `VecMTDot()`
424: @*/
425: PetscErrorCode VecTDot(Vec x, Vec y, PetscScalar *val)
426: {
427: PetscFunctionBegin;
433: PetscCheckSameTypeAndComm(x, 1, y, 2);
434: VecCheckSameSize(x, 1, y, 2);
435: VecCheckAssembled(x);
436: VecCheckAssembled(y);
438: PetscCall(VecLockReadPush(x));
439: PetscCall(VecLockReadPush(y));
440: PetscCall(PetscLogEventBegin(VEC_TDot, x, y, 0, 0));
441: PetscUseTypeMethod(x, tdot, y, val);
442: PetscCall(PetscLogEventEnd(VEC_TDot, x, y, 0, 0));
443: PetscCall(VecLockReadPop(x));
444: PetscCall(VecLockReadPop(y));
445: PetscFunctionReturn(PETSC_SUCCESS);
446: }
448: /*@
449: VecScale - Scales a vector.
451: Not collective
453: Input Parameters:
454: + x - the vector
455: - alpha - the scalar
457: Level: intermediate
459: Note:
460: For a vector with n components, `VecScale()` computes x[i] = alpha * x[i], for i=1,...,n.
462: .seealso: [](chapter_vectors), `Vec`, `VecSet()`
463: @*/
464: PetscErrorCode VecScale(Vec x, PetscScalar alpha)
465: {
466: PetscReal norms[4];
467: PetscBool flgs[4];
469: PetscFunctionBegin;
472: VecCheckAssembled(x);
473: PetscCall(VecSetErrorIfLocked(x, 1));
474: if (alpha == (PetscScalar)1.0) PetscFunctionReturn(PETSC_SUCCESS);
476: /* get current stashed norms */
477: for (PetscInt i = 0; i < 4; i++) PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], norms[i], flgs[i]));
479: PetscCall(PetscLogEventBegin(VEC_Scale, x, 0, 0, 0));
480: PetscUseTypeMethod(x, scale, alpha);
481: PetscCall(PetscLogEventEnd(VEC_Scale, x, 0, 0, 0));
483: PetscCall(PetscObjectStateIncrease((PetscObject)x));
484: /* put the scaled stashed norms back into the Vec */
485: for (PetscInt i = 0; i < 4; i++) {
486: if (flgs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[i], PetscAbsScalar(alpha) * norms[i]));
487: }
488: PetscFunctionReturn(PETSC_SUCCESS);
489: }
491: /*@
492: VecSet - Sets all components of a vector to a single scalar value.
494: Logically Collective
496: Input Parameters:
497: + x - the vector
498: - alpha - the scalar
500: Level: beginner
502: Notes:
503: For a vector of dimension n, `VecSet()` sets x[i] = alpha, for i=1,...,n,
504: so that all vector entries then equal the identical
505: scalar value, `alpha`. Use the more general routine
506: `VecSetValues()` to set different vector entries.
508: You CANNOT call this after you have called `VecSetValues()` but before you call
509: `VecAssemblyBegin()`
511: .seealso: [](chapter_vectors), `Vec`, `VecSetValues()`, `VecSetValuesBlocked()`, `VecSetRandom()`
512: @*/
513: PetscErrorCode VecSet(Vec x, PetscScalar alpha)
514: {
515: PetscFunctionBegin;
518: VecCheckAssembled(x);
520: PetscCall(VecSetErrorIfLocked(x, 1));
522: PetscCall(PetscLogEventBegin(VEC_Set, x, 0, 0, 0));
523: PetscUseTypeMethod(x, set, alpha);
524: PetscCall(PetscLogEventEnd(VEC_Set, x, 0, 0, 0));
525: PetscCall(PetscObjectStateIncrease((PetscObject)x));
527: /* norms can be simply set (if |alpha|*N not too large) */
529: {
530: PetscReal val = PetscAbsScalar(alpha);
531: const PetscInt N = x->map->N;
533: if (N == 0) {
534: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_1], 0.0l));
535: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_INFINITY], 0.0));
536: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_2], 0.0));
537: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_FROBENIUS], 0.0));
538: } else if (val > PETSC_MAX_REAL / N) {
539: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_INFINITY], val));
540: } else {
541: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_1], N * val));
542: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_INFINITY], val));
543: val *= PetscSqrtReal((PetscReal)N);
544: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_2], val));
545: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_FROBENIUS], val));
546: }
547: }
548: PetscFunctionReturn(PETSC_SUCCESS);
549: }
551: /*@
552: VecAXPY - Computes `y = alpha x + y`.
554: Logically Collective
556: Input Parameters:
557: + alpha - the scalar
558: - x, y - the vectors
560: Output Parameter:
561: . y - output vector
563: Level: intermediate
565: Notes:
566: This routine is optimized for alpha of 0.0, otherwise it calls the BLAS routine
567: .vb
568: VecAXPY(y,alpha,x) y = alpha x + y
569: VecAYPX(y,beta,x) y = x + beta y
570: VecAXPBY(y,alpha,beta,x) y = alpha x + beta y
571: VecWAXPY(w,alpha,x,y) w = alpha x + y
572: VecAXPBYPCZ(w,alpha,beta,gamma,x,y) z = alpha x + beta y + gamma z
573: VecMAXPY(y,nv,alpha[],x[]) y = sum alpha[i] x[i] + y
574: .ve
576: .seealso: [](chapter_vectors), `Vec`, `VecAYPX()`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPBYPCZ()`, `VecAXPBY()`
577: @*/
578: PetscErrorCode VecAXPY(Vec y, PetscScalar alpha, Vec x)
579: {
580: PetscFunctionBegin;
585: PetscCheckSameTypeAndComm(x, 3, y, 1);
586: VecCheckSameSize(x, 3, y, 1);
587: VecCheckAssembled(x);
588: VecCheckAssembled(y);
590: if (alpha == (PetscScalar)0.0) PetscFunctionReturn(PETSC_SUCCESS);
591: PetscCall(VecSetErrorIfLocked(y, 1));
592: if (x == y) {
593: PetscCall(VecScale(y, alpha + 1.0));
594: PetscFunctionReturn(PETSC_SUCCESS);
595: }
596: PetscCall(VecLockReadPush(x));
597: PetscCall(PetscLogEventBegin(VEC_AXPY, x, y, 0, 0));
598: PetscUseTypeMethod(y, axpy, alpha, x);
599: PetscCall(PetscLogEventEnd(VEC_AXPY, x, y, 0, 0));
600: PetscCall(VecLockReadPop(x));
601: PetscCall(PetscObjectStateIncrease((PetscObject)y));
602: PetscFunctionReturn(PETSC_SUCCESS);
603: }
605: /*@
606: VecAYPX - Computes `y = x + beta y`.
608: Logically Collective
610: Input Parameters:
611: + beta - the scalar
612: . x - the unscaled vector
613: - y - the vector to be scaled
615: Output Parameter:
616: . y - output vector
618: Level: intermediate
620: Developer Note:
621: The implementation is optimized for beta of -1.0, 0.0, and 1.0
623: .seealso: [](chapter_vectors), `Vec`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBYPCZ()`, `VecAXPBY()`
624: @*/
625: PetscErrorCode VecAYPX(Vec y, PetscScalar beta, Vec x)
626: {
627: PetscFunctionBegin;
632: PetscCheckSameTypeAndComm(x, 3, y, 1);
633: VecCheckSameSize(x, 1, y, 3);
634: VecCheckAssembled(x);
635: VecCheckAssembled(y);
637: PetscCall(VecSetErrorIfLocked(y, 1));
638: if (x == y) {
639: PetscCall(VecScale(y, beta + 1.0));
640: PetscFunctionReturn(PETSC_SUCCESS);
641: }
642: PetscCall(VecLockReadPush(x));
643: if (beta == (PetscScalar)0.0) {
644: PetscCall(VecCopy(x, y));
645: } else {
646: PetscCall(PetscLogEventBegin(VEC_AYPX, x, y, 0, 0));
647: PetscUseTypeMethod(y, aypx, beta, x);
648: PetscCall(PetscLogEventEnd(VEC_AYPX, x, y, 0, 0));
649: PetscCall(PetscObjectStateIncrease((PetscObject)y));
650: }
651: PetscCall(VecLockReadPop(x));
652: PetscFunctionReturn(PETSC_SUCCESS);
653: }
655: /*@
656: VecAXPBY - Computes `y = alpha x + beta y`.
658: Logically Collective
660: Input Parameters:
661: + alpha,beta - the scalars
662: . x - the first scaled vector
663: - y - the second scaled vector
665: Output Parameter:
666: . y - output vector
668: Level: intermediate
670: Developer Note:
671: The implementation is optimized for alpha and/or beta values of 0.0 and 1.0
673: .seealso: [](chapter_vectors), `Vec`, `VecAYPX()`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBYPCZ()`
674: @*/
675: PetscErrorCode VecAXPBY(Vec y, PetscScalar alpha, PetscScalar beta, Vec x)
676: {
677: PetscFunctionBegin;
682: PetscCheckSameTypeAndComm(x, 4, y, 1);
683: VecCheckSameSize(y, 1, x, 4);
684: VecCheckAssembled(x);
685: VecCheckAssembled(y);
688: if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)1.0) PetscFunctionReturn(PETSC_SUCCESS);
689: if (x == y) {
690: PetscCall(VecScale(y, alpha + beta));
691: PetscFunctionReturn(PETSC_SUCCESS);
692: }
694: PetscCall(VecSetErrorIfLocked(y, 1));
695: PetscCall(VecLockReadPush(x));
696: PetscCall(PetscLogEventBegin(VEC_AXPY, y, x, 0, 0));
697: PetscUseTypeMethod(y, axpby, alpha, beta, x);
698: PetscCall(PetscLogEventEnd(VEC_AXPY, y, x, 0, 0));
699: PetscCall(PetscObjectStateIncrease((PetscObject)y));
700: PetscCall(VecLockReadPop(x));
701: PetscFunctionReturn(PETSC_SUCCESS);
702: }
704: /*@
705: VecAXPBYPCZ - Computes `z = alpha x + beta y + gamma z`
707: Logically Collective
709: Input Parameters:
710: + alpha,beta, gamma - the scalars
711: - x, y, z - the vectors
713: Output Parameter:
714: . z - output vector
716: Level: intermediate
718: Note:
719: `x`, `y` and `z` must be different vectors
721: Developer Note:
722: The implementation is optimized for alpha of 1.0 and gamma of 1.0 or 0.0
724: .seealso: [](chapter_vectors), `Vec`, `VecAYPX()`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBY()`
725: @*/
726: PetscErrorCode VecAXPBYPCZ(Vec z, PetscScalar alpha, PetscScalar beta, PetscScalar gamma, Vec x, Vec y)
727: {
728: PetscFunctionBegin;
735: PetscCheckSameTypeAndComm(x, 5, y, 6);
736: PetscCheckSameTypeAndComm(x, 5, z, 1);
737: VecCheckSameSize(x, 1, y, 5);
738: VecCheckSameSize(x, 1, z, 6);
739: PetscCheck(x != y && x != z, PetscObjectComm((PetscObject)x), PETSC_ERR_ARG_IDN, "x, y, and z must be different vectors");
740: PetscCheck(y != z, PetscObjectComm((PetscObject)y), PETSC_ERR_ARG_IDN, "x, y, and z must be different vectors");
741: VecCheckAssembled(x);
742: VecCheckAssembled(y);
743: VecCheckAssembled(z);
747: if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)0.0 && gamma == (PetscScalar)1.0) PetscFunctionReturn(PETSC_SUCCESS);
749: PetscCall(VecSetErrorIfLocked(z, 1));
750: PetscCall(VecLockReadPush(x));
751: PetscCall(VecLockReadPush(y));
752: PetscCall(PetscLogEventBegin(VEC_AXPBYPCZ, x, y, z, 0));
753: PetscUseTypeMethod(z, axpbypcz, alpha, beta, gamma, x, y);
754: PetscCall(PetscLogEventEnd(VEC_AXPBYPCZ, x, y, z, 0));
755: PetscCall(PetscObjectStateIncrease((PetscObject)z));
756: PetscCall(VecLockReadPop(x));
757: PetscCall(VecLockReadPop(y));
758: PetscFunctionReturn(PETSC_SUCCESS);
759: }
761: /*@
762: VecWAXPY - Computes `w = alpha x + y`.
764: Logically Collective
766: Input Parameters:
767: + alpha - the scalar
768: - x, y - the vectors
770: Output Parameter:
771: . w - the result
773: Level: intermediate
775: Note:
776: `w` cannot be either `x` or `y`, but `x` and `y` can be the same
778: Developer Note:
779: The implementation is optimized for alpha of -1.0, 0.0, and 1.0
781: .seealso: [](chapter_vectors), `Vec`, `VecAXPY()`, `VecAYPX()`, `VecAXPBY()`, `VecMAXPY()`, `VecAXPBYPCZ()`
782: @*/
783: PetscErrorCode VecWAXPY(Vec w, PetscScalar alpha, Vec x, Vec y)
784: {
785: PetscFunctionBegin;
792: PetscCheckSameTypeAndComm(x, 3, y, 4);
793: PetscCheckSameTypeAndComm(y, 4, w, 1);
794: VecCheckSameSize(x, 3, y, 4);
795: VecCheckSameSize(x, 3, w, 1);
796: PetscCheck(w != y, PETSC_COMM_SELF, PETSC_ERR_SUP, "Result vector w cannot be same as input vector y, suggest VecAXPY()");
797: PetscCheck(w != x, PETSC_COMM_SELF, PETSC_ERR_SUP, "Result vector w cannot be same as input vector x, suggest VecAYPX()");
798: VecCheckAssembled(x);
799: VecCheckAssembled(y);
801: PetscCall(VecSetErrorIfLocked(w, 1));
803: PetscCall(VecLockReadPush(x));
804: PetscCall(VecLockReadPush(y));
805: if (alpha == (PetscScalar)0.0) {
806: PetscCall(VecCopy(y, w));
807: } else {
808: PetscCall(PetscLogEventBegin(VEC_WAXPY, x, y, w, 0));
809: PetscUseTypeMethod(w, waxpy, alpha, x, y);
810: PetscCall(PetscLogEventEnd(VEC_WAXPY, x, y, w, 0));
811: PetscCall(PetscObjectStateIncrease((PetscObject)w));
812: }
813: PetscCall(VecLockReadPop(x));
814: PetscCall(VecLockReadPop(y));
815: PetscFunctionReturn(PETSC_SUCCESS);
816: }
818: /*@C
819: VecSetValues - Inserts or adds values into certain locations of a vector.
821: Not Collective
823: Input Parameters:
824: + x - vector to insert in
825: . ni - number of elements to add
826: . ix - indices where to add
827: . y - array of values
828: - iora - either `INSERT_VALUES` to replace the current values or `ADD_VALUES` to add values to any existing entries
830: Level: beginner
832: Notes:
833: .vb
834: `VecSetValues()` sets x[ix[i]] = y[i], for i=0,...,ni-1.
835: .ve
837: Calls to `VecSetValues()` with the `INSERT_VALUES` and `ADD_VALUES`
838: options cannot be mixed without intervening calls to the assembly
839: routines.
841: These values may be cached, so `VecAssemblyBegin()` and `VecAssemblyEnd()`
842: MUST be called after all calls to `VecSetValues()` have been completed.
844: VecSetValues() uses 0-based indices in Fortran as well as in C.
846: If you call `VecSetOption`(x, `VEC_IGNORE_NEGATIVE_INDICES`,`PETSC_TRUE`),
847: negative indices may be passed in ix. These rows are
848: simply ignored. This allows easily inserting element load matrices
849: with homogeneous Dirchlet boundary conditions that you don't want represented
850: in the vector.
852: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValuesLocal()`,
853: `VecSetValue()`, `VecSetValuesBlocked()`, `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `VecGetValues()`
854: @*/
855: PetscErrorCode VecSetValues(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
856: {
857: PetscFunctionBeginHot;
859: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
864: PetscCall(PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0));
865: PetscUseTypeMethod(x, setvalues, ni, ix, y, iora);
866: PetscCall(PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0));
867: PetscCall(PetscObjectStateIncrease((PetscObject)x));
868: PetscFunctionReturn(PETSC_SUCCESS);
869: }
871: /*@C
872: VecGetValues - Gets values from certain locations of a vector. Currently
873: can only get values on the same processor on which they are owned
875: Not Collective
877: Input Parameters:
878: + x - vector to get values from
879: . ni - number of elements to get
880: - ix - indices where to get them from (in global 1d numbering)
882: Output Parameter:
883: . y - array of values
885: Level: beginner
887: Notes:
888: The user provides the allocated array y; it is NOT allocated in this routine
890: `VecGetValues()` gets y[i] = x[ix[i]], for i=0,...,ni-1.
892: `VecAssemblyBegin()` and `VecAssemblyEnd()` MUST be called before calling this if `VecSetValues()` or related routine has been called
894: VecGetValues() uses 0-based indices in Fortran as well as in C.
896: If you call `VecSetOption`(x, `VEC_IGNORE_NEGATIVE_INDICES`,`PETSC_TRUE`),
897: negative indices may be passed in ix. These rows are
898: simply ignored.
900: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`
901: @*/
902: PetscErrorCode VecGetValues(Vec x, PetscInt ni, const PetscInt ix[], PetscScalar y[])
903: {
904: PetscFunctionBegin;
906: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
910: VecCheckAssembled(x);
911: PetscUseTypeMethod(x, getvalues, ni, ix, y);
912: PetscFunctionReturn(PETSC_SUCCESS);
913: }
915: /*@C
916: VecSetValuesBlocked - Inserts or adds blocks of values into certain locations of a vector.
918: Not Collective
920: Input Parameters:
921: + x - vector to insert in
922: . ni - number of blocks to add
923: . ix - indices where to add in block count, rather than element count
924: . y - array of values
925: - iora - either `INSERT_VALUES` replaces existing entries with new values, `ADD_VALUES`, adds values to any existing entries
927: Level: intermediate
929: Notes:
930: `VecSetValuesBlocked()` sets x[bs*ix[i]+j] = y[bs*i+j],
931: for j=0,...,bs-1, for i=0,...,ni-1. where bs was set with VecSetBlockSize().
933: Calls to `VecSetValuesBlocked()` with the `INSERT_VALUES` and `ADD_VALUES`
934: options cannot be mixed without intervening calls to the assembly
935: routines.
937: These values may be cached, so `VecAssemblyBegin()` and `VecAssemblyEnd()`
938: MUST be called after all calls to `VecSetValuesBlocked()` have been completed.
940: `VecSetValuesBlocked()` uses 0-based indices in Fortran as well as in C.
942: Negative indices may be passed in ix, these rows are
943: simply ignored. This allows easily inserting element load matrices
944: with homogeneous Dirchlet boundary conditions that you don't want represented
945: in the vector.
947: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValuesBlockedLocal()`,
948: `VecSetValues()`
949: @*/
950: PetscErrorCode VecSetValuesBlocked(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
951: {
952: PetscFunctionBeginHot;
954: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
959: PetscCall(PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0));
960: PetscUseTypeMethod(x, setvaluesblocked, ni, ix, y, iora);
961: PetscCall(PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0));
962: PetscCall(PetscObjectStateIncrease((PetscObject)x));
963: PetscFunctionReturn(PETSC_SUCCESS);
964: }
966: /*@C
967: VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
968: using a local ordering of the nodes.
970: Not Collective
972: Input Parameters:
973: + x - vector to insert in
974: . ni - number of elements to add
975: . ix - indices where to add
976: . y - array of values
977: - iora - either `INSERT_VALUES` replaces existing entries with new values, `ADD_VALUES` adds values to any existing entries
979: Level: intermediate
981: Notes:
982: `VecSetValuesLocal()` sets x[ix[i]] = y[i], for i=0,...,ni-1.
984: Calls to `VecSetValues()` with the `INSERT_VALUES` and `ADD_VALUES`
985: options cannot be mixed without intervening calls to the assembly
986: routines.
988: These values may be cached, so `VecAssemblyBegin()` and `VecAssemblyEnd()`
989: MUST be called after all calls to `VecSetValuesLocal()` have been completed.
991: `VecSetValuesLocal()` uses 0-based indices in Fortran as well as in C.
993: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`, `VecSetLocalToGlobalMapping()`,
994: `VecSetValuesBlockedLocal()`
995: @*/
996: PetscErrorCode VecSetValuesLocal(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
997: {
998: PetscInt lixp[128], *lix = lixp;
1000: PetscFunctionBeginHot;
1002: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
1007: PetscCall(PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0));
1008: if (!x->ops->setvalueslocal) {
1009: if (x->map->mapping) {
1010: if (ni > 128) PetscCall(PetscMalloc1(ni, &lix));
1011: PetscCall(ISLocalToGlobalMappingApply(x->map->mapping, ni, (PetscInt *)ix, lix));
1012: PetscUseTypeMethod(x, setvalues, ni, lix, y, iora);
1013: if (ni > 128) PetscCall(PetscFree(lix));
1014: } else PetscUseTypeMethod(x, setvalues, ni, ix, y, iora);
1015: } else PetscUseTypeMethod(x, setvalueslocal, ni, ix, y, iora);
1016: PetscCall(PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0));
1017: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1018: PetscFunctionReturn(PETSC_SUCCESS);
1019: }
1021: /*@
1022: VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
1023: using a local ordering of the nodes.
1025: Not Collective
1027: Input Parameters:
1028: + x - vector to insert in
1029: . ni - number of blocks to add
1030: . ix - indices where to add in block count, not element count
1031: . y - array of values
1032: - iora - either `INSERT_VALUES` replaces existing entries with new values, `ADD_VALUES` adds values to any existing entries
1034: Level: intermediate
1036: Notes:
1037: `VecSetValuesBlockedLocal()` sets x[bs*ix[i]+j] = y[bs*i+j],
1038: for j=0,..bs-1, for i=0,...,ni-1, where bs has been set with `VecSetBlockSize()`.
1040: Calls to `VecSetValuesBlockedLocal()` with the `INSERT_VALUES` and `ADD_VALUES`
1041: options cannot be mixed without intervening calls to the assembly
1042: routines.
1044: These values may be cached, so `VecAssemblyBegin()` and `VecAssemblyEnd()`
1045: MUST be called after all calls to `VecSetValuesBlockedLocal()` have been completed.
1047: `VecSetValuesBlockedLocal()` uses 0-based indices in Fortran as well as in C.
1049: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`, `VecSetValuesBlocked()`,
1050: `VecSetLocalToGlobalMapping()`
1051: @*/
1052: PetscErrorCode VecSetValuesBlockedLocal(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
1053: {
1054: PetscInt lixp[128], *lix = lixp;
1056: PetscFunctionBeginHot;
1058: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
1062: PetscCall(PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0));
1063: if (x->map->mapping) {
1064: if (ni > 128) PetscCall(PetscMalloc1(ni, &lix));
1065: PetscCall(ISLocalToGlobalMappingApplyBlock(x->map->mapping, ni, (PetscInt *)ix, lix));
1066: PetscUseTypeMethod(x, setvaluesblocked, ni, lix, y, iora);
1067: if (ni > 128) PetscCall(PetscFree(lix));
1068: } else {
1069: PetscUseTypeMethod(x, setvaluesblocked, ni, ix, y, iora);
1070: }
1071: PetscCall(PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0));
1072: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1073: PetscFunctionReturn(PETSC_SUCCESS);
1074: }
1076: static PetscErrorCode VecMXDot_Private(Vec x, PetscInt nv, const Vec y[], PetscScalar result[], PetscErrorCode (*mxdot)(Vec, PetscInt, const Vec[], PetscScalar[]), PetscLogEvent event)
1077: {
1078: PetscFunctionBegin;
1081: VecCheckAssembled(x);
1083: if (!nv) PetscFunctionReturn(PETSC_SUCCESS);
1085: for (PetscInt i = 0; i < nv; ++i) {
1088: PetscCheckSameTypeAndComm(x, 1, y[i], 3);
1089: VecCheckSameSize(x, 1, y[i], 3);
1090: VecCheckAssembled(y[i]);
1091: PetscCall(VecLockReadPush(y[i]));
1092: }
1096: PetscCall(VecLockReadPush(x));
1097: PetscCall(PetscLogEventBegin(event, x, *y, 0, 0));
1098: PetscCall((*mxdot)(x, nv, y, result));
1099: PetscCall(PetscLogEventEnd(event, x, *y, 0, 0));
1100: PetscCall(VecLockReadPop(x));
1101: for (PetscInt i = 0; i < nv; ++i) PetscCall(VecLockReadPop(y[i]));
1102: PetscFunctionReturn(PETSC_SUCCESS);
1103: }
1105: /*@
1106: VecMTDot - Computes indefinite vector multiple dot products.
1107: That is, it does NOT use the complex conjugate.
1109: Collective
1111: Input Parameters:
1112: + x - one vector
1113: . nv - number of vectors
1114: - y - array of vectors. Note that vectors are pointers
1116: Output Parameter:
1117: . val - array of the dot products
1119: Level: intermediate
1121: Notes for Users of Complex Numbers:
1122: For complex vectors, `VecMTDot()` computes the indefinite form
1123: $ val = (x,y) = y^T x,
1124: where y^T denotes the transpose of y.
1126: Use `VecMDot()` for the inner product
1127: $ val = (x,y) = y^H x,
1128: where y^H denotes the conjugate transpose of y.
1130: .seealso: [](chapter_vectors), `Vec`, `VecMDot()`, `VecTDot()`
1131: @*/
1132: PetscErrorCode VecMTDot(Vec x, PetscInt nv, const Vec y[], PetscScalar val[])
1133: {
1134: PetscFunctionBegin;
1136: PetscCall(VecMXDot_Private(x, nv, y, val, x->ops->mtdot, VEC_MTDot));
1137: PetscFunctionReturn(PETSC_SUCCESS);
1138: }
1140: /*@
1141: VecMDot - Computes multiple vector dot products.
1143: Collective
1145: Input Parameters:
1146: + x - one vector
1147: . nv - number of vectors
1148: - y - array of vectors.
1150: Output Parameter:
1151: . val - array of the dot products (does not allocate the array)
1153: Level: intermediate
1155: Notes for Users of Complex Numbers:
1156: For complex vectors, `VecMDot()` computes
1157: $ val = (x,y) = y^H x,
1158: where y^H denotes the conjugate transpose of y.
1160: Use `VecMTDot()` for the indefinite form
1161: $ val = (x,y) = y^T x,
1162: where y^T denotes the transpose of y.
1164: .seealso: [](chapter_vectors), `Vec`, `VecMTDot()`, `VecDot()`
1165: @*/
1166: PetscErrorCode VecMDot(Vec x, PetscInt nv, const Vec y[], PetscScalar val[])
1167: {
1168: PetscFunctionBegin;
1170: PetscCall(VecMXDot_Private(x, nv, y, val, x->ops->mdot, VEC_MDot));
1171: PetscFunctionReturn(PETSC_SUCCESS);
1172: }
1174: /*@
1175: VecMAXPY - Computes `y = y + sum alpha[i] x[i]`
1177: Logically Collective
1179: Input Parameters:
1180: + nv - number of scalars and x-vectors
1181: . alpha - array of scalars
1182: . y - one vector
1183: - x - array of vectors
1185: Level: intermediate
1187: Note:
1188: `y` cannot be any of the `x` vectors
1190: .seealso: [](chapter_vectors), `Vec`, `VecAYPX()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBYPCZ()`, `VecAXPBY()`
1191: @*/
1192: PetscErrorCode VecMAXPY(Vec y, PetscInt nv, const PetscScalar alpha[], Vec x[])
1193: {
1194: PetscFunctionBegin;
1196: VecCheckAssembled(y);
1198: PetscCall(VecSetErrorIfLocked(y, 1));
1199: PetscCheck(nv >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of vectors (given %" PetscInt_FMT ") cannot be negative", nv);
1200: if (nv) {
1201: PetscInt zeros = 0;
1205: for (PetscInt i = 0; i < nv; ++i) {
1209: PetscCheckSameTypeAndComm(y, 1, x[i], 4);
1210: VecCheckSameSize(y, 1, x[i], 4);
1211: PetscCheck(y != x[i], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Array of vectors 'x' cannot contain y, found x[%" PetscInt_FMT "] == y", i);
1212: VecCheckAssembled(x[i]);
1213: PetscCall(VecLockReadPush(x[i]));
1214: zeros += alpha[i] == (PetscScalar)0.0;
1215: }
1217: if (zeros < nv) {
1218: PetscCall(PetscLogEventBegin(VEC_MAXPY, y, *x, 0, 0));
1219: PetscUseTypeMethod(y, maxpy, nv, alpha, x);
1220: PetscCall(PetscLogEventEnd(VEC_MAXPY, y, *x, 0, 0));
1221: PetscCall(PetscObjectStateIncrease((PetscObject)y));
1222: }
1224: for (PetscInt i = 0; i < nv; ++i) PetscCall(VecLockReadPop(x[i]));
1225: }
1226: PetscFunctionReturn(PETSC_SUCCESS);
1227: }
1229: /*@
1230: VecConcatenate - Creates a new vector that is a vertical concatenation of all the given array of vectors
1231: in the order they appear in the array. The concatenated vector resides on the same
1232: communicator and is the same type as the source vectors.
1234: Collective
1236: Input Parameters:
1237: + nx - number of vectors to be concatenated
1238: - X - array containing the vectors to be concatenated in the order of concatenation
1240: Output Parameters:
1241: + Y - concatenated vector
1242: - x_is - array of index sets corresponding to the concatenated components of `Y` (pass `NULL` if not needed)
1244: Level: advanced
1246: Notes:
1247: Concatenation is similar to the functionality of a `VECNEST` object; they both represent combination of
1248: different vector spaces. However, concatenated vectors do not store any information about their
1249: sub-vectors and own their own data. Consequently, this function provides index sets to enable the
1250: manipulation of data in the concatenated vector that corresponds to the original components at creation.
1252: This is a useful tool for outer loop algorithms, particularly constrained optimizers, where the solver
1253: has to operate on combined vector spaces and cannot utilize `VECNEST` objects due to incompatibility with
1254: bound projections.
1256: .seealso: [](chapter_vectors), `Vec`, `VECNEST`, `VECSCATTER`, `VecScatterCreate()`
1257: @*/
1258: PetscErrorCode VecConcatenate(PetscInt nx, const Vec X[], Vec *Y, IS *x_is[])
1259: {
1260: MPI_Comm comm;
1261: VecType vec_type;
1262: Vec Ytmp, Xtmp;
1263: IS *is_tmp;
1264: PetscInt i, shift = 0, Xnl, Xng, Xbegin;
1266: PetscFunctionBegin;
1272: if ((*X)->ops->concatenate) {
1273: /* use the dedicated concatenation function if available */
1274: PetscCall((*(*X)->ops->concatenate)(nx, X, Y, x_is));
1275: } else {
1276: /* loop over vectors and start creating IS */
1277: comm = PetscObjectComm((PetscObject)(*X));
1278: PetscCall(VecGetType(*X, &vec_type));
1279: PetscCall(PetscMalloc1(nx, &is_tmp));
1280: for (i = 0; i < nx; i++) {
1281: PetscCall(VecGetSize(X[i], &Xng));
1282: PetscCall(VecGetLocalSize(X[i], &Xnl));
1283: PetscCall(VecGetOwnershipRange(X[i], &Xbegin, NULL));
1284: PetscCall(ISCreateStride(comm, Xnl, shift + Xbegin, 1, &is_tmp[i]));
1285: shift += Xng;
1286: }
1287: /* create the concatenated vector */
1288: PetscCall(VecCreate(comm, &Ytmp));
1289: PetscCall(VecSetType(Ytmp, vec_type));
1290: PetscCall(VecSetSizes(Ytmp, PETSC_DECIDE, shift));
1291: PetscCall(VecSetUp(Ytmp));
1292: /* copy data from X array to Y and return */
1293: for (i = 0; i < nx; i++) {
1294: PetscCall(VecGetSubVector(Ytmp, is_tmp[i], &Xtmp));
1295: PetscCall(VecCopy(X[i], Xtmp));
1296: PetscCall(VecRestoreSubVector(Ytmp, is_tmp[i], &Xtmp));
1297: }
1298: *Y = Ytmp;
1299: if (x_is) {
1300: *x_is = is_tmp;
1301: } else {
1302: for (i = 0; i < nx; i++) PetscCall(ISDestroy(&is_tmp[i]));
1303: PetscCall(PetscFree(is_tmp));
1304: }
1305: }
1306: PetscFunctionReturn(PETSC_SUCCESS);
1307: }
1309: /* A helper function for VecGetSubVector to check if we can implement it with no-copy (i.e. the subvector shares
1310: memory with the original vector), and the block size of the subvector.
1312: Input Parameters:
1313: + X - the original vector
1314: - is - the index set of the subvector
1316: Output Parameters:
1317: + contig - PETSC_TRUE if the index set refers to contiguous entries on this process, else PETSC_FALSE
1318: . start - start of contiguous block, as an offset from the start of the ownership range of the original vector
1319: - blocksize - the block size of the subvector
1321: */
1322: PetscErrorCode VecGetSubVectorContiguityAndBS_Private(Vec X, IS is, PetscBool *contig, PetscInt *start, PetscInt *blocksize)
1323: {
1324: PetscInt gstart, gend, lstart;
1325: PetscBool red[2] = {PETSC_TRUE /*contiguous*/, PETSC_TRUE /*validVBS*/};
1326: PetscInt n, N, ibs, vbs, bs = -1;
1328: PetscFunctionBegin;
1329: PetscCall(ISGetLocalSize(is, &n));
1330: PetscCall(ISGetSize(is, &N));
1331: PetscCall(ISGetBlockSize(is, &ibs));
1332: PetscCall(VecGetBlockSize(X, &vbs));
1333: PetscCall(VecGetOwnershipRange(X, &gstart, &gend));
1334: PetscCall(ISContiguousLocal(is, gstart, gend, &lstart, &red[0]));
1335: /* block size is given by IS if ibs > 1; otherwise, check the vector */
1336: if (ibs > 1) {
1337: PetscCall(MPIU_Allreduce(MPI_IN_PLACE, red, 1, MPIU_BOOL, MPI_LAND, PetscObjectComm((PetscObject)is)));
1338: bs = ibs;
1339: } else {
1340: if (n % vbs || vbs == 1) red[1] = PETSC_FALSE; /* this process invalidate the collectiveness of block size */
1341: PetscCall(MPIU_Allreduce(MPI_IN_PLACE, red, 2, MPIU_BOOL, MPI_LAND, PetscObjectComm((PetscObject)is)));
1342: if (red[0] && red[1]) bs = vbs; /* all processes have a valid block size and the access will be contiguous */
1343: }
1345: *contig = red[0];
1346: *start = lstart;
1347: *blocksize = bs;
1348: PetscFunctionReturn(PETSC_SUCCESS);
1349: }
1351: /* A helper function for VecGetSubVector, to be used when we have to build a standalone subvector through VecScatter
1353: Input Parameters:
1354: + X - the original vector
1355: . is - the index set of the subvector
1356: - bs - the block size of the subvector, gotten from VecGetSubVectorContiguityAndBS_Private()
1358: Output Parameters:
1359: . Z - the subvector, which will compose the VecScatter context on output
1360: */
1361: PetscErrorCode VecGetSubVectorThroughVecScatter_Private(Vec X, IS is, PetscInt bs, Vec *Z)
1362: {
1363: PetscInt n, N;
1364: VecScatter vscat;
1365: Vec Y;
1367: PetscFunctionBegin;
1368: PetscCall(ISGetLocalSize(is, &n));
1369: PetscCall(ISGetSize(is, &N));
1370: PetscCall(VecCreate(PetscObjectComm((PetscObject)is), &Y));
1371: PetscCall(VecSetSizes(Y, n, N));
1372: PetscCall(VecSetBlockSize(Y, bs));
1373: PetscCall(VecSetType(Y, ((PetscObject)X)->type_name));
1374: PetscCall(VecScatterCreate(X, is, Y, NULL, &vscat));
1375: PetscCall(VecScatterBegin(vscat, X, Y, INSERT_VALUES, SCATTER_FORWARD));
1376: PetscCall(VecScatterEnd(vscat, X, Y, INSERT_VALUES, SCATTER_FORWARD));
1377: PetscCall(PetscObjectCompose((PetscObject)Y, "VecGetSubVector_Scatter", (PetscObject)vscat));
1378: PetscCall(VecScatterDestroy(&vscat));
1379: *Z = Y;
1380: PetscFunctionReturn(PETSC_SUCCESS);
1381: }
1383: /*@
1384: VecGetSubVector - Gets a vector representing part of another vector
1386: Collective
1388: Input Parameters:
1389: + X - vector from which to extract a subvector
1390: - is - index set representing portion of `X` to extract
1392: Output Parameter:
1393: . Y - subvector corresponding to `is`
1395: Level: advanced
1397: Notes:
1398: The subvector `Y` should be returned with `VecRestoreSubVector()`.
1399: `X` and must be defined on the same communicator
1401: This function may return a subvector without making a copy, therefore it is not safe to use the original vector while
1402: modifying the subvector. Other non-overlapping subvectors can still be obtained from X using this function.
1404: 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`.
1406: .seealso: [](chapter_vectors), `Vec`, `IS`, `VECNEST`, `MatCreateSubMatrix()`
1407: @*/
1408: PetscErrorCode VecGetSubVector(Vec X, IS is, Vec *Y)
1409: {
1410: Vec Z;
1412: PetscFunctionBegin;
1415: PetscCheckSameComm(X, 1, is, 2);
1417: if (X->ops->getsubvector) {
1418: PetscUseTypeMethod(X, getsubvector, is, &Z);
1419: } else { /* Default implementation currently does no caching */
1420: PetscBool contig;
1421: PetscInt n, N, start, bs;
1423: PetscCall(ISGetLocalSize(is, &n));
1424: PetscCall(ISGetSize(is, &N));
1425: PetscCall(VecGetSubVectorContiguityAndBS_Private(X, is, &contig, &start, &bs));
1426: if (contig) { /* We can do a no-copy implementation */
1427: const PetscScalar *x;
1428: PetscInt state = 0;
1429: PetscBool isstd, iscuda, iship;
1431: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &isstd, VECSEQ, VECMPI, VECSTANDARD, ""));
1432: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &iscuda, VECSEQCUDA, VECMPICUDA, ""));
1433: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &iship, VECSEQHIP, VECMPIHIP, ""));
1434: if (iscuda) {
1435: #if defined(PETSC_HAVE_CUDA)
1436: const PetscScalar *x_d;
1437: PetscMPIInt size;
1438: PetscOffloadMask flg;
1440: PetscCall(VecCUDAGetArrays_Private(X, &x, &x_d, &flg));
1441: PetscCheck(flg != PETSC_OFFLOAD_UNALLOCATED, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not for PETSC_OFFLOAD_UNALLOCATED");
1442: PetscCheck(!n || x || x_d, PETSC_COMM_SELF, PETSC_ERR_SUP, "Missing vector data");
1443: if (x) x += start;
1444: if (x_d) x_d += start;
1445: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)X), &size));
1446: if (size == 1) {
1447: PetscCall(VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)X), bs, n, x, x_d, &Z));
1448: } else {
1449: PetscCall(VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)X), bs, n, N, x, x_d, &Z));
1450: }
1451: Z->offloadmask = flg;
1452: #endif
1453: } else if (iship) {
1454: #if defined(PETSC_HAVE_HIP)
1455: const PetscScalar *x_d;
1456: PetscMPIInt size;
1457: PetscOffloadMask flg;
1459: PetscCall(VecHIPGetArrays_Private(X, &x, &x_d, &flg));
1460: PetscCheck(flg != PETSC_OFFLOAD_UNALLOCATED, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not for PETSC_OFFLOAD_UNALLOCATED");
1461: PetscCheck(!n || x || x_d, PETSC_COMM_SELF, PETSC_ERR_SUP, "Missing vector data");
1462: if (x) x += start;
1463: if (x_d) x_d += start;
1464: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)X), &size));
1465: if (size == 1) {
1466: PetscCall(VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)X), bs, n, x, x_d, &Z));
1467: } else {
1468: PetscCall(VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)X), bs, n, N, x, x_d, &Z));
1469: }
1470: Z->offloadmask = flg;
1471: #endif
1472: } else if (isstd) {
1473: PetscMPIInt size;
1475: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)X), &size));
1476: PetscCall(VecGetArrayRead(X, &x));
1477: if (x) x += start;
1478: if (size == 1) {
1479: PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)X), bs, n, x, &Z));
1480: } else {
1481: PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)X), bs, n, N, x, &Z));
1482: }
1483: PetscCall(VecRestoreArrayRead(X, &x));
1484: } else { /* default implementation: use place array */
1485: PetscCall(VecGetArrayRead(X, &x));
1486: PetscCall(VecCreate(PetscObjectComm((PetscObject)X), &Z));
1487: PetscCall(VecSetType(Z, ((PetscObject)X)->type_name));
1488: PetscCall(VecSetSizes(Z, n, N));
1489: PetscCall(VecSetBlockSize(Z, bs));
1490: PetscCall(VecPlaceArray(Z, x ? x + start : NULL));
1491: PetscCall(VecRestoreArrayRead(X, &x));
1492: }
1494: /* this is relevant only in debug mode */
1495: PetscCall(VecLockGet(X, &state));
1496: if (state) PetscCall(VecLockReadPush(Z));
1497: Z->ops->placearray = NULL;
1498: Z->ops->replacearray = NULL;
1499: } else { /* Have to create a scatter and do a copy */
1500: PetscCall(VecGetSubVectorThroughVecScatter_Private(X, is, bs, &Z));
1501: }
1502: }
1503: /* Record the state when the subvector was gotten so we know whether its values need to be put back */
1504: if (VecGetSubVectorSavedStateId < 0) PetscCall(PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId));
1505: PetscCall(PetscObjectComposedDataSetInt((PetscObject)Z, VecGetSubVectorSavedStateId, 1));
1506: *Y = Z;
1507: PetscFunctionReturn(PETSC_SUCCESS);
1508: }
1510: /*@
1511: VecRestoreSubVector - Restores a subvector extracted using `VecGetSubVector()`
1513: Collective
1515: Input Parameters:
1516: + X - vector from which subvector was obtained
1517: . is - index set representing the subset of `X`
1518: - Y - subvector being restored
1520: Level: advanced
1522: .seealso: [](chapter_vectors), `Vec`, `IS`, `VecGetSubVector()`
1523: @*/
1524: PetscErrorCode VecRestoreSubVector(Vec X, IS is, Vec *Y)
1525: {
1526: PETSC_UNUSED PetscObjectState dummystate = 0;
1527: PetscBool unchanged;
1529: PetscFunctionBegin;
1532: PetscCheckSameComm(X, 1, is, 2);
1536: if (X->ops->restoresubvector) PetscUseTypeMethod(X, restoresubvector, is, Y);
1537: else {
1538: PetscCall(PetscObjectComposedDataGetInt((PetscObject)*Y, VecGetSubVectorSavedStateId, dummystate, unchanged));
1539: if (!unchanged) { /* If Y's state has not changed since VecGetSubVector(), we only need to destroy Y */
1540: VecScatter scatter;
1541: PetscInt state;
1543: PetscCall(VecLockGet(X, &state));
1544: PetscCheck(state == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Vec X is locked for read-only or read/write access");
1546: PetscCall(PetscObjectQuery((PetscObject)*Y, "VecGetSubVector_Scatter", (PetscObject *)&scatter));
1547: if (scatter) {
1548: PetscCall(VecScatterBegin(scatter, *Y, X, INSERT_VALUES, SCATTER_REVERSE));
1549: PetscCall(VecScatterEnd(scatter, *Y, X, INSERT_VALUES, SCATTER_REVERSE));
1550: } else {
1551: PetscBool iscuda, iship;
1552: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &iscuda, VECSEQCUDA, VECMPICUDA, ""));
1553: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &iship, VECSEQHIP, VECMPIHIP, ""));
1555: if (iscuda) {
1556: #if defined(PETSC_HAVE_CUDA)
1557: PetscOffloadMask ymask = (*Y)->offloadmask;
1559: /* The offloadmask of X dictates where to move memory
1560: If X GPU data is valid, then move Y data on GPU if needed
1561: Otherwise, move back to the CPU */
1562: switch (X->offloadmask) {
1563: case PETSC_OFFLOAD_BOTH:
1564: if (ymask == PETSC_OFFLOAD_CPU) {
1565: PetscCall(VecCUDAResetArray(*Y));
1566: } else if (ymask == PETSC_OFFLOAD_GPU) {
1567: X->offloadmask = PETSC_OFFLOAD_GPU;
1568: }
1569: break;
1570: case PETSC_OFFLOAD_GPU:
1571: if (ymask == PETSC_OFFLOAD_CPU) PetscCall(VecCUDAResetArray(*Y));
1572: break;
1573: case PETSC_OFFLOAD_CPU:
1574: if (ymask == PETSC_OFFLOAD_GPU) PetscCall(VecResetArray(*Y));
1575: break;
1576: case PETSC_OFFLOAD_UNALLOCATED:
1577: case PETSC_OFFLOAD_KOKKOS:
1578: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "This should not happen");
1579: }
1580: #endif
1581: } else if (iship) {
1582: #if defined(PETSC_HAVE_HIP)
1583: PetscOffloadMask ymask = (*Y)->offloadmask;
1585: /* The offloadmask of X dictates where to move memory
1586: If X GPU data is valid, then move Y data on GPU if needed
1587: Otherwise, move back to the CPU */
1588: switch (X->offloadmask) {
1589: case PETSC_OFFLOAD_BOTH:
1590: if (ymask == PETSC_OFFLOAD_CPU) {
1591: PetscCall(VecHIPResetArray(*Y));
1592: } else if (ymask == PETSC_OFFLOAD_GPU) {
1593: X->offloadmask = PETSC_OFFLOAD_GPU;
1594: }
1595: break;
1596: case PETSC_OFFLOAD_GPU:
1597: if (ymask == PETSC_OFFLOAD_CPU) PetscCall(VecHIPResetArray(*Y));
1598: break;
1599: case PETSC_OFFLOAD_CPU:
1600: if (ymask == PETSC_OFFLOAD_GPU) PetscCall(VecResetArray(*Y));
1601: break;
1602: case PETSC_OFFLOAD_UNALLOCATED:
1603: case PETSC_OFFLOAD_KOKKOS:
1604: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "This should not happen");
1605: }
1606: #endif
1607: } else {
1608: /* If OpenCL vecs updated the device memory, this triggers a copy on the CPU */
1609: PetscCall(VecResetArray(*Y));
1610: }
1611: PetscCall(PetscObjectStateIncrease((PetscObject)X));
1612: }
1613: }
1614: }
1615: PetscCall(VecDestroy(Y));
1616: PetscFunctionReturn(PETSC_SUCCESS);
1617: }
1619: /*@
1620: VecCreateLocalVector - Creates a vector object suitable for use with `VecGetLocalVector()` and friends. You must call `VecDestroy()` when the
1621: vector is no longer needed.
1623: Not collective.
1625: Input parameter:
1626: . v - The vector for which the local vector is desired.
1628: Output parameter:
1629: . w - Upon exit this contains the local vector.
1631: Level: beginner
1633: .seealso: [](chapter_vectors), `Vec`, `VecGetLocalVectorRead()`, `VecRestoreLocalVectorRead()`, `VecGetLocalVector()`, `VecRestoreLocalVector()`
1634: @*/
1635: PetscErrorCode VecCreateLocalVector(Vec v, Vec *w)
1636: {
1637: PetscMPIInt size;
1639: PetscFunctionBegin;
1642: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)v), &size));
1643: if (size == 1) PetscCall(VecDuplicate(v, w));
1644: else if (v->ops->createlocalvector) PetscUseTypeMethod(v, createlocalvector, w);
1645: else {
1646: VecType type;
1647: PetscInt n;
1649: PetscCall(VecCreate(PETSC_COMM_SELF, w));
1650: PetscCall(VecGetLocalSize(v, &n));
1651: PetscCall(VecSetSizes(*w, n, n));
1652: PetscCall(VecGetBlockSize(v, &n));
1653: PetscCall(VecSetBlockSize(*w, n));
1654: PetscCall(VecGetType(v, &type));
1655: PetscCall(VecSetType(*w, type));
1656: }
1657: PetscFunctionReturn(PETSC_SUCCESS);
1658: }
1660: /*@
1661: VecGetLocalVectorRead - Maps the local portion of a vector into a
1662: vector.
1664: Not collective.
1666: Input parameter:
1667: . v - The vector for which the local vector is desired.
1669: Output parameter:
1670: . w - Upon exit this contains the local vector.
1672: Level: beginner
1674: Notes:
1675: You must call `VecRestoreLocalVectorRead()` when the local
1676: vector is no longer needed.
1678: This function is similar to `VecGetArrayRead()` which maps the local
1679: portion into a raw pointer. `VecGetLocalVectorRead()` is usually
1680: almost as efficient as `VecGetArrayRead()` but in certain circumstances
1681: `VecGetLocalVectorRead()` can be much more efficient than
1682: `VecGetArrayRead()`. This is because the construction of a contiguous
1683: array representing the vector data required by `VecGetArrayRead()` can
1684: be an expensive operation for certain vector types. For example, for
1685: GPU vectors `VecGetArrayRead()` requires that the data between device
1686: and host is synchronized.
1688: Unlike `VecGetLocalVector()`, this routine is not collective and
1689: preserves cached information.
1691: .seealso: [](chapter_vectors), `Vec`, `VecCreateLocalVector()`, `VecRestoreLocalVectorRead()`, `VecGetLocalVector()`, `VecGetArrayRead()`, `VecGetArray()`
1692: @*/
1693: PetscErrorCode VecGetLocalVectorRead(Vec v, Vec w)
1694: {
1695: PetscFunctionBegin;
1698: VecCheckSameLocalSize(v, 1, w, 2);
1699: if (v->ops->getlocalvectorread) {
1700: PetscUseTypeMethod(v, getlocalvectorread, w);
1701: } else {
1702: PetscScalar *a;
1704: PetscCall(VecGetArrayRead(v, (const PetscScalar **)&a));
1705: PetscCall(VecPlaceArray(w, a));
1706: }
1707: PetscCall(PetscObjectStateIncrease((PetscObject)w));
1708: PetscCall(VecLockReadPush(v));
1709: PetscCall(VecLockReadPush(w));
1710: PetscFunctionReturn(PETSC_SUCCESS);
1711: }
1713: /*@
1714: VecRestoreLocalVectorRead - Unmaps the local portion of a vector
1715: previously mapped into a vector using `VecGetLocalVectorRead()`.
1717: Not collective.
1719: Input parameter:
1720: + v - The local portion of this vector was previously mapped into `w` using `VecGetLocalVectorRead()`.
1721: - w - The vector into which the local portion of `v` was mapped.
1723: Level: beginner
1725: .seealso: [](chapter_vectors), `Vec`, `VecCreateLocalVector()`, `VecGetLocalVectorRead()`, `VecGetLocalVector()`, `VecGetArrayRead()`, `VecGetArray()`
1726: @*/
1727: PetscErrorCode VecRestoreLocalVectorRead(Vec v, Vec w)
1728: {
1729: PetscFunctionBegin;
1732: if (v->ops->restorelocalvectorread) {
1733: PetscUseTypeMethod(v, restorelocalvectorread, w);
1734: } else {
1735: const PetscScalar *a;
1737: PetscCall(VecGetArrayRead(w, &a));
1738: PetscCall(VecRestoreArrayRead(v, &a));
1739: PetscCall(VecResetArray(w));
1740: }
1741: PetscCall(VecLockReadPop(v));
1742: PetscCall(VecLockReadPop(w));
1743: PetscCall(PetscObjectStateIncrease((PetscObject)w));
1744: PetscFunctionReturn(PETSC_SUCCESS);
1745: }
1747: /*@
1748: VecGetLocalVector - Maps the local portion of a vector into a
1749: vector.
1751: Collective
1753: Input parameter:
1754: . v - The vector for which the local vector is desired.
1756: Output parameter:
1757: . w - Upon exit this contains the local vector.
1759: Level: beginner
1761: Notes:
1762: You must call `VecRestoreLocalVector()` when the local
1763: vector is no longer needed.
1765: This function is similar to `VecGetArray()` which maps the local
1766: portion into a raw pointer. `VecGetLocalVector()` is usually about as
1767: efficient as `VecGetArray()` but in certain circumstances
1768: `VecGetLocalVector()` can be much more efficient than `VecGetArray()`.
1769: This is because the construction of a contiguous array representing
1770: the vector data required by `VecGetArray()` can be an expensive
1771: operation for certain vector types. For example, for GPU vectors
1772: `VecGetArray()` requires that the data between device and host is
1773: synchronized.
1775: .seealso: [](chapter_vectors), `Vec`, `VecCreateLocalVector()`, `VecRestoreLocalVector()`, `VecGetLocalVectorRead()`, `VecGetArrayRead()`, `VecGetArray()`
1776: @*/
1777: PetscErrorCode VecGetLocalVector(Vec v, Vec w)
1778: {
1779: PetscFunctionBegin;
1782: VecCheckSameLocalSize(v, 1, w, 2);
1783: if (v->ops->getlocalvector) {
1784: PetscUseTypeMethod(v, getlocalvector, w);
1785: } else {
1786: PetscScalar *a;
1788: PetscCall(VecGetArray(v, &a));
1789: PetscCall(VecPlaceArray(w, a));
1790: }
1791: PetscCall(PetscObjectStateIncrease((PetscObject)w));
1792: PetscFunctionReturn(PETSC_SUCCESS);
1793: }
1795: /*@
1796: VecRestoreLocalVector - Unmaps the local portion of a vector
1797: previously mapped into a vector using `VecGetLocalVector()`.
1799: Logically collective.
1801: Input parameter:
1802: + v - The local portion of this vector was previously mapped into `w` using `VecGetLocalVector()`.
1803: - w - The vector into which the local portion of `v` was mapped.
1805: Level: beginner
1807: .seealso: [](chapter_vectors), `Vec`, `VecCreateLocalVector()`, `VecGetLocalVector()`, `VecGetLocalVectorRead()`, `VecRestoreLocalVectorRead()`, `LocalVectorRead()`, `VecGetArrayRead()`, `VecGetArray()`
1808: @*/
1809: PetscErrorCode VecRestoreLocalVector(Vec v, Vec w)
1810: {
1811: PetscFunctionBegin;
1814: if (v->ops->restorelocalvector) {
1815: PetscUseTypeMethod(v, restorelocalvector, w);
1816: } else {
1817: PetscScalar *a;
1818: PetscCall(VecGetArray(w, &a));
1819: PetscCall(VecRestoreArray(v, &a));
1820: PetscCall(VecResetArray(w));
1821: }
1822: PetscCall(PetscObjectStateIncrease((PetscObject)w));
1823: PetscCall(PetscObjectStateIncrease((PetscObject)v));
1824: PetscFunctionReturn(PETSC_SUCCESS);
1825: }
1827: /*@C
1828: VecGetArray - Returns a pointer to a contiguous array that contains this
1829: processor's portion of the vector data. For the standard PETSc
1830: vectors, `VecGetArray()` returns a pointer to the local data array and
1831: does not use any copies. If the underlying vector data is not stored
1832: in a contiguous array this routine will copy the data to a contiguous
1833: array and return a pointer to that. You MUST call `VecRestoreArray()`
1834: when you no longer need access to the array.
1836: Logically Collective
1838: Input Parameter:
1839: . x - the vector
1841: Output Parameter:
1842: . a - location to put pointer to the array
1844: Level: beginner
1846: Fortran Note:
1847: `VecGetArray()` Fortran binding is deprecated (since PETSc 3.19), use `VecGetArrayF90()`
1849: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecGetArrayReadF90()`, `VecPlaceArray()`, `VecGetArray2d()`,
1850: `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayWrite()`, `VecRestoreArrayWrite()`
1851: @*/
1852: PetscErrorCode VecGetArray(Vec x, PetscScalar **a)
1853: {
1854: PetscFunctionBegin;
1856: PetscCall(VecSetErrorIfLocked(x, 1));
1857: if (x->ops->getarray) { /* The if-else order matters! VECNEST, VECCUDA etc should have ops->getarray while VECCUDA etc are petscnative */
1858: PetscUseTypeMethod(x, getarray, a);
1859: } else if (x->petscnative) { /* VECSTANDARD */
1860: *a = *((PetscScalar **)x->data);
1861: } else SETERRQ(PetscObjectComm((PetscObject)x), PETSC_ERR_SUP, "Cannot get array for vector type \"%s\"", ((PetscObject)x)->type_name);
1862: PetscFunctionReturn(PETSC_SUCCESS);
1863: }
1865: /*@C
1866: VecRestoreArray - Restores a vector after `VecGetArray()` has been called and the array is no longer needed
1868: Logically Collective
1870: Input Parameters:
1871: + x - the vector
1872: - a - location of pointer to array obtained from `VecGetArray()`
1874: Level: beginner
1876: Fortran Note:
1877: `VecRestoreArray()` Fortran binding is deprecated (since PETSc 3.19), use `VecRestoreArrayF90()`
1879: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArrayRead()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecRestoreArrayReadF90()`, `VecPlaceArray()`, `VecRestoreArray2d()`,
1880: `VecGetArrayPair()`, `VecRestoreArrayPair()`
1881: @*/
1882: PetscErrorCode VecRestoreArray(Vec x, PetscScalar **a)
1883: {
1884: PetscFunctionBegin;
1887: if (x->ops->restorearray) {
1888: PetscUseTypeMethod(x, restorearray, a);
1889: } else PetscCheck(x->petscnative, PetscObjectComm((PetscObject)x), PETSC_ERR_SUP, "Cannot restore array for vector type \"%s\"", ((PetscObject)x)->type_name);
1890: if (a) *a = NULL;
1891: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1892: PetscFunctionReturn(PETSC_SUCCESS);
1893: }
1894: /*@C
1895: VecGetArrayRead - Get read-only pointer to contiguous array containing this processor's portion of the vector data.
1897: Not Collective
1899: Input Parameter:
1900: . x - the vector
1902: Output Parameter:
1903: . a - the array
1905: Level: beginner
1907: Notes:
1908: The array must be returned using a matching call to `VecRestoreArrayRead()`.
1910: Unlike `VecGetArray()`, preserves cached information like vector norms.
1912: Standard PETSc vectors use contiguous storage so that this routine does not perform a copy. Other vector
1913: implementations may require a copy, but such implementations should cache the contiguous representation so that
1914: only one copy is performed when this routine is called multiple times in sequence.
1916: Fortran Note:
1917: `VecGetArrayRead()` Fortran binding is deprecated (since PETSc 3.19), use `VecGetArrayReadF90()`
1919: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayReadF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
1920: @*/
1921: PetscErrorCode VecGetArrayRead(Vec x, const PetscScalar **a)
1922: {
1923: PetscFunctionBegin;
1926: if (x->ops->getarrayread) {
1927: PetscUseTypeMethod(x, getarrayread, a);
1928: } else if (x->ops->getarray) {
1929: PetscObjectState state;
1931: /* VECNEST, VECCUDA, VECKOKKOS etc */
1932: // x->ops->getarray may bump the object state, but since we know this is a read-only get
1933: // we can just undo that
1934: PetscCall(PetscObjectStateGet((PetscObject)x, &state));
1935: PetscUseTypeMethod(x, getarray, (PetscScalar **)a);
1936: PetscCall(PetscObjectStateSet((PetscObject)x, state));
1937: } else if (x->petscnative) {
1938: /* VECSTANDARD */
1939: *a = *((PetscScalar **)x->data);
1940: } else SETERRQ(PetscObjectComm((PetscObject)x), PETSC_ERR_SUP, "Cannot get array read for vector type \"%s\"", ((PetscObject)x)->type_name);
1941: PetscFunctionReturn(PETSC_SUCCESS);
1942: }
1944: /*@C
1945: VecRestoreArrayRead - Restore array obtained with `VecGetArrayRead()`
1947: Not Collective
1949: Input Parameters:
1950: + vec - the vector
1951: - array - the array
1953: Level: beginner
1955: Fortran Note:
1956: `VecRestoreArrayRead()` Fortran binding is deprecated (since PETSc 3.19), use `VecRestoreArrayReadF90()`
1958: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayReadF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
1959: @*/
1960: PetscErrorCode VecRestoreArrayRead(Vec x, const PetscScalar **a)
1961: {
1962: PetscFunctionBegin;
1965: if (x->petscnative) { /* VECSTANDARD, VECCUDA, VECKOKKOS etc */
1966: /* nothing */
1967: } else if (x->ops->restorearrayread) { /* VECNEST */
1968: PetscUseTypeMethod(x, restorearrayread, a);
1969: } else { /* No one? */
1970: PetscObjectState state;
1972: // x->ops->restorearray may bump the object state, but since we know this is a read-restore
1973: // we can just undo that
1974: PetscCall(PetscObjectStateGet((PetscObject)x, &state));
1975: PetscUseTypeMethod(x, restorearray, (PetscScalar **)a);
1976: PetscCall(PetscObjectStateSet((PetscObject)x, state));
1977: }
1978: if (a) *a = NULL;
1979: PetscFunctionReturn(PETSC_SUCCESS);
1980: }
1982: /*@C
1983: VecGetArrayWrite - Returns a pointer to a contiguous array that WILL contain this
1984: processor's portion of the vector data. The values in this array are NOT valid, the caller of this
1985: routine is responsible for putting values into the array; any values it does not set will be invalid
1987: Logically Collective
1989: Input Parameter:
1990: . x - the vector
1992: Output Parameter:
1993: . a - location to put pointer to the array
1995: Level: intermediate
1997: Note:
1998: The array must be returned using a matching call to `VecRestoreArrayRead()`.
2000: For vectors associated with GPUs, the host and device vectors are not synchronized before giving access. If you need correct
2001: values in the array use `VecGetArray()`
2003: Fortran Note:
2004: `VecGetArrayWrite()` Fortran binding is deprecated (since PETSc 3.19), use `VecGetArrayWriteF90()`
2006: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayWriteF90()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecGetArrayReadF90()`, `VecPlaceArray()`, `VecGetArray2d()`,
2007: `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArray()`, `VecRestoreArrayWrite()`
2008: @*/
2009: PetscErrorCode VecGetArrayWrite(Vec x, PetscScalar **a)
2010: {
2011: PetscFunctionBegin;
2014: PetscCall(VecSetErrorIfLocked(x, 1));
2015: if (x->ops->getarraywrite) {
2016: PetscUseTypeMethod(x, getarraywrite, a);
2017: } else {
2018: PetscCall(VecGetArray(x, a));
2019: }
2020: PetscFunctionReturn(PETSC_SUCCESS);
2021: }
2023: /*@C
2024: VecRestoreArrayWrite - Restores a vector after `VecGetArrayWrite()` has been called.
2026: Logically Collective
2028: Input Parameters:
2029: + x - the vector
2030: - a - location of pointer to array obtained from `VecGetArray()`
2032: Level: beginner
2034: Fortran Note:
2035: `VecRestoreArrayWrite()` Fortran binding is deprecated (since PETSc 3.19), use `VecRestoreArrayWriteF90()`
2037: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayWriteF90()`, `VecGetArray()`, `VecRestoreArrayRead()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecRestoreArrayReadF90()`, `VecPlaceArray()`, `VecRestoreArray2d()`,
2038: `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayWrite()`
2039: @*/
2040: PetscErrorCode VecRestoreArrayWrite(Vec x, PetscScalar **a)
2041: {
2042: PetscFunctionBegin;
2045: if (x->ops->restorearraywrite) {
2046: PetscUseTypeMethod(x, restorearraywrite, a);
2047: } else if (x->ops->restorearray) {
2048: PetscUseTypeMethod(x, restorearray, a);
2049: }
2050: if (a) *a = NULL;
2051: PetscCall(PetscObjectStateIncrease((PetscObject)x));
2052: PetscFunctionReturn(PETSC_SUCCESS);
2053: }
2055: /*@C
2056: VecGetArrays - Returns a pointer to the arrays in a set of vectors
2057: that were created by a call to `VecDuplicateVecs()`.
2059: Logically Collective; No Fortran Support
2061: Input Parameters:
2062: + x - the vectors
2063: - n - the number of vectors
2065: Output Parameter:
2066: . a - location to put pointer to the array
2068: Level: intermediate
2070: Note:
2071: You MUST call `VecRestoreArrays()` when you no longer need access to the arrays.
2073: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArrays()`
2074: @*/
2075: PetscErrorCode VecGetArrays(const Vec x[], PetscInt n, PetscScalar **a[])
2076: {
2077: PetscInt i;
2078: PetscScalar **q;
2080: PetscFunctionBegin;
2084: PetscCheck(n > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Must get at least one array n = %" PetscInt_FMT, n);
2085: PetscCall(PetscMalloc1(n, &q));
2086: for (i = 0; i < n; ++i) PetscCall(VecGetArray(x[i], &q[i]));
2087: *a = q;
2088: PetscFunctionReturn(PETSC_SUCCESS);
2089: }
2091: /*@C
2092: VecRestoreArrays - Restores a group of vectors after `VecGetArrays()`
2093: has been called.
2095: Logically Collective; No Fortran Support
2097: Input Parameters:
2098: + x - the vector
2099: . n - the number of vectors
2100: - a - location of pointer to arrays obtained from `VecGetArrays()`
2102: Notes:
2103: For regular PETSc vectors this routine does not involve any copies. For
2104: any special vectors that do not store local vector data in a contiguous
2105: array, this routine will copy the data back into the underlying
2106: vector data structure from the arrays obtained with `VecGetArrays()`.
2108: Level: intermediate
2110: .seealso: [](chapter_vectors), `Vec`, `VecGetArrays()`, `VecRestoreArray()`
2111: @*/
2112: PetscErrorCode VecRestoreArrays(const Vec x[], PetscInt n, PetscScalar **a[])
2113: {
2114: PetscInt i;
2115: PetscScalar **q = *a;
2117: PetscFunctionBegin;
2122: for (i = 0; i < n; ++i) PetscCall(VecRestoreArray(x[i], &q[i]));
2123: PetscCall(PetscFree(q));
2124: PetscFunctionReturn(PETSC_SUCCESS);
2125: }
2127: /*@C
2128: VecGetArrayAndMemType - Like `VecGetArray()`, but if this is a standard device vector (e.g., `VECCUDA`), the returned pointer will be a device
2129: pointer to the device memory that contains this processor's portion of the vector data. Device data is guaranteed to have the latest value.
2130: Otherwise, when this is a host vector (e.g., `VECMPI`), this routine functions the same as `VecGetArray()` and returns a host pointer.
2132: For `VECKOKKOS`, if Kokkos is configured without device (e.g., use serial or openmp), per this function, the vector works like `VECSEQ`/`VECMPI`;
2133: otherwise, it works like `VECCUDA` or `VECHIP` etc.
2135: Logically Collective; No Fortran Support
2137: Input Parameter:
2138: . x - the vector
2140: Output Parameters:
2141: + a - location to put pointer to the array
2142: - mtype - memory type of the array
2144: Level: beginner
2146: Note:
2147: Use `VecRestoreArrayAndMemType()` when the array access is no longer needed
2149: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayAndMemType()`, `VecGetArrayReadAndMemType()`, `VecGetArrayWriteAndMemType()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecGetArrayReadF90()`,
2150: `VecPlaceArray()`, `VecGetArray2d()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayWrite()`, `VecRestoreArrayWrite()`
2151: @*/
2152: PetscErrorCode VecGetArrayAndMemType(Vec x, PetscScalar **a, PetscMemType *mtype)
2153: {
2154: PetscFunctionBegin;
2159: PetscCall(VecSetErrorIfLocked(x, 1));
2160: if (x->ops->getarrayandmemtype) {
2161: /* VECCUDA, VECKOKKOS etc */
2162: PetscUseTypeMethod(x, getarrayandmemtype, a, mtype);
2163: } else {
2164: /* VECSTANDARD, VECNEST, VECVIENNACL */
2165: PetscCall(VecGetArray(x, a));
2166: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2167: }
2168: PetscFunctionReturn(PETSC_SUCCESS);
2169: }
2171: /*@C
2172: VecRestoreArrayAndMemType - Restores a vector after `VecGetArrayAndMemType()` has been called.
2174: Logically Collective; No Fortran Support
2176: Input Parameters:
2177: + x - the vector
2178: - a - location of pointer to array obtained from `VecGetArrayAndMemType()`
2180: Level: beginner
2182: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayAndMemType()`, `VecGetArray()`, `VecRestoreArrayRead()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecRestoreArrayReadF90()`,
2183: `VecPlaceArray()`, `VecRestoreArray2d()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
2184: @*/
2185: PetscErrorCode VecRestoreArrayAndMemType(Vec x, PetscScalar **a)
2186: {
2187: PetscFunctionBegin;
2191: if (x->ops->restorearrayandmemtype) {
2192: /* VECCUDA, VECKOKKOS etc */
2193: PetscUseTypeMethod(x, restorearrayandmemtype, a);
2194: } else {
2195: /* VECNEST, VECVIENNACL */
2196: PetscCall(VecRestoreArray(x, a));
2197: } /* VECSTANDARD does nothing */
2198: if (a) *a = NULL;
2199: PetscCall(PetscObjectStateIncrease((PetscObject)x));
2200: PetscFunctionReturn(PETSC_SUCCESS);
2201: }
2203: /*@C
2204: VecGetArrayReadAndMemType - Like `VecGetArrayRead()`, but if the input vector is a device vector, it will return a read-only device pointer.
2205: The returned pointer is guaranteed to point to up-to-date data. For host vectors, it functions as `VecGetArrayRead()`.
2207: Not Collective; No Fortran Support
2209: Input Parameter:
2210: . x - the vector
2212: Output Parameters:
2213: + a - the array
2214: - mtype - memory type of the array
2216: Level: beginner
2218: Notes:
2219: The array must be returned using a matching call to `VecRestoreArrayReadAndMemType()`.
2221: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayReadAndMemType()`, `VecGetArrayAndMemType()`, `VecGetArrayWriteAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayAndMemType()`
2222: @*/
2223: PetscErrorCode VecGetArrayReadAndMemType(Vec x, const PetscScalar **a, PetscMemType *mtype)
2224: {
2225: PetscFunctionBegin;
2230: if (x->ops->getarrayreadandmemtype) {
2231: /* VECCUDA/VECHIP though they are also petscnative */
2232: PetscUseTypeMethod(x, getarrayreadandmemtype, a, mtype);
2233: } else if (x->ops->getarrayandmemtype) {
2234: /* VECKOKKOS */
2235: PetscObjectState state;
2237: // see VecGetArrayRead() for why
2238: PetscCall(PetscObjectStateGet((PetscObject)x, &state));
2239: PetscUseTypeMethod(x, getarrayandmemtype, (PetscScalar **)a, mtype);
2240: PetscCall(PetscObjectStateSet((PetscObject)x, state));
2241: } else {
2242: PetscCall(VecGetArrayRead(x, a));
2243: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2244: }
2245: PetscFunctionReturn(PETSC_SUCCESS);
2246: }
2248: /*@C
2249: VecRestoreArrayReadAndMemType - Restore array obtained with `VecGetArrayReadAndMemType()`
2251: Not Collective; No Fortran Support
2253: Input Parameters:
2254: + vec - the vector
2255: - array - the array
2257: Level: beginner
2259: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayReadAndMemType()`, `VecRestoreArrayAndMemType()`, `VecRestoreArrayWriteAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
2260: @*/
2261: PetscErrorCode VecRestoreArrayReadAndMemType(Vec x, const PetscScalar **a)
2262: {
2263: PetscFunctionBegin;
2267: if (x->ops->restorearrayreadandmemtype) {
2268: /* VECCUDA/VECHIP */
2269: PetscUseTypeMethod(x, restorearrayreadandmemtype, a);
2270: } else if (!x->petscnative) {
2271: /* VECNEST */
2272: PetscCall(VecRestoreArrayRead(x, a));
2273: }
2274: if (a) *a = NULL;
2275: PetscFunctionReturn(PETSC_SUCCESS);
2276: }
2278: /*@C
2279: VecGetArrayWriteAndMemType - Like `VecGetArrayWrite()`, but if this is a device vector it will always return
2280: a device pointer to the device memory that contains this processor's portion of the vector data.
2282: Not Collective; No Fortran Support
2284: Input Parameter:
2285: . x - the vector
2287: Output Parameters:
2288: + a - the array
2289: - mtype - memory type of the array
2291: Level: beginner
2293: Note:
2294: The array must be returned using a matching call to `VecRestoreArrayWriteAndMemType()`, where it will label the device memory as most recent.
2296: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayWriteAndMemType()`, `VecGetArrayReadAndMemType()`, `VecGetArrayAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`,
2297: @*/
2298: PetscErrorCode VecGetArrayWriteAndMemType(Vec x, PetscScalar **a, PetscMemType *mtype)
2299: {
2300: PetscFunctionBegin;
2303: PetscCall(VecSetErrorIfLocked(x, 1));
2306: if (x->ops->getarraywriteandmemtype) {
2307: /* VECCUDA, VECHIP, VECKOKKOS etc, though they are also petscnative */
2308: PetscUseTypeMethod(x, getarraywriteandmemtype, a, mtype);
2309: } else if (x->ops->getarrayandmemtype) {
2310: PetscCall(VecGetArrayAndMemType(x, a, mtype));
2311: } else {
2312: /* VECNEST, VECVIENNACL */
2313: PetscCall(VecGetArrayWrite(x, a));
2314: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2315: }
2316: PetscFunctionReturn(PETSC_SUCCESS);
2317: }
2319: /*@C
2320: VecRestoreArrayWriteAndMemType - Restore array obtained with `VecGetArrayWriteAndMemType()`
2322: Not Collective; No Fortran Support
2324: Input Parameters:
2325: + vec - the vector
2326: - array - the array
2328: Level: beginner
2330: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayWriteAndMemType()`, `VecRestoreArrayAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
2331: @*/
2332: PetscErrorCode VecRestoreArrayWriteAndMemType(Vec x, PetscScalar **a)
2333: {
2334: PetscFunctionBegin;
2337: PetscCall(VecSetErrorIfLocked(x, 1));
2339: if (x->ops->restorearraywriteandmemtype) {
2340: /* VECCUDA/VECHIP */
2341: PetscMemType PETSC_UNUSED mtype; // since this function doesn't accept a memtype?
2342: PetscUseTypeMethod(x, restorearraywriteandmemtype, a, &mtype);
2343: } else if (x->ops->restorearrayandmemtype) {
2344: PetscCall(VecRestoreArrayAndMemType(x, a));
2345: } else {
2346: PetscCall(VecRestoreArray(x, a));
2347: }
2348: if (a) *a = NULL;
2349: PetscFunctionReturn(PETSC_SUCCESS);
2350: }
2352: /*@
2353: VecPlaceArray - Allows one to replace the array in a vector with an
2354: array provided by the user. This is useful to avoid copying an array
2355: into a vector.
2357: Not Collective; No Fortran Support
2359: Input Parameters:
2360: + vec - the vector
2361: - array - the array
2363: Level: developer
2365: Notes:
2366: Use `VecReplaceArray()` instead to permanently replace the array
2368: You can return to the original array with a call to `VecResetArray()`. `vec` does not take
2369: ownership of `array` in any way.
2371: The user must free `array` themselves but be careful not to
2372: do so before the vector has either been destroyed, had its original array restored with
2373: `VecResetArray()` or permanently replaced with `VecReplaceArray()`.
2375: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecResetArray()`
2376: @*/
2377: PetscErrorCode VecPlaceArray(Vec vec, const PetscScalar array[])
2378: {
2379: PetscFunctionBegin;
2383: PetscUseTypeMethod(vec, placearray, array);
2384: PetscCall(PetscObjectStateIncrease((PetscObject)vec));
2385: PetscFunctionReturn(PETSC_SUCCESS);
2386: }
2388: /*@C
2389: VecReplaceArray - Allows one to replace the array in a vector with an
2390: array provided by the user. This is useful to avoid copying an array
2391: into a vector.
2393: Not Collective; No Fortran Support
2395: Input Parameters:
2396: + vec - the vector
2397: - array - the array
2399: Level: developer
2401: Notes:
2402: This permanently replaces the array and frees the memory associated
2403: with the old array. Use `VecPlaceArray()` to temporarily replace the array.
2405: The memory passed in MUST be obtained with `PetscMalloc()` and CANNOT be
2406: freed by the user. It will be freed when the vector is destroyed.
2408: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecPlaceArray()`, `VecResetArray()`
2409: @*/
2410: PetscErrorCode VecReplaceArray(Vec vec, const PetscScalar array[])
2411: {
2412: PetscFunctionBegin;
2415: PetscUseTypeMethod(vec, replacearray, array);
2416: PetscCall(PetscObjectStateIncrease((PetscObject)vec));
2417: PetscFunctionReturn(PETSC_SUCCESS);
2418: }
2420: /*MC
2421: VecDuplicateVecsF90 - Creates several vectors of the same type as an existing vector
2422: and makes them accessible via a Fortran pointer.
2424: Synopsis:
2425: VecDuplicateVecsF90(Vec x,PetscInt n,{Vec, pointer :: y(:)},integer ierr)
2427: Collective
2429: Input Parameters:
2430: + x - a vector to mimic
2431: - n - the number of vectors to obtain
2433: Output Parameters:
2434: + y - Fortran pointer to the array of vectors
2435: - ierr - error code
2437: Example of Usage:
2438: .vb
2439: #include <petsc/finclude/petscvec.h>
2440: use petscvec
2442: Vec x
2443: Vec, pointer :: y(:)
2444: ....
2445: call VecDuplicateVecsF90(x,2,y,ierr)
2446: call VecSet(y(2),alpha,ierr)
2447: call VecSet(y(2),alpha,ierr)
2448: ....
2449: call VecDestroyVecsF90(2,y,ierr)
2450: .ve
2452: Level: beginner
2454: Note:
2455: Use `VecDestroyVecsF90()` to free the space.
2457: .seealso: [](chapter_vectors), `Vec`, `VecDestroyVecsF90()`, `VecDuplicateVecs()`
2458: M*/
2460: /*MC
2461: VecRestoreArrayF90 - Restores a vector to a usable state after a call to
2462: `VecGetArrayF90()`.
2464: Synopsis:
2465: VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2467: Logically Collective
2469: Input Parameters:
2470: + x - vector
2471: - xx_v - the Fortran pointer to the array
2473: Output Parameter:
2474: . ierr - error code
2476: Example of Usage:
2477: .vb
2478: #include <petsc/finclude/petscvec.h>
2479: use petscvec
2481: PetscScalar, pointer :: xx_v(:)
2482: ....
2483: call VecGetArrayF90(x,xx_v,ierr)
2484: xx_v(3) = a
2485: call VecRestoreArrayF90(x,xx_v,ierr)
2486: .ve
2488: Level: beginner
2490: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrayReadF90()`
2491: M*/
2493: /*MC
2494: VecDestroyVecsF90 - Frees a block of vectors obtained with `VecDuplicateVecsF90()`.
2496: Synopsis:
2497: VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)
2499: Collective
2501: Input Parameters:
2502: + n - the number of vectors previously obtained
2503: - x - pointer to array of vector pointers
2505: Output Parameter:
2506: . ierr - error code
2508: Level: beginner
2510: .seealso: [](chapter_vectors), `Vec`, `VecDestroyVecs()`, `VecDuplicateVecsF90()`
2511: M*/
2513: /*MC
2514: VecGetArrayF90 - Accesses a vector array from Fortran. For default PETSc
2515: vectors, `VecGetArrayF90()` returns a pointer to the local data array. Otherwise,
2516: this routine is implementation dependent. You MUST call `VecRestoreArrayF90()`
2517: when you no longer need access to the array.
2519: Synopsis:
2520: VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2522: Logically Collective
2524: Input Parameter:
2525: . x - vector
2527: Output Parameters:
2528: + xx_v - the Fortran pointer to the array
2529: - ierr - error code
2531: Example of Usage:
2532: .vb
2533: #include <petsc/finclude/petscvec.h>
2534: use petscvec
2536: PetscScalar, pointer :: xx_v(:)
2537: ....
2538: call VecGetArrayF90(x,xx_v,ierr)
2539: xx_v(3) = a
2540: call VecRestoreArrayF90(x,xx_v,ierr)
2541: .ve
2543: Level: beginner
2545: Note:
2546: If you ONLY intend to read entries from the array and not change any entries you should use `VecGetArrayReadF90()`.
2548: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayReadF90()`
2549: M*/
2551: /*MC
2552: VecGetArrayReadF90 - Accesses a read only array from Fortran. For default PETSc
2553: vectors, `VecGetArrayF90()` returns a pointer to the local data array. Otherwise,
2554: this routine is implementation dependent. You MUST call `VecRestoreArrayReadF90()`
2555: when you no longer need access to the array.
2557: Synopsis:
2558: VecGetArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2560: Logically Collective
2562: Input Parameter:
2563: . x - vector
2565: Output Parameters:
2566: + xx_v - the Fortran pointer to the array
2567: - ierr - error code
2569: Example of Usage:
2570: .vb
2571: #include <petsc/finclude/petscvec.h>
2572: use petscvec
2574: PetscScalar, pointer :: xx_v(:)
2575: ....
2576: call VecGetArrayReadF90(x,xx_v,ierr)
2577: a = xx_v(3)
2578: call VecRestoreArrayReadF90(x,xx_v,ierr)
2579: .ve
2581: Level: beginner
2583: Note:
2584: If you intend to write entries into the array you must use `VecGetArrayF90()`.
2586: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayReadF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecRestoreArrayRead()`, `VecGetArrayF90()`
2587: M*/
2589: /*MC
2590: VecRestoreArrayReadF90 - Restores a readonly vector to a usable state after a call to
2591: `VecGetArrayReadF90()`.
2593: Synopsis:
2594: VecRestoreArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2596: Logically Collective
2598: Input Parameters:
2599: + x - vector
2600: - xx_v - the Fortran pointer to the array
2602: Output Parameter:
2603: . ierr - error code
2605: Example of Usage:
2606: .vb
2607: #include <petsc/finclude/petscvec.h>
2608: use petscvec
2610: PetscScalar, pointer :: xx_v(:)
2611: ....
2612: call VecGetArrayReadF90(x,xx_v,ierr)
2613: a = xx_v(3)
2614: call VecRestoreArrayReadF90(x,xx_v,ierr)
2615: .ve
2617: Level: beginner
2619: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayReadF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecRestoreArrayRead()`, `VecRestoreArrayF90()`
2620: M*/
2622: /*@C
2623: VecGetArray2d - Returns a pointer to a 2d contiguous array that contains this
2624: processor's portion of the vector data. You MUST call `VecRestoreArray2d()`
2625: when you no longer need access to the array.
2627: Logically Collective
2629: Input Parameters:
2630: + x - the vector
2631: . m - first dimension of two dimensional array
2632: . n - second dimension of two dimensional array
2633: . mstart - first index you will use in first coordinate direction (often 0)
2634: - nstart - first index in the second coordinate direction (often 0)
2636: Output Parameter:
2637: . a - location to put pointer to the array
2639: Level: developer
2641: Notes:
2642: For a vector obtained from `DMCreateLocalVector()` mstart and nstart are likely
2643: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2644: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
2645: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray2d()`.
2647: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2649: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2650: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
2651: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2652: @*/
2653: PetscErrorCode VecGetArray2d(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
2654: {
2655: PetscInt i, N;
2656: PetscScalar *aa;
2658: PetscFunctionBegin;
2662: PetscCall(VecGetLocalSize(x, &N));
2663: 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);
2664: PetscCall(VecGetArray(x, &aa));
2666: PetscCall(PetscMalloc1(m, a));
2667: for (i = 0; i < m; i++) (*a)[i] = aa + i * n - nstart;
2668: *a -= mstart;
2669: PetscFunctionReturn(PETSC_SUCCESS);
2670: }
2672: /*@C
2673: VecGetArray2dWrite - Returns a pointer to a 2d contiguous array that will contain this
2674: processor's portion of the vector data. You MUST call `VecRestoreArray2dWrite()`
2675: when you no longer need access to the array.
2677: Logically Collective
2679: Input Parameters:
2680: + x - the vector
2681: . m - first dimension of two dimensional array
2682: . n - second dimension of two dimensional array
2683: . mstart - first index you will use in first coordinate direction (often 0)
2684: - nstart - first index in the second coordinate direction (often 0)
2686: Output Parameter:
2687: . a - location to put pointer to the array
2689: Level: developer
2691: Notes:
2692: For a vector obtained from `DMCreateLocalVector()` mstart and nstart are likely
2693: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2694: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
2695: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray2d()`.
2697: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2699: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2700: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
2701: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2702: @*/
2703: PetscErrorCode VecGetArray2dWrite(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
2704: {
2705: PetscInt i, N;
2706: PetscScalar *aa;
2708: PetscFunctionBegin;
2712: PetscCall(VecGetLocalSize(x, &N));
2713: 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);
2714: PetscCall(VecGetArrayWrite(x, &aa));
2716: PetscCall(PetscMalloc1(m, a));
2717: for (i = 0; i < m; i++) (*a)[i] = aa + i * n - nstart;
2718: *a -= mstart;
2719: PetscFunctionReturn(PETSC_SUCCESS);
2720: }
2722: /*@C
2723: VecRestoreArray2d - Restores a vector after `VecGetArray2d()` has been called.
2725: Logically Collective
2727: Input Parameters:
2728: + x - the vector
2729: . m - first dimension of two dimensional array
2730: . n - second dimension of the two dimensional array
2731: . mstart - first index you will use in first coordinate direction (often 0)
2732: . nstart - first index in the second coordinate direction (often 0)
2733: - a - location of pointer to array obtained from `VecGetArray2d()`
2735: Level: developer
2737: Notes:
2738: For regular PETSc vectors this routine does not involve any copies. For
2739: any special vectors that do not store local vector data in a contiguous
2740: array, this routine will copy the data back into the underlying
2741: vector data structure from the array obtained with `VecGetArray()`.
2743: This routine actually zeros out the a pointer.
2745: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
2746: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
2747: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2748: @*/
2749: PetscErrorCode VecRestoreArray2d(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
2750: {
2751: void *dummy;
2753: PetscFunctionBegin;
2757: dummy = (void *)(*a + mstart);
2758: PetscCall(PetscFree(dummy));
2759: PetscCall(VecRestoreArray(x, NULL));
2760: PetscFunctionReturn(PETSC_SUCCESS);
2761: }
2763: /*@C
2764: VecRestoreArray2dWrite - Restores a vector after VecGetArray2dWrite`()` has been called.
2766: Logically Collective
2768: Input Parameters:
2769: + x - the vector
2770: . m - first dimension of two dimensional array
2771: . n - second dimension of the two dimensional array
2772: . mstart - first index you will use in first coordinate direction (often 0)
2773: . nstart - first index in the second coordinate direction (often 0)
2774: - a - location of pointer to array obtained from `VecGetArray2d()`
2776: Level: developer
2778: Notes:
2779: For regular PETSc vectors this routine does not involve any copies. For
2780: any special vectors that do not store local vector data in a contiguous
2781: array, this routine will copy the data back into the underlying
2782: vector data structure from the array obtained with `VecGetArray()`.
2784: This routine actually zeros out the a pointer.
2786: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
2787: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
2788: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2789: @*/
2790: PetscErrorCode VecRestoreArray2dWrite(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
2791: {
2792: void *dummy;
2794: PetscFunctionBegin;
2798: dummy = (void *)(*a + mstart);
2799: PetscCall(PetscFree(dummy));
2800: PetscCall(VecRestoreArrayWrite(x, NULL));
2801: PetscFunctionReturn(PETSC_SUCCESS);
2802: }
2804: /*@C
2805: VecGetArray1d - Returns a pointer to a 1d contiguous array that contains this
2806: processor's portion of the vector data. You MUST call `VecRestoreArray1d()`
2807: when you no longer need access to the array.
2809: Logically Collective
2811: Input Parameters:
2812: + x - the vector
2813: . m - first dimension of two dimensional array
2814: - mstart - first index you will use in first coordinate direction (often 0)
2816: Output Parameter:
2817: . a - location to put pointer to the array
2819: Level: developer
2821: Notes:
2822: For a vector obtained from `DMCreateLocalVector()` mstart are likely
2823: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2824: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`.
2826: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2828: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2829: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
2830: `VecGetArray2d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2831: @*/
2832: PetscErrorCode VecGetArray1d(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
2833: {
2834: PetscInt N;
2836: PetscFunctionBegin;
2840: PetscCall(VecGetLocalSize(x, &N));
2841: 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);
2842: PetscCall(VecGetArray(x, a));
2843: *a -= mstart;
2844: PetscFunctionReturn(PETSC_SUCCESS);
2845: }
2847: /*@C
2848: VecGetArray1dWrite - Returns a pointer to a 1d contiguous array that will contain this
2849: processor's portion of the vector data. You MUST call `VecRestoreArray1dWrite()`
2850: when you no longer need access to the array.
2852: Logically Collective
2854: Input Parameters:
2855: + x - the vector
2856: . m - first dimension of two dimensional array
2857: - mstart - first index you will use in first coordinate direction (often 0)
2859: Output Parameter:
2860: . a - location to put pointer to the array
2862: Level: developer
2864: Notes:
2865: For a vector obtained from `DMCreateLocalVector()` mstart are likely
2866: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2867: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`.
2869: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2871: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2872: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
2873: `VecGetArray2d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2874: @*/
2875: PetscErrorCode VecGetArray1dWrite(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
2876: {
2877: PetscInt N;
2879: PetscFunctionBegin;
2883: PetscCall(VecGetLocalSize(x, &N));
2884: 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);
2885: PetscCall(VecGetArrayWrite(x, a));
2886: *a -= mstart;
2887: PetscFunctionReturn(PETSC_SUCCESS);
2888: }
2890: /*@C
2891: VecRestoreArray1d - Restores a vector after `VecGetArray1d()` has been called.
2893: Logically Collective
2895: Input Parameters:
2896: + x - the vector
2897: . m - first dimension of two dimensional array
2898: . mstart - first index you will use in first coordinate direction (often 0)
2899: - a - location of pointer to array obtained from `VecGetArray1d()`
2901: Level: developer
2903: Notes:
2904: For regular PETSc vectors this routine does not involve any copies. For
2905: any special vectors that do not store local vector data in a contiguous
2906: array, this routine will copy the data back into the underlying
2907: vector data structure from the array obtained with `VecGetArray1d()`.
2909: This routine actually zeros out the a pointer.
2911: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
2912: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
2913: `VecGetArray1d()`, `VecRestoreArray2d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2914: @*/
2915: PetscErrorCode VecRestoreArray1d(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
2916: {
2917: PetscFunctionBegin;
2920: PetscCall(VecRestoreArray(x, NULL));
2921: PetscFunctionReturn(PETSC_SUCCESS);
2922: }
2924: /*@C
2925: VecRestoreArray1dWrite - Restores a vector after `VecGetArray1dWrite()` has been called.
2927: Logically Collective
2929: Input Parameters:
2930: + x - the vector
2931: . m - first dimension of two dimensional array
2932: . mstart - first index you will use in first coordinate direction (often 0)
2933: - a - location of pointer to array obtained from `VecGetArray1d()`
2935: Level: developer
2937: Notes:
2938: For regular PETSc vectors this routine does not involve any copies. For
2939: any special vectors that do not store local vector data in a contiguous
2940: array, this routine will copy the data back into the underlying
2941: vector data structure from the array obtained with `VecGetArray1d()`.
2943: This routine actually zeros out the a pointer.
2945: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
2946: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
2947: `VecGetArray1d()`, `VecRestoreArray2d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2948: @*/
2949: PetscErrorCode VecRestoreArray1dWrite(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
2950: {
2951: PetscFunctionBegin;
2954: PetscCall(VecRestoreArrayWrite(x, NULL));
2955: PetscFunctionReturn(PETSC_SUCCESS);
2956: }
2958: /*@C
2959: VecGetArray3d - Returns a pointer to a 3d contiguous array that contains this
2960: processor's portion of the vector data. You MUST call `VecRestoreArray3d()`
2961: when you no longer need access to the array.
2963: Logically Collective
2965: Input Parameters:
2966: + x - the vector
2967: . m - first dimension of three dimensional array
2968: . n - second dimension of three dimensional array
2969: . p - third dimension of three dimensional array
2970: . mstart - first index you will use in first coordinate direction (often 0)
2971: . nstart - first index in the second coordinate direction (often 0)
2972: - pstart - first index in the third coordinate direction (often 0)
2974: Output Parameter:
2975: . a - location to put pointer to the array
2977: Level: developer
2979: Notes:
2980: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
2981: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2982: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
2983: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
2985: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2987: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2988: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
2989: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2990: @*/
2991: PetscErrorCode VecGetArray3d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
2992: {
2993: PetscInt i, N, j;
2994: PetscScalar *aa, **b;
2996: PetscFunctionBegin;
3000: PetscCall(VecGetLocalSize(x, &N));
3001: 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);
3002: PetscCall(VecGetArray(x, &aa));
3004: PetscCall(PetscMalloc(m * sizeof(PetscScalar **) + m * n * sizeof(PetscScalar *), a));
3005: b = (PetscScalar **)((*a) + m);
3006: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3007: for (i = 0; i < m; i++)
3008: for (j = 0; j < n; j++) b[i * n + j] = aa + i * n * p + j * p - pstart;
3009: *a -= mstart;
3010: PetscFunctionReturn(PETSC_SUCCESS);
3011: }
3013: /*@C
3014: VecGetArray3dWrite - Returns a pointer to a 3d contiguous array that will contain this
3015: processor's portion of the vector data. You MUST call `VecRestoreArray3dWrite()`
3016: when you no longer need access to the array.
3018: Logically Collective
3020: Input Parameters:
3021: + x - the vector
3022: . m - first dimension of three dimensional array
3023: . n - second dimension of three dimensional array
3024: . p - third dimension of three dimensional array
3025: . mstart - first index you will use in first coordinate direction (often 0)
3026: . nstart - first index in the second coordinate direction (often 0)
3027: - pstart - first index in the third coordinate direction (often 0)
3029: Output Parameter:
3030: . a - location to put pointer to the array
3032: Level: developer
3034: Notes:
3035: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3036: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3037: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3038: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
3040: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3042: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3043: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3044: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3045: @*/
3046: PetscErrorCode VecGetArray3dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3047: {
3048: PetscInt i, N, j;
3049: PetscScalar *aa, **b;
3051: PetscFunctionBegin;
3055: PetscCall(VecGetLocalSize(x, &N));
3056: 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);
3057: PetscCall(VecGetArrayWrite(x, &aa));
3059: PetscCall(PetscMalloc(m * sizeof(PetscScalar **) + m * n * sizeof(PetscScalar *), a));
3060: b = (PetscScalar **)((*a) + m);
3061: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3062: for (i = 0; i < m; i++)
3063: for (j = 0; j < n; j++) b[i * n + j] = aa + i * n * p + j * p - pstart;
3065: *a -= mstart;
3066: PetscFunctionReturn(PETSC_SUCCESS);
3067: }
3069: /*@C
3070: VecRestoreArray3d - Restores a vector after `VecGetArray3d()` has been called.
3072: Logically Collective
3074: Input Parameters:
3075: + x - the vector
3076: . m - first dimension of three dimensional array
3077: . n - second dimension of the three dimensional array
3078: . p - third dimension of the three dimensional array
3079: . mstart - first index you will use in first coordinate direction (often 0)
3080: . nstart - first index in the second coordinate direction (often 0)
3081: . pstart - first index in the third coordinate direction (often 0)
3082: - a - location of pointer to array obtained from VecGetArray3d()
3084: Level: developer
3086: Notes:
3087: For regular PETSc vectors this routine does not involve any copies. For
3088: any special vectors that do not store local vector data in a contiguous
3089: array, this routine will copy the data back into the underlying
3090: vector data structure from the array obtained with `VecGetArray()`.
3092: This routine actually zeros out the a pointer.
3094: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3095: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3096: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3097: @*/
3098: PetscErrorCode VecRestoreArray3d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3099: {
3100: void *dummy;
3102: PetscFunctionBegin;
3106: dummy = (void *)(*a + mstart);
3107: PetscCall(PetscFree(dummy));
3108: PetscCall(VecRestoreArray(x, NULL));
3109: PetscFunctionReturn(PETSC_SUCCESS);
3110: }
3112: /*@C
3113: VecRestoreArray3dWrite - Restores a vector after `VecGetArray3dWrite()` has been called.
3115: Logically Collective
3117: Input Parameters:
3118: + x - the vector
3119: . m - first dimension of three dimensional array
3120: . n - second dimension of the three dimensional array
3121: . p - third dimension of the three dimensional array
3122: . mstart - first index you will use in first coordinate direction (often 0)
3123: . nstart - first index in the second coordinate direction (often 0)
3124: . pstart - first index in the third coordinate direction (often 0)
3125: - a - location of pointer to array obtained from VecGetArray3d()
3127: Level: developer
3129: Notes:
3130: For regular PETSc vectors this routine does not involve any copies. For
3131: any special vectors that do not store local vector data in a contiguous
3132: array, this routine will copy the data back into the underlying
3133: vector data structure from the array obtained with `VecGetArray()`.
3135: This routine actually zeros out the a pointer.
3137: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3138: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3139: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3140: @*/
3141: PetscErrorCode VecRestoreArray3dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3142: {
3143: void *dummy;
3145: PetscFunctionBegin;
3149: dummy = (void *)(*a + mstart);
3150: PetscCall(PetscFree(dummy));
3151: PetscCall(VecRestoreArrayWrite(x, NULL));
3152: PetscFunctionReturn(PETSC_SUCCESS);
3153: }
3155: /*@C
3156: VecGetArray4d - Returns a pointer to a 4d contiguous array that contains this
3157: processor's portion of the vector data. You MUST call `VecRestoreArray4d()`
3158: when you no longer need access to the array.
3160: Logically Collective
3162: Input Parameters:
3163: + x - the vector
3164: . m - first dimension of four dimensional array
3165: . n - second dimension of four dimensional array
3166: . p - third dimension of four dimensional array
3167: . q - fourth dimension of four dimensional array
3168: . mstart - first index you will use in first coordinate direction (often 0)
3169: . nstart - first index in the second coordinate direction (often 0)
3170: . pstart - first index in the third coordinate direction (often 0)
3171: - qstart - first index in the fourth coordinate direction (often 0)
3173: Output Parameter:
3174: . a - location to put pointer to the array
3176: Level: beginner
3178: Notes:
3179: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3180: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3181: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3182: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
3184: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3186: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3187: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3188: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3189: @*/
3190: PetscErrorCode VecGetArray4d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3191: {
3192: PetscInt i, N, j, k;
3193: PetscScalar *aa, ***b, **c;
3195: PetscFunctionBegin;
3199: PetscCall(VecGetLocalSize(x, &N));
3200: 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);
3201: PetscCall(VecGetArray(x, &aa));
3203: PetscCall(PetscMalloc(m * sizeof(PetscScalar ***) + m * n * sizeof(PetscScalar **) + m * n * p * sizeof(PetscScalar *), a));
3204: b = (PetscScalar ***)((*a) + m);
3205: c = (PetscScalar **)(b + m * n);
3206: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3207: for (i = 0; i < m; i++)
3208: for (j = 0; j < n; j++) b[i * n + j] = c + i * n * p + j * p - pstart;
3209: for (i = 0; i < m; i++)
3210: for (j = 0; j < n; j++)
3211: for (k = 0; k < p; k++) c[i * n * p + j * p + k] = aa + i * n * p * q + j * p * q + k * q - qstart;
3212: *a -= mstart;
3213: PetscFunctionReturn(PETSC_SUCCESS);
3214: }
3216: /*@C
3217: VecGetArray4dWrite - Returns a pointer to a 4d contiguous array that will contain this
3218: processor's portion of the vector data. You MUST call `VecRestoreArray4dWrite()`
3219: when you no longer need access to the array.
3221: Logically Collective
3223: Input Parameters:
3224: + x - the vector
3225: . m - first dimension of four dimensional array
3226: . n - second dimension of four dimensional array
3227: . p - third dimension of four dimensional array
3228: . q - fourth dimension of four dimensional array
3229: . mstart - first index you will use in first coordinate direction (often 0)
3230: . nstart - first index in the second coordinate direction (often 0)
3231: . pstart - first index in the third coordinate direction (often 0)
3232: - qstart - first index in the fourth coordinate direction (often 0)
3234: Output Parameter:
3235: . a - location to put pointer to the array
3237: Level: beginner
3239: Notes:
3240: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3241: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3242: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3243: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
3245: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3247: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3248: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3249: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3250: @*/
3251: PetscErrorCode VecGetArray4dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3252: {
3253: PetscInt i, N, j, k;
3254: PetscScalar *aa, ***b, **c;
3256: PetscFunctionBegin;
3260: PetscCall(VecGetLocalSize(x, &N));
3261: 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);
3262: PetscCall(VecGetArrayWrite(x, &aa));
3264: PetscCall(PetscMalloc(m * sizeof(PetscScalar ***) + m * n * sizeof(PetscScalar **) + m * n * p * sizeof(PetscScalar *), a));
3265: b = (PetscScalar ***)((*a) + m);
3266: c = (PetscScalar **)(b + m * n);
3267: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3268: for (i = 0; i < m; i++)
3269: for (j = 0; j < n; j++) b[i * n + j] = c + i * n * p + j * p - pstart;
3270: for (i = 0; i < m; i++)
3271: for (j = 0; j < n; j++)
3272: for (k = 0; k < p; k++) c[i * n * p + j * p + k] = aa + i * n * p * q + j * p * q + k * q - qstart;
3273: *a -= mstart;
3274: PetscFunctionReturn(PETSC_SUCCESS);
3275: }
3277: /*@C
3278: VecRestoreArray4d - Restores a vector after `VecGetArray4d()` has been called.
3280: Logically Collective
3282: Input Parameters:
3283: + x - the vector
3284: . m - first dimension of four dimensional array
3285: . n - second dimension of the four dimensional array
3286: . p - third dimension of the four dimensional array
3287: . q - fourth dimension of the four dimensional array
3288: . mstart - first index you will use in first coordinate direction (often 0)
3289: . nstart - first index in the second coordinate direction (often 0)
3290: . pstart - first index in the third coordinate direction (often 0)
3291: . qstart - first index in the fourth coordinate direction (often 0)
3292: - a - location of pointer to array obtained from VecGetArray4d()
3294: Level: beginner
3296: Notes:
3297: For regular PETSc vectors this routine does not involve any copies. For
3298: any special vectors that do not store local vector data in a contiguous
3299: array, this routine will copy the data back into the underlying
3300: vector data structure from the array obtained with `VecGetArray()`.
3302: This routine actually zeros out the a pointer.
3304: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3305: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3306: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3307: @*/
3308: PetscErrorCode VecRestoreArray4d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3309: {
3310: void *dummy;
3312: PetscFunctionBegin;
3316: dummy = (void *)(*a + mstart);
3317: PetscCall(PetscFree(dummy));
3318: PetscCall(VecRestoreArray(x, NULL));
3319: PetscFunctionReturn(PETSC_SUCCESS);
3320: }
3322: /*@C
3323: VecRestoreArray4dWrite - Restores a vector after `VecGetArray4dWrite()` has been called.
3325: Logically Collective
3327: Input Parameters:
3328: + x - the vector
3329: . m - first dimension of four dimensional array
3330: . n - second dimension of the four dimensional array
3331: . p - third dimension of the four dimensional array
3332: . q - fourth dimension of the four dimensional array
3333: . mstart - first index you will use in first coordinate direction (often 0)
3334: . nstart - first index in the second coordinate direction (often 0)
3335: . pstart - first index in the third coordinate direction (often 0)
3336: . qstart - first index in the fourth coordinate direction (often 0)
3337: - a - location of pointer to array obtained from `VecGetArray4d()`
3339: Level: beginner
3341: Notes:
3342: For regular PETSc vectors this routine does not involve any copies. For
3343: any special vectors that do not store local vector data in a contiguous
3344: array, this routine will copy the data back into the underlying
3345: vector data structure from the array obtained with `VecGetArray()`.
3347: This routine actually zeros out the a pointer.
3349: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3350: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3351: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3352: @*/
3353: PetscErrorCode VecRestoreArray4dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3354: {
3355: void *dummy;
3357: PetscFunctionBegin;
3361: dummy = (void *)(*a + mstart);
3362: PetscCall(PetscFree(dummy));
3363: PetscCall(VecRestoreArrayWrite(x, NULL));
3364: PetscFunctionReturn(PETSC_SUCCESS);
3365: }
3367: /*@C
3368: VecGetArray2dRead - Returns a pointer to a 2d contiguous array that contains this
3369: processor's portion of the vector data. You MUST call `VecRestoreArray2dRead()`
3370: when you no longer need access to the array.
3372: Logically Collective
3374: Input Parameters:
3375: + x - the vector
3376: . m - first dimension of two dimensional array
3377: . n - second dimension of two dimensional array
3378: . mstart - first index you will use in first coordinate direction (often 0)
3379: - nstart - first index in the second coordinate direction (often 0)
3381: Output Parameter:
3382: . a - location to put pointer to the array
3384: Level: developer
3386: Notes:
3387: For a vector obtained from `DMCreateLocalVector()` mstart and nstart are likely
3388: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3389: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3390: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray2d()`.
3392: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3394: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3395: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3396: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3397: @*/
3398: PetscErrorCode VecGetArray2dRead(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
3399: {
3400: PetscInt i, N;
3401: const PetscScalar *aa;
3403: PetscFunctionBegin;
3407: PetscCall(VecGetLocalSize(x, &N));
3408: 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);
3409: PetscCall(VecGetArrayRead(x, &aa));
3411: PetscCall(PetscMalloc1(m, a));
3412: for (i = 0; i < m; i++) (*a)[i] = (PetscScalar *)aa + i * n - nstart;
3413: *a -= mstart;
3414: PetscFunctionReturn(PETSC_SUCCESS);
3415: }
3417: /*@C
3418: VecRestoreArray2dRead - Restores a vector after `VecGetArray2dRead()` has been called.
3420: Logically Collective
3422: Input Parameters:
3423: + x - the vector
3424: . m - first dimension of two dimensional array
3425: . n - second dimension of the two dimensional array
3426: . mstart - first index you will use in first coordinate direction (often 0)
3427: . nstart - first index in the second coordinate direction (often 0)
3428: - a - location of pointer to array obtained from VecGetArray2d()
3430: Level: developer
3432: Notes:
3433: For regular PETSc vectors this routine does not involve any copies. For
3434: any special vectors that do not store local vector data in a contiguous
3435: array, this routine will copy the data back into the underlying
3436: vector data structure from the array obtained with `VecGetArray()`.
3438: This routine actually zeros out the a pointer.
3440: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3441: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3442: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3443: @*/
3444: PetscErrorCode VecRestoreArray2dRead(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
3445: {
3446: void *dummy;
3448: PetscFunctionBegin;
3452: dummy = (void *)(*a + mstart);
3453: PetscCall(PetscFree(dummy));
3454: PetscCall(VecRestoreArrayRead(x, NULL));
3455: PetscFunctionReturn(PETSC_SUCCESS);
3456: }
3458: /*@C
3459: VecGetArray1dRead - Returns a pointer to a 1d contiguous array that contains this
3460: processor's portion of the vector data. You MUST call `VecRestoreArray1dRead()`
3461: when you no longer need access to the array.
3463: Logically Collective
3465: Input Parameters:
3466: + x - the vector
3467: . m - first dimension of two dimensional array
3468: - mstart - first index you will use in first coordinate direction (often 0)
3470: Output Parameter:
3471: . a - location to put pointer to the array
3473: Level: developer
3475: Notes:
3476: For a vector obtained from `DMCreateLocalVector()` mstart are likely
3477: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3478: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`.
3480: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3482: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3483: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3484: `VecGetArray2d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3485: @*/
3486: PetscErrorCode VecGetArray1dRead(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
3487: {
3488: PetscInt N;
3490: PetscFunctionBegin;
3494: PetscCall(VecGetLocalSize(x, &N));
3495: 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);
3496: PetscCall(VecGetArrayRead(x, (const PetscScalar **)a));
3497: *a -= mstart;
3498: PetscFunctionReturn(PETSC_SUCCESS);
3499: }
3501: /*@C
3502: VecRestoreArray1dRead - Restores a vector after `VecGetArray1dRead()` has been called.
3504: Logically Collective
3506: Input Parameters:
3507: + x - the vector
3508: . m - first dimension of two dimensional array
3509: . mstart - first index you will use in first coordinate direction (often 0)
3510: - a - location of pointer to array obtained from `VecGetArray1dRead()`
3512: Level: developer
3514: Notes:
3515: For regular PETSc vectors this routine does not involve any copies. For
3516: any special vectors that do not store local vector data in a contiguous
3517: array, this routine will copy the data back into the underlying
3518: vector data structure from the array obtained with `VecGetArray1dRead()`.
3520: This routine actually zeros out the a pointer.
3522: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3523: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3524: `VecGetArray1d()`, `VecRestoreArray2d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3525: @*/
3526: PetscErrorCode VecRestoreArray1dRead(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
3527: {
3528: PetscFunctionBegin;
3531: PetscCall(VecRestoreArrayRead(x, NULL));
3532: PetscFunctionReturn(PETSC_SUCCESS);
3533: }
3535: /*@C
3536: VecGetArray3dRead - Returns a pointer to a 3d contiguous array that contains this
3537: processor's portion of the vector data. You MUST call `VecRestoreArray3dRead()`
3538: when you no longer need access to the array.
3540: Logically Collective
3542: Input Parameters:
3543: + x - the vector
3544: . m - first dimension of three dimensional array
3545: . n - second dimension of three dimensional array
3546: . p - third dimension of three dimensional array
3547: . mstart - first index you will use in first coordinate direction (often 0)
3548: . nstart - first index in the second coordinate direction (often 0)
3549: - pstart - first index in the third coordinate direction (often 0)
3551: Output Parameter:
3552: . a - location to put pointer to the array
3554: Level: developer
3556: Notes:
3557: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3558: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3559: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3560: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3dRead()`.
3562: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3564: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3565: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3566: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3567: @*/
3568: PetscErrorCode VecGetArray3dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3569: {
3570: PetscInt i, N, j;
3571: const PetscScalar *aa;
3572: PetscScalar **b;
3574: PetscFunctionBegin;
3578: PetscCall(VecGetLocalSize(x, &N));
3579: 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);
3580: PetscCall(VecGetArrayRead(x, &aa));
3582: PetscCall(PetscMalloc(m * sizeof(PetscScalar **) + m * n * sizeof(PetscScalar *), a));
3583: b = (PetscScalar **)((*a) + m);
3584: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3585: for (i = 0; i < m; i++)
3586: for (j = 0; j < n; j++) b[i * n + j] = (PetscScalar *)aa + i * n * p + j * p - pstart;
3587: *a -= mstart;
3588: PetscFunctionReturn(PETSC_SUCCESS);
3589: }
3591: /*@C
3592: VecRestoreArray3dRead - Restores a vector after `VecGetArray3dRead()` has been called.
3594: Logically Collective
3596: Input Parameters:
3597: + x - the vector
3598: . m - first dimension of three dimensional array
3599: . n - second dimension of the three dimensional array
3600: . p - third dimension of the three dimensional array
3601: . mstart - first index you will use in first coordinate direction (often 0)
3602: . nstart - first index in the second coordinate direction (often 0)
3603: . pstart - first index in the third coordinate direction (often 0)
3604: - a - location of pointer to array obtained from `VecGetArray3dRead()`
3606: Level: developer
3608: Notes:
3609: For regular PETSc vectors this routine does not involve any copies. For
3610: any special vectors that do not store local vector data in a contiguous
3611: array, this routine will copy the data back into the underlying
3612: vector data structure from the array obtained with `VecGetArray()`.
3614: This routine actually zeros out the a pointer.
3616: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3617: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3618: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3619: @*/
3620: PetscErrorCode VecRestoreArray3dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3621: {
3622: void *dummy;
3624: PetscFunctionBegin;
3628: dummy = (void *)(*a + mstart);
3629: PetscCall(PetscFree(dummy));
3630: PetscCall(VecRestoreArrayRead(x, NULL));
3631: PetscFunctionReturn(PETSC_SUCCESS);
3632: }
3634: /*@C
3635: VecGetArray4dRead - Returns a pointer to a 4d contiguous array that contains this
3636: processor's portion of the vector data. You MUST call `VecRestoreArray4dRead()`
3637: when you no longer need access to the array.
3639: Logically Collective
3641: Input Parameters:
3642: + x - the vector
3643: . m - first dimension of four dimensional array
3644: . n - second dimension of four dimensional array
3645: . p - third dimension of four dimensional array
3646: . q - fourth dimension of four dimensional array
3647: . mstart - first index you will use in first coordinate direction (often 0)
3648: . nstart - first index in the second coordinate direction (often 0)
3649: . pstart - first index in the third coordinate direction (often 0)
3650: - qstart - first index in the fourth coordinate direction (often 0)
3652: Output Parameter:
3653: . a - location to put pointer to the array
3655: Level: beginner
3657: Notes:
3658: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3659: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3660: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3661: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
3663: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3665: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3666: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3667: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3668: @*/
3669: PetscErrorCode VecGetArray4dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3670: {
3671: PetscInt i, N, j, k;
3672: const PetscScalar *aa;
3673: PetscScalar ***b, **c;
3675: PetscFunctionBegin;
3679: PetscCall(VecGetLocalSize(x, &N));
3680: 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);
3681: PetscCall(VecGetArrayRead(x, &aa));
3683: PetscCall(PetscMalloc(m * sizeof(PetscScalar ***) + m * n * sizeof(PetscScalar **) + m * n * p * sizeof(PetscScalar *), a));
3684: b = (PetscScalar ***)((*a) + m);
3685: c = (PetscScalar **)(b + m * n);
3686: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3687: for (i = 0; i < m; i++)
3688: for (j = 0; j < n; j++) b[i * n + j] = c + i * n * p + j * p - pstart;
3689: for (i = 0; i < m; i++)
3690: for (j = 0; j < n; j++)
3691: 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;
3692: *a -= mstart;
3693: PetscFunctionReturn(PETSC_SUCCESS);
3694: }
3696: /*@C
3697: VecRestoreArray4dRead - Restores a vector after `VecGetArray4d()` has been called.
3699: Logically Collective
3701: Input Parameters:
3702: + x - the vector
3703: . m - first dimension of four dimensional array
3704: . n - second dimension of the four dimensional array
3705: . p - third dimension of the four dimensional array
3706: . q - fourth dimension of the four dimensional array
3707: . mstart - first index you will use in first coordinate direction (often 0)
3708: . nstart - first index in the second coordinate direction (often 0)
3709: . pstart - first index in the third coordinate direction (often 0)
3710: . qstart - first index in the fourth coordinate direction (often 0)
3711: - a - location of pointer to array obtained from `VecGetArray4dRead()`
3713: Level: beginner
3715: Notes:
3716: For regular PETSc vectors this routine does not involve any copies. For
3717: any special vectors that do not store local vector data in a contiguous
3718: array, this routine will copy the data back into the underlying
3719: vector data structure from the array obtained with `VecGetArray()`.
3721: This routine actually zeros out the a pointer.
3723: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3724: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3725: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3726: @*/
3727: PetscErrorCode VecRestoreArray4dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3728: {
3729: void *dummy;
3731: PetscFunctionBegin;
3735: dummy = (void *)(*a + mstart);
3736: PetscCall(PetscFree(dummy));
3737: PetscCall(VecRestoreArrayRead(x, NULL));
3738: PetscFunctionReturn(PETSC_SUCCESS);
3739: }
3741: #if defined(PETSC_USE_DEBUG)
3743: /*@
3744: VecLockGet - Gets the current lock status of a vector
3746: Logically Collective
3748: Input Parameter:
3749: . x - the vector
3751: Output Parameter:
3752: . state - greater than zero indicates the vector is locked for read; less then zero indicates the vector is
3753: locked for write; equal to zero means the vector is unlocked, that is, it is free to read or write.
3755: Level: advanced
3757: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPush()`, `VecLockReadPop()`
3758: @*/
3759: PetscErrorCode VecLockGet(Vec x, PetscInt *state)
3760: {
3761: PetscFunctionBegin;
3763: *state = x->lock;
3764: PetscFunctionReturn(PETSC_SUCCESS);
3765: }
3767: PetscErrorCode VecLockGetLocation(Vec x, const char *file[], const char *func[], int *line)
3768: {
3769: PetscFunctionBegin;
3774: #if !PetscDefined(HAVE_THREADSAFETY)
3775: {
3776: const int index = x->lockstack.currentsize - 1;
3778: PetscCheck(index >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Corrupted vec lock stack, have negative index %d", index);
3779: *file = x->lockstack.file[index];
3780: *func = x->lockstack.function[index];
3781: *line = x->lockstack.line[index];
3782: }
3783: #else
3784: *file = NULL;
3785: *func = NULL;
3786: *line = 0;
3787: #endif
3788: PetscFunctionReturn(PETSC_SUCCESS);
3789: }
3791: /*@
3792: VecLockReadPush - Pushes a read-only lock on a vector to prevent it from being written to
3794: Logically Collective
3796: Input Parameter:
3797: . x - the vector
3799: Level: intermediate
3801: Notes:
3802: If this is set then calls to `VecGetArray()` or `VecSetValues()` or any other routines that change the vectors values will generate an error.
3804: The call can be nested, i.e., called multiple times on the same vector, but each `VecLockReadPush()` has to have one matching
3805: `VecLockReadPop()`, which removes the latest read-only lock.
3807: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPop()`, `VecLockGet()`
3808: @*/
3809: PetscErrorCode VecLockReadPush(Vec x)
3810: {
3811: PetscFunctionBegin;
3813: 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");
3814: #if !PetscDefined(HAVE_THREADSAFETY)
3815: {
3816: const char *file, *func;
3817: int index, line;
3819: if ((index = petscstack.currentsize - 2) == -1) {
3820: // vec was locked "outside" of petsc, either in user-land or main. the error message will
3821: // now show this function as the culprit, but it will include the stacktrace
3822: file = "unknown user-file";
3823: func = "unknown_user_function";
3824: line = 0;
3825: } else {
3826: PetscCheck(index >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected petscstack, have negative index %d", index);
3827: file = petscstack.file[index];
3828: func = petscstack.function[index];
3829: line = petscstack.line[index];
3830: }
3831: PetscStackPush_Private(x->lockstack, file, func, line, petscstack.petscroutine[index], PETSC_FALSE);
3832: }
3833: #endif
3834: PetscFunctionReturn(PETSC_SUCCESS);
3835: }
3837: /*@
3838: VecLockReadPop - Pops a read-only lock from a vector
3840: Logically Collective
3842: Input Parameter:
3843: . x - the vector
3845: Level: intermediate
3847: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPush()`, `VecLockGet()`
3848: @*/
3849: PetscErrorCode VecLockReadPop(Vec x)
3850: {
3851: PetscFunctionBegin;
3853: PetscCheck(--x->lock >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Vector has been unlocked from read-only access too many times");
3854: #if !PetscDefined(HAVE_THREADSAFETY)
3855: {
3856: const char *previous = x->lockstack.function[x->lockstack.currentsize - 1];
3858: PetscStackPop_Private(x->lockstack, previous);
3859: }
3860: #endif
3861: PetscFunctionReturn(PETSC_SUCCESS);
3862: }
3864: /*@C
3865: VecLockWriteSet - Lock or unlock a vector for exclusive read/write access
3867: Logically Collective
3869: Input Parameters:
3870: + x - the vector
3871: - flg - `PETSC_TRUE` to lock the vector for exclusive read/write access; `PETSC_FALSE` to unlock it.
3873: Level: intermediate
3875: Notes:
3876: The function is useful in split-phase computations, which usually have a begin phase and an end phase.
3877: One can call `VecLockWriteSet`(x,`PETSC_TRUE`) in the begin phase to lock a vector for exclusive
3878: access, and call `VecLockWriteSet`(x,`PETSC_FALSE`) in the end phase to unlock the vector from exclusive
3879: access. In this way, one is ensured no other operations can access the vector in between. The code may like
3881: .vb
3882: VecGetArray(x,&xdata); // begin phase
3883: VecLockWriteSet(v,PETSC_TRUE);
3885: Other operations, which can not access x anymore (they can access xdata, of course)
3887: VecRestoreArray(x,&vdata); // end phase
3888: VecLockWriteSet(v,PETSC_FALSE);
3889: .ve
3891: The call can not be nested on the same vector, in other words, one can not call `VecLockWriteSet`(x,`PETSC_TRUE`)
3892: again before calling `VecLockWriteSet`(v,`PETSC_FALSE`).
3894: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPush()`, `VecLockReadPop()`, `VecLockGet()`
3895: @*/
3896: PetscErrorCode VecLockWriteSet(Vec x, PetscBool flg)
3897: {
3898: PetscFunctionBegin;
3900: if (flg) {
3901: 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");
3902: 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");
3903: x->lock = -1;
3904: } else {
3905: 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");
3906: x->lock = 0;
3907: }
3908: PetscFunctionReturn(PETSC_SUCCESS);
3909: }
3911: /*@
3912: VecLockPush - Pushes a read-only lock on a vector to prevent it from being written to
3914: Level: deprecated
3916: .seealso: [](chapter_vectors), `Vec`, `VecLockReadPush()`
3917: @*/
3918: PetscErrorCode VecLockPush(Vec x)
3919: {
3920: PetscFunctionBegin;
3921: PetscCall(VecLockReadPush(x));
3922: PetscFunctionReturn(PETSC_SUCCESS);
3923: }
3925: /*@
3926: VecLockPop - Pops a read-only lock from a vector
3928: Level: deprecated
3930: .seealso: [](chapter_vectors), `Vec`, `VecLockReadPop()`
3931: @*/
3932: PetscErrorCode VecLockPop(Vec x)
3933: {
3934: PetscFunctionBegin;
3935: PetscCall(VecLockReadPop(x));
3936: PetscFunctionReturn(PETSC_SUCCESS);
3937: }
3939: #endif