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`, `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.
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()`
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 location of val (pass `NULL` if you don't want this)
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 location of val (pass `NULL` if you don't want this location)
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
461: $ x[i] = alpha * x[i], for i=1,...,n.
463: .seealso: [](chapter_vectors), `Vec`, `VecSet()`
464: @*/
465: PetscErrorCode VecScale(Vec x, PetscScalar alpha)
466: {
467: PetscReal norms[4];
468: PetscBool flgs[4];
470: PetscFunctionBegin;
473: VecCheckAssembled(x);
474: PetscCall(VecSetErrorIfLocked(x, 1));
475: if (alpha == (PetscScalar)1.0) PetscFunctionReturn(PETSC_SUCCESS);
477: /* get current stashed norms */
478: for (PetscInt i = 0; i < 4; i++) PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], norms[i], flgs[i]));
480: PetscCall(PetscLogEventBegin(VEC_Scale, x, 0, 0, 0));
481: PetscUseTypeMethod(x, scale, alpha);
482: PetscCall(PetscLogEventEnd(VEC_Scale, x, 0, 0, 0));
484: PetscCall(PetscObjectStateIncrease((PetscObject)x));
485: /* put the scaled stashed norms back into the Vec */
486: for (PetscInt i = 0; i < 4; i++) {
487: if (flgs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[i], PetscAbsScalar(alpha) * norms[i]));
488: }
489: PetscFunctionReturn(PETSC_SUCCESS);
490: }
492: /*@
493: VecSet - Sets all components of a vector to a single scalar value.
495: Logically Collective
497: Input Parameters:
498: + x - the vector
499: - alpha - the scalar
501: Output Parameter:
502: . x - the vector
504: Level: beginner
506: Notes:
507: For a vector of dimension n, `VecSet()` computes
508: $ x[i] = alpha, for i=1,...,n,
509: so that all vector entries then equal the identical
510: scalar value, alpha. Use the more general routine
511: `VecSetValues()` to set different vector entries.
513: You CANNOT call this after you have called `VecSetValues()` but before you call
514: `VecAssemblyBegin()`
516: .seealso: [](chapter_vectors), `Vec`, `VecSetValues()`, `VecSetValuesBlocked()`, `VecSetRandom()`
517: @*/
518: PetscErrorCode VecSet(Vec x, PetscScalar alpha)
519: {
520: PetscFunctionBegin;
523: VecCheckAssembled(x);
525: PetscCall(VecSetErrorIfLocked(x, 1));
527: PetscCall(PetscLogEventBegin(VEC_Set, x, 0, 0, 0));
528: PetscUseTypeMethod(x, set, alpha);
529: PetscCall(PetscLogEventEnd(VEC_Set, x, 0, 0, 0));
530: PetscCall(PetscObjectStateIncrease((PetscObject)x));
532: /* norms can be simply set (if |alpha|*N not too large) */
534: {
535: PetscReal val = PetscAbsScalar(alpha);
536: const PetscInt N = x->map->N;
538: if (N == 0) {
539: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_1], 0.0l));
540: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_INFINITY], 0.0));
541: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_2], 0.0));
542: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_FROBENIUS], 0.0));
543: } else if (val > PETSC_MAX_REAL / N) {
544: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_INFINITY], val));
545: } else {
546: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_1], N * val));
547: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_INFINITY], val));
548: val *= PetscSqrtReal((PetscReal)N);
549: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_2], val));
550: PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_FROBENIUS], val));
551: }
552: }
553: PetscFunctionReturn(PETSC_SUCCESS);
554: }
556: /*@
557: VecAXPY - Computes `y = alpha x + y`.
559: Logically Collective
561: Input Parameters:
562: + alpha - the scalar
563: - x, y - the vectors
565: Output Parameter:
566: . y - output vector
568: Level: intermediate
570: Notes:
571: This routine is optimized for alpha of 0.0, otherwise it calls the BLAS routine
572: .vb
573: VecAXPY(y,alpha,x) y = alpha x + y
574: VecAYPX(y,beta,x) y = x + beta y
575: VecAXPBY(y,alpha,beta,x) y = alpha x + beta y
576: VecWAXPY(w,alpha,x,y) w = alpha x + y
577: VecAXPBYPCZ(w,alpha,beta,gamma,x,y) z = alpha x + beta y + gamma z
578: VecMAXPY(y,nv,alpha[],x[]) y = sum alpha[i] x[i] + y
579: .ve
581: .seealso: [](chapter_vectors), `Vec`, `VecAYPX()`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPBYPCZ()`, `VecAXPBY()`
582: @*/
583: PetscErrorCode VecAXPY(Vec y, PetscScalar alpha, Vec x)
584: {
585: PetscFunctionBegin;
590: PetscCheckSameTypeAndComm(x, 3, y, 1);
591: VecCheckSameSize(x, 3, y, 1);
592: VecCheckAssembled(x);
593: VecCheckAssembled(y);
595: if (alpha == (PetscScalar)0.0) PetscFunctionReturn(PETSC_SUCCESS);
596: PetscCall(VecSetErrorIfLocked(y, 1));
597: if (x == y) {
598: PetscCall(VecScale(y, alpha + 1.0));
599: PetscFunctionReturn(PETSC_SUCCESS);
600: }
601: PetscCall(VecLockReadPush(x));
602: PetscCall(PetscLogEventBegin(VEC_AXPY, x, y, 0, 0));
603: PetscUseTypeMethod(y, axpy, alpha, x);
604: PetscCall(PetscLogEventEnd(VEC_AXPY, x, y, 0, 0));
605: PetscCall(VecLockReadPop(x));
606: PetscCall(PetscObjectStateIncrease((PetscObject)y));
607: PetscFunctionReturn(PETSC_SUCCESS);
608: }
610: /*@
611: VecAYPX - Computes `y = x + beta y`.
613: Logically Collective
615: Input Parameters:
616: + beta - the scalar
617: . x - the unscaled vector
618: - y - the vector to be scaled
620: Output Parameter:
621: . y - output vector
623: Level: intermediate
625: Developer Note:
626: The implementation is optimized for beta of -1.0, 0.0, and 1.0
628: .seealso: [](chapter_vectors), `Vec`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBYPCZ()`, `VecAXPBY()`
629: @*/
630: PetscErrorCode VecAYPX(Vec y, PetscScalar beta, Vec x)
631: {
632: PetscFunctionBegin;
637: PetscCheckSameTypeAndComm(x, 3, y, 1);
638: VecCheckSameSize(x, 1, y, 3);
639: VecCheckAssembled(x);
640: VecCheckAssembled(y);
642: PetscCall(VecSetErrorIfLocked(y, 1));
643: if (x == y) {
644: PetscCall(VecScale(y, beta + 1.0));
645: PetscFunctionReturn(PETSC_SUCCESS);
646: }
647: PetscCall(VecLockReadPush(x));
648: if (beta == (PetscScalar)0.0) {
649: PetscCall(VecCopy(x, y));
650: } else {
651: PetscCall(PetscLogEventBegin(VEC_AYPX, x, y, 0, 0));
652: PetscUseTypeMethod(y, aypx, beta, x);
653: PetscCall(PetscLogEventEnd(VEC_AYPX, x, y, 0, 0));
654: PetscCall(PetscObjectStateIncrease((PetscObject)y));
655: }
656: PetscCall(VecLockReadPop(x));
657: PetscFunctionReturn(PETSC_SUCCESS);
658: }
660: /*@
661: VecAXPBY - Computes `y = alpha x + beta y`.
663: Logically Collective
665: Input Parameters:
666: + alpha,beta - the scalars
667: . x - the first scaled vector
668: - y - the second scaled vector
670: Output Parameter:
671: . y - output vector
673: Level: intermediate
675: Developer Note:
676: The implementation is optimized for alpha and/or beta values of 0.0 and 1.0
678: .seealso: [](chapter_vectors), `Vec`, `VecAYPX()`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBYPCZ()`
679: @*/
680: PetscErrorCode VecAXPBY(Vec y, PetscScalar alpha, PetscScalar beta, Vec x)
681: {
682: PetscFunctionBegin;
687: PetscCheckSameTypeAndComm(x, 4, y, 1);
688: VecCheckSameSize(y, 1, x, 4);
689: VecCheckAssembled(x);
690: VecCheckAssembled(y);
693: if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)1.0) PetscFunctionReturn(PETSC_SUCCESS);
694: if (x == y) {
695: PetscCall(VecScale(y, alpha + beta));
696: PetscFunctionReturn(PETSC_SUCCESS);
697: }
699: PetscCall(VecSetErrorIfLocked(y, 1));
700: PetscCall(VecLockReadPush(x));
701: PetscCall(PetscLogEventBegin(VEC_AXPY, y, x, 0, 0));
702: PetscUseTypeMethod(y, axpby, alpha, beta, x);
703: PetscCall(PetscLogEventEnd(VEC_AXPY, y, x, 0, 0));
704: PetscCall(PetscObjectStateIncrease((PetscObject)y));
705: PetscCall(VecLockReadPop(x));
706: PetscFunctionReturn(PETSC_SUCCESS);
707: }
709: /*@
710: VecAXPBYPCZ - Computes `z = alpha x + beta y + gamma z`
712: Logically Collective
714: Input Parameters:
715: + alpha,beta, gamma - the scalars
716: - x, y, z - the vectors
718: Output Parameter:
719: . z - output vector
721: Level: intermediate
723: Note:
724: `x`, `y` and `z` must be different vectors
726: Developer Note:
727: The implementation is optimized for alpha of 1.0 and gamma of 1.0 or 0.0
729: .seealso: [](chapter_vectors), `Vec`, `VecAYPX()`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBY()`
730: @*/
731: PetscErrorCode VecAXPBYPCZ(Vec z, PetscScalar alpha, PetscScalar beta, PetscScalar gamma, Vec x, Vec y)
732: {
733: PetscFunctionBegin;
740: PetscCheckSameTypeAndComm(x, 5, y, 6);
741: PetscCheckSameTypeAndComm(x, 5, z, 1);
742: VecCheckSameSize(x, 1, y, 5);
743: VecCheckSameSize(x, 1, z, 6);
744: PetscCheck(x != y && x != z, PetscObjectComm((PetscObject)x), PETSC_ERR_ARG_IDN, "x, y, and z must be different vectors");
745: PetscCheck(y != z, PetscObjectComm((PetscObject)y), PETSC_ERR_ARG_IDN, "x, y, and z must be different vectors");
746: VecCheckAssembled(x);
747: VecCheckAssembled(y);
748: VecCheckAssembled(z);
752: if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)0.0 && gamma == (PetscScalar)1.0) PetscFunctionReturn(PETSC_SUCCESS);
754: PetscCall(VecSetErrorIfLocked(z, 1));
755: PetscCall(VecLockReadPush(x));
756: PetscCall(VecLockReadPush(y));
757: PetscCall(PetscLogEventBegin(VEC_AXPBYPCZ, x, y, z, 0));
758: PetscUseTypeMethod(z, axpbypcz, alpha, beta, gamma, x, y);
759: PetscCall(PetscLogEventEnd(VEC_AXPBYPCZ, x, y, z, 0));
760: PetscCall(PetscObjectStateIncrease((PetscObject)z));
761: PetscCall(VecLockReadPop(x));
762: PetscCall(VecLockReadPop(y));
763: PetscFunctionReturn(PETSC_SUCCESS);
764: }
766: /*@
767: VecWAXPY - Computes `w = alpha x + y`.
769: Logically Collective
771: Input Parameters:
772: + alpha - the scalar
773: - x, y - the vectors
775: Output Parameter:
776: . w - the result
778: Level: intermediate
780: Note:
781: `w` cannot be either `x` or `y`, but `x` and `y` can be the same
783: Developer Note:
784: The implementation is optimized for alpha of -1.0, 0.0, and 1.0
786: .seealso: [](chapter_vectors), `Vec`, `VecAXPY()`, `VecAYPX()`, `VecAXPBY()`, `VecMAXPY()`, `VecAXPBYPCZ()`
787: @*/
788: PetscErrorCode VecWAXPY(Vec w, PetscScalar alpha, Vec x, Vec y)
789: {
790: PetscFunctionBegin;
797: PetscCheckSameTypeAndComm(x, 3, y, 4);
798: PetscCheckSameTypeAndComm(y, 4, w, 1);
799: VecCheckSameSize(x, 3, y, 4);
800: VecCheckSameSize(x, 3, w, 1);
801: PetscCheck(w != y, PETSC_COMM_SELF, PETSC_ERR_SUP, "Result vector w cannot be same as input vector y, suggest VecAXPY()");
802: PetscCheck(w != x, PETSC_COMM_SELF, PETSC_ERR_SUP, "Result vector w cannot be same as input vector x, suggest VecAYPX()");
803: VecCheckAssembled(x);
804: VecCheckAssembled(y);
806: PetscCall(VecSetErrorIfLocked(w, 1));
808: PetscCall(VecLockReadPush(x));
809: PetscCall(VecLockReadPush(y));
810: if (alpha == (PetscScalar)0.0) {
811: PetscCall(VecCopy(y, w));
812: } else {
813: PetscCall(PetscLogEventBegin(VEC_WAXPY, x, y, w, 0));
814: PetscUseTypeMethod(w, waxpy, alpha, x, y);
815: PetscCall(PetscLogEventEnd(VEC_WAXPY, x, y, w, 0));
816: PetscCall(PetscObjectStateIncrease((PetscObject)w));
817: }
818: PetscCall(VecLockReadPop(x));
819: PetscCall(VecLockReadPop(y));
820: PetscFunctionReturn(PETSC_SUCCESS);
821: }
823: /*@C
824: VecSetValues - Inserts or adds values into certain locations of a vector.
826: Not Collective
828: Input Parameters:
829: + x - vector to insert in
830: . ni - number of elements to add
831: . ix - indices where to add
832: . y - array of values
833: - iora - either `INSERT_VALUES` or `ADD_VALUES`, where
834: `ADD_VALUES` adds values to any existing entries, and
835: `INSERT_VALUES` replaces existing entries with new values
837: Level: beginner
839: Notes:
840: `VecSetValues()` sets x[ix[i]] = y[i], for i=0,...,ni-1.
842: Calls to `VecSetValues()` with the `INSERT_VALUES` and `ADD_VALUES`
843: options cannot be mixed without intervening calls to the assembly
844: routines.
846: These values may be cached, so `VecAssemblyBegin()` and `VecAssemblyEnd()`
847: MUST be called after all calls to `VecSetValues()` have been completed.
849: VecSetValues() uses 0-based indices in Fortran as well as in C.
851: If you call `VecSetOption`(x, `VEC_IGNORE_NEGATIVE_INDICES`,`PETSC_TRUE`),
852: negative indices may be passed in ix. These rows are
853: simply ignored. This allows easily inserting element load matrices
854: with homogeneous Dirchlet boundary conditions that you don't want represented
855: in the vector.
857: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValuesLocal()`,
858: `VecSetValue()`, `VecSetValuesBlocked()`, `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `VecGetValues()`
859: @*/
860: PetscErrorCode VecSetValues(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
861: {
862: PetscFunctionBeginHot;
864: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
869: PetscCall(PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0));
870: PetscUseTypeMethod(x, setvalues, ni, ix, y, iora);
871: PetscCall(PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0));
872: PetscCall(PetscObjectStateIncrease((PetscObject)x));
873: PetscFunctionReturn(PETSC_SUCCESS);
874: }
876: /*@C
877: VecGetValues - Gets values from certain locations of a vector. Currently
878: can only get values on the same processor
880: Not Collective
882: Input Parameters:
883: + x - vector to get values from
884: . ni - number of elements to get
885: - ix - indices where to get them from (in global 1d numbering)
887: Output Parameter:
888: . y - array of values
890: Level: beginner
892: Notes:
893: The user provides the allocated array y; it is NOT allocated in this routine
895: `VecGetValues()` gets y[i] = x[ix[i]], for i=0,...,ni-1.
897: `VecAssemblyBegin()` and `VecAssemblyEnd()` MUST be called before calling this if `VecSetValues()` or related routine has been called
899: VecGetValues() uses 0-based indices in Fortran as well as in C.
901: If you call `VecSetOption`(x, `VEC_IGNORE_NEGATIVE_INDICES`,`PETSC_TRUE`),
902: negative indices may be passed in ix. These rows are
903: simply ignored.
905: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`
906: @*/
907: PetscErrorCode VecGetValues(Vec x, PetscInt ni, const PetscInt ix[], PetscScalar y[])
908: {
909: PetscFunctionBegin;
911: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
915: VecCheckAssembled(x);
916: PetscUseTypeMethod(x, getvalues, ni, ix, y);
917: PetscFunctionReturn(PETSC_SUCCESS);
918: }
920: /*@C
921: VecSetValuesBlocked - Inserts or adds blocks of values into certain locations of a vector.
923: Not Collective
925: Input Parameters:
926: + x - vector to insert in
927: . ni - number of blocks to add
928: . ix - indices where to add in block count, rather than element count
929: . y - array of values
930: - iora - either `INSERT_VALUES` or `ADD_VALUES`, where
931: `ADD_VALUES` adds values to any existing entries, and
932: `INSERT_VALUES` replaces existing entries with new values
934: Level: intermediate
936: Notes:
937: `VecSetValuesBlocked()` sets x[bs*ix[i]+j] = y[bs*i+j],
938: for j=0,...,bs-1, for i=0,...,ni-1. where bs was set with VecSetBlockSize().
940: Calls to `VecSetValuesBlocked()` with the `INSERT_VALUES` and `ADD_VALUES`
941: options cannot be mixed without intervening calls to the assembly
942: routines.
944: These values may be cached, so `VecAssemblyBegin()` and `VecAssemblyEnd()`
945: MUST be called after all calls to `VecSetValuesBlocked()` have been completed.
947: `VecSetValuesBlocked()` uses 0-based indices in Fortran as well as in C.
949: Negative indices may be passed in ix, these rows are
950: simply ignored. This allows easily inserting element load matrices
951: with homogeneous Dirchlet boundary conditions that you don't want represented
952: in the vector.
954: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValuesBlockedLocal()`,
955: `VecSetValues()`
956: @*/
957: PetscErrorCode VecSetValuesBlocked(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
958: {
959: PetscFunctionBeginHot;
961: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
966: PetscCall(PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0));
967: PetscUseTypeMethod(x, setvaluesblocked, ni, ix, y, iora);
968: PetscCall(PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0));
969: PetscCall(PetscObjectStateIncrease((PetscObject)x));
970: PetscFunctionReturn(PETSC_SUCCESS);
971: }
973: /*@C
974: VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
975: using a local ordering of the nodes.
977: Not Collective
979: Input Parameters:
980: + x - vector to insert in
981: . ni - number of elements to add
982: . ix - indices where to add
983: . y - array of values
984: - iora - either `INSERT_VALUES` or `ADD_VALUES`, where
985: `ADD_VALUES` adds values to any existing entries, and
986: `INSERT_VALUES` replaces existing entries with new values
988: Level: intermediate
990: Notes:
991: `VecSetValuesLocal()` sets x[ix[i]] = y[i], for i=0,...,ni-1.
993: Calls to `VecSetValues()` with the `INSERT_VALUES` and `ADD_VALUES`
994: options cannot be mixed without intervening calls to the assembly
995: routines.
997: These values may be cached, so `VecAssemblyBegin()` and `VecAssemblyEnd()`
998: MUST be called after all calls to `VecSetValuesLocal()` have been completed.
1000: `VecSetValuesLocal()` uses 0-based indices in Fortran as well as in C.
1002: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`, `VecSetLocalToGlobalMapping()`,
1003: `VecSetValuesBlockedLocal()`
1004: @*/
1005: PetscErrorCode VecSetValuesLocal(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
1006: {
1007: PetscInt lixp[128], *lix = lixp;
1009: PetscFunctionBeginHot;
1011: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
1016: PetscCall(PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0));
1017: if (!x->ops->setvalueslocal) {
1018: if (x->map->mapping) {
1019: if (ni > 128) PetscCall(PetscMalloc1(ni, &lix));
1020: PetscCall(ISLocalToGlobalMappingApply(x->map->mapping, ni, (PetscInt *)ix, lix));
1021: PetscUseTypeMethod(x, setvalues, ni, lix, y, iora);
1022: if (ni > 128) PetscCall(PetscFree(lix));
1023: } else PetscUseTypeMethod(x, setvalues, ni, ix, y, iora);
1024: } else PetscUseTypeMethod(x, setvalueslocal, ni, ix, y, iora);
1025: PetscCall(PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0));
1026: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1027: PetscFunctionReturn(PETSC_SUCCESS);
1028: }
1030: /*@
1031: VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
1032: using a local ordering of the nodes.
1034: Not Collective
1036: Input Parameters:
1037: + x - vector to insert in
1038: . ni - number of blocks to add
1039: . ix - indices where to add in block count, not element count
1040: . y - array of values
1041: - iora - either `INSERT_VALUES` or `ADD_VALUES`, where
1042: `ADD_VALUES` adds values to any existing entries, and
1043: `INSERT_VALUES` replaces existing entries with new values
1045: Level: intermediate
1047: Notes:
1048: `VecSetValuesBlockedLocal()` sets x[bs*ix[i]+j] = y[bs*i+j],
1049: for j=0,..bs-1, for i=0,...,ni-1, where bs has been set with `VecSetBlockSize()`.
1051: Calls to `VecSetValuesBlockedLocal()` with the `INSERT_VALUES` and `ADD_VALUES`
1052: options cannot be mixed without intervening calls to the assembly
1053: routines.
1055: These values may be cached, so `VecAssemblyBegin()` and `VecAssemblyEnd()`
1056: MUST be called after all calls to `VecSetValuesBlockedLocal()` have been completed.
1058: `VecSetValuesBlockedLocal()` uses 0-based indices in Fortran as well as in C.
1060: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`, `VecSetValuesBlocked()`,
1061: `VecSetLocalToGlobalMapping()`
1062: @*/
1063: PetscErrorCode VecSetValuesBlockedLocal(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
1064: {
1065: PetscInt lixp[128], *lix = lixp;
1067: PetscFunctionBeginHot;
1069: if (!ni) PetscFunctionReturn(PETSC_SUCCESS);
1073: PetscCall(PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0));
1074: if (x->map->mapping) {
1075: if (ni > 128) PetscCall(PetscMalloc1(ni, &lix));
1076: PetscCall(ISLocalToGlobalMappingApplyBlock(x->map->mapping, ni, (PetscInt *)ix, lix));
1077: PetscUseTypeMethod(x, setvaluesblocked, ni, lix, y, iora);
1078: if (ni > 128) PetscCall(PetscFree(lix));
1079: } else {
1080: PetscUseTypeMethod(x, setvaluesblocked, ni, ix, y, iora);
1081: }
1082: PetscCall(PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0));
1083: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1084: PetscFunctionReturn(PETSC_SUCCESS);
1085: }
1087: static PetscErrorCode VecMXDot_Private(Vec x, PetscInt nv, const Vec y[], PetscScalar result[], PetscErrorCode (*mxdot)(Vec, PetscInt, const Vec[], PetscScalar[]), PetscLogEvent event)
1088: {
1089: PetscFunctionBegin;
1092: VecCheckAssembled(x);
1094: if (!nv) PetscFunctionReturn(PETSC_SUCCESS);
1096: for (PetscInt i = 0; i < nv; ++i) {
1099: PetscCheckSameTypeAndComm(x, 1, y[i], 3);
1100: VecCheckSameSize(x, 1, y[i], 3);
1101: VecCheckAssembled(y[i]);
1102: PetscCall(VecLockReadPush(y[i]));
1103: }
1107: PetscCall(VecLockReadPush(x));
1108: PetscCall(PetscLogEventBegin(event, x, *y, 0, 0));
1109: PetscCall((*mxdot)(x, nv, y, result));
1110: PetscCall(PetscLogEventEnd(event, x, *y, 0, 0));
1111: PetscCall(VecLockReadPop(x));
1112: for (PetscInt i = 0; i < nv; ++i) PetscCall(VecLockReadPop(y[i]));
1113: PetscFunctionReturn(PETSC_SUCCESS);
1114: }
1116: /*@
1117: VecMTDot - Computes indefinite vector multiple dot products.
1118: That is, it does NOT use the complex conjugate.
1120: Collective
1122: Input Parameters:
1123: + x - one vector
1124: . nv - number of vectors
1125: - y - array of vectors. Note that vectors are pointers
1127: Output Parameter:
1128: . val - array of the dot products
1130: Level: intermediate
1132: Notes for Users of Complex Numbers:
1133: For complex vectors, `VecMTDot()` computes the indefinite form
1134: $ val = (x,y) = y^T x,
1135: where y^T denotes the transpose of y.
1137: Use `VecMDot()` for the inner product
1138: $ val = (x,y) = y^H x,
1139: where y^H denotes the conjugate transpose of y.
1141: .seealso: [](chapter_vectors), `Vec`, `VecMDot()`, `VecTDot()`
1142: @*/
1143: PetscErrorCode VecMTDot(Vec x, PetscInt nv, const Vec y[], PetscScalar val[])
1144: {
1145: PetscFunctionBegin;
1147: PetscCall(VecMXDot_Private(x, nv, y, val, x->ops->mtdot, VEC_MTDot));
1148: PetscFunctionReturn(PETSC_SUCCESS);
1149: }
1151: /*@
1152: VecMDot - Computes vector multiple dot products.
1154: Collective
1156: Input Parameters:
1157: + x - one vector
1158: . nv - number of vectors
1159: - y - array of vectors.
1161: Output Parameter:
1162: . val - array of the dot products (does not allocate the array)
1164: Level: intermediate
1166: Notes for Users of Complex Numbers:
1167: For complex vectors, `VecMDot()` computes
1168: $ val = (x,y) = y^H x,
1169: where y^H denotes the conjugate transpose of y.
1171: Use `VecMTDot()` for the indefinite form
1172: $ val = (x,y) = y^T x,
1173: where y^T denotes the transpose of y.
1175: .seealso: [](chapter_vectors), `Vec`, `VecMTDot()`, `VecDot()`
1176: @*/
1177: PetscErrorCode VecMDot(Vec x, PetscInt nv, const Vec y[], PetscScalar val[])
1178: {
1179: PetscFunctionBegin;
1181: PetscCall(VecMXDot_Private(x, nv, y, val, x->ops->mdot, VEC_MDot));
1182: PetscFunctionReturn(PETSC_SUCCESS);
1183: }
1185: /*@
1186: VecMAXPY - Computes `y = y + sum alpha[i] x[i]`
1188: Logically Collective
1190: Input Parameters:
1191: + nv - number of scalars and x-vectors
1192: . alpha - array of scalars
1193: . y - one vector
1194: - x - array of vectors
1196: Level: intermediate
1198: Note:
1199: `y` cannot be any of the `x` vectors
1201: .seealso: [](chapter_vectors), `Vec`, `VecAYPX()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBYPCZ()`, `VecAXPBY()`
1202: @*/
1203: PetscErrorCode VecMAXPY(Vec y, PetscInt nv, const PetscScalar alpha[], Vec x[])
1204: {
1205: PetscFunctionBegin;
1207: VecCheckAssembled(y);
1209: PetscCall(VecSetErrorIfLocked(y, 1));
1210: PetscCheck(nv >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of vectors (given %" PetscInt_FMT ") cannot be negative", nv);
1211: if (nv) {
1212: PetscInt zeros = 0;
1216: for (PetscInt i = 0; i < nv; ++i) {
1220: PetscCheckSameTypeAndComm(y, 1, x[i], 4);
1221: VecCheckSameSize(y, 1, x[i], 4);
1222: PetscCheck(y != x[i], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Array of vectors 'x' cannot contain y, found x[%" PetscInt_FMT "] == y", i);
1223: VecCheckAssembled(x[i]);
1224: PetscCall(VecLockReadPush(x[i]));
1225: zeros += alpha[i] == (PetscScalar)0.0;
1226: }
1228: if (zeros < nv) {
1229: PetscCall(PetscLogEventBegin(VEC_MAXPY, y, *x, 0, 0));
1230: PetscUseTypeMethod(y, maxpy, nv, alpha, x);
1231: PetscCall(PetscLogEventEnd(VEC_MAXPY, y, *x, 0, 0));
1232: PetscCall(PetscObjectStateIncrease((PetscObject)y));
1233: }
1235: for (PetscInt i = 0; i < nv; ++i) PetscCall(VecLockReadPop(x[i]));
1236: }
1237: PetscFunctionReturn(PETSC_SUCCESS);
1238: }
1240: /*@
1241: VecConcatenate - Creates a new vector that is a vertical concatenation of all the given array of vectors
1242: in the order they appear in the array. The concatenated vector resides on the same
1243: communicator and is the same type as the source vectors.
1245: Collective
1247: Input Parameters:
1248: + nx - number of vectors to be concatenated
1249: - X - array containing the vectors to be concatenated in the order of concatenation
1251: Output Parameters:
1252: + Y - concatenated vector
1253: - x_is - array of index sets corresponding to the concatenated components of Y (`NULL` if not needed)
1255: Level: advanced
1257: Notes:
1258: Concatenation is similar to the functionality of a `VECNEST` object; they both represent combination of
1259: different vector spaces. However, concatenated vectors do not store any information about their
1260: sub-vectors and own their own data. Consequently, this function provides index sets to enable the
1261: manipulation of data in the concatenated vector that corresponds to the original components at creation.
1263: This is a useful tool for outer loop algorithms, particularly constrained optimizers, where the solver
1264: has to operate on combined vector spaces and cannot utilize `VECNEST` objects due to incompatibility with
1265: bound projections.
1267: .seealso: [](chapter_vectors), `Vec`, `VECNEST`, `VECSCATTER`, `VecScatterCreate()`
1268: @*/
1269: PetscErrorCode VecConcatenate(PetscInt nx, const Vec X[], Vec *Y, IS *x_is[])
1270: {
1271: MPI_Comm comm;
1272: VecType vec_type;
1273: Vec Ytmp, Xtmp;
1274: IS *is_tmp;
1275: PetscInt i, shift = 0, Xnl, Xng, Xbegin;
1277: PetscFunctionBegin;
1283: if ((*X)->ops->concatenate) {
1284: /* use the dedicated concatenation function if available */
1285: PetscCall((*(*X)->ops->concatenate)(nx, X, Y, x_is));
1286: } else {
1287: /* loop over vectors and start creating IS */
1288: comm = PetscObjectComm((PetscObject)(*X));
1289: PetscCall(VecGetType(*X, &vec_type));
1290: PetscCall(PetscMalloc1(nx, &is_tmp));
1291: for (i = 0; i < nx; i++) {
1292: PetscCall(VecGetSize(X[i], &Xng));
1293: PetscCall(VecGetLocalSize(X[i], &Xnl));
1294: PetscCall(VecGetOwnershipRange(X[i], &Xbegin, NULL));
1295: PetscCall(ISCreateStride(comm, Xnl, shift + Xbegin, 1, &is_tmp[i]));
1296: shift += Xng;
1297: }
1298: /* create the concatenated vector */
1299: PetscCall(VecCreate(comm, &Ytmp));
1300: PetscCall(VecSetType(Ytmp, vec_type));
1301: PetscCall(VecSetSizes(Ytmp, PETSC_DECIDE, shift));
1302: PetscCall(VecSetUp(Ytmp));
1303: /* copy data from X array to Y and return */
1304: for (i = 0; i < nx; i++) {
1305: PetscCall(VecGetSubVector(Ytmp, is_tmp[i], &Xtmp));
1306: PetscCall(VecCopy(X[i], Xtmp));
1307: PetscCall(VecRestoreSubVector(Ytmp, is_tmp[i], &Xtmp));
1308: }
1309: *Y = Ytmp;
1310: if (x_is) {
1311: *x_is = is_tmp;
1312: } else {
1313: for (i = 0; i < nx; i++) PetscCall(ISDestroy(&is_tmp[i]));
1314: PetscCall(PetscFree(is_tmp));
1315: }
1316: }
1317: PetscFunctionReturn(PETSC_SUCCESS);
1318: }
1320: /* A helper function for VecGetSubVector to check if we can implement it with no-copy (i.e. the subvector shares
1321: memory with the original vector), and the block size of the subvector.
1323: Input Parameters:
1324: + X - the original vector
1325: - is - the index set of the subvector
1327: Output Parameters:
1328: + contig - PETSC_TRUE if the index set refers to contiguous entries on this process, else PETSC_FALSE
1329: . start - start of contiguous block, as an offset from the start of the ownership range of the original vector
1330: - blocksize - the block size of the subvector
1332: */
1333: PetscErrorCode VecGetSubVectorContiguityAndBS_Private(Vec X, IS is, PetscBool *contig, PetscInt *start, PetscInt *blocksize)
1334: {
1335: PetscInt gstart, gend, lstart;
1336: PetscBool red[2] = {PETSC_TRUE /*contiguous*/, PETSC_TRUE /*validVBS*/};
1337: PetscInt n, N, ibs, vbs, bs = -1;
1339: PetscFunctionBegin;
1340: PetscCall(ISGetLocalSize(is, &n));
1341: PetscCall(ISGetSize(is, &N));
1342: PetscCall(ISGetBlockSize(is, &ibs));
1343: PetscCall(VecGetBlockSize(X, &vbs));
1344: PetscCall(VecGetOwnershipRange(X, &gstart, &gend));
1345: PetscCall(ISContiguousLocal(is, gstart, gend, &lstart, &red[0]));
1346: /* block size is given by IS if ibs > 1; otherwise, check the vector */
1347: if (ibs > 1) {
1348: PetscCall(MPIU_Allreduce(MPI_IN_PLACE, red, 1, MPIU_BOOL, MPI_LAND, PetscObjectComm((PetscObject)is)));
1349: bs = ibs;
1350: } else {
1351: if (n % vbs || vbs == 1) red[1] = PETSC_FALSE; /* this process invalidate the collectiveness of block size */
1352: PetscCall(MPIU_Allreduce(MPI_IN_PLACE, red, 2, MPIU_BOOL, MPI_LAND, PetscObjectComm((PetscObject)is)));
1353: if (red[0] && red[1]) bs = vbs; /* all processes have a valid block size and the access will be contiguous */
1354: }
1356: *contig = red[0];
1357: *start = lstart;
1358: *blocksize = bs;
1359: PetscFunctionReturn(PETSC_SUCCESS);
1360: }
1362: /* A helper function for VecGetSubVector, to be used when we have to build a standalone subvector through VecScatter
1364: Input Parameters:
1365: + X - the original vector
1366: . is - the index set of the subvector
1367: - bs - the block size of the subvector, gotten from VecGetSubVectorContiguityAndBS_Private()
1369: Output Parameters:
1370: . Z - the subvector, which will compose the VecScatter context on output
1371: */
1372: PetscErrorCode VecGetSubVectorThroughVecScatter_Private(Vec X, IS is, PetscInt bs, Vec *Z)
1373: {
1374: PetscInt n, N;
1375: VecScatter vscat;
1376: Vec Y;
1378: PetscFunctionBegin;
1379: PetscCall(ISGetLocalSize(is, &n));
1380: PetscCall(ISGetSize(is, &N));
1381: PetscCall(VecCreate(PetscObjectComm((PetscObject)is), &Y));
1382: PetscCall(VecSetSizes(Y, n, N));
1383: PetscCall(VecSetBlockSize(Y, bs));
1384: PetscCall(VecSetType(Y, ((PetscObject)X)->type_name));
1385: PetscCall(VecScatterCreate(X, is, Y, NULL, &vscat));
1386: PetscCall(VecScatterBegin(vscat, X, Y, INSERT_VALUES, SCATTER_FORWARD));
1387: PetscCall(VecScatterEnd(vscat, X, Y, INSERT_VALUES, SCATTER_FORWARD));
1388: PetscCall(PetscObjectCompose((PetscObject)Y, "VecGetSubVector_Scatter", (PetscObject)vscat));
1389: PetscCall(VecScatterDestroy(&vscat));
1390: *Z = Y;
1391: PetscFunctionReturn(PETSC_SUCCESS);
1392: }
1394: /*@
1395: VecGetSubVector - Gets a vector representing part of another vector
1397: Collective
1399: Input Parameters:
1400: + X - vector from which to extract a subvector
1401: - is - index set representing portion of X to extract
1403: Output Parameter:
1404: . Y - subvector corresponding to is
1406: Level: advanced
1408: Notes:
1409: The subvector `Y` should be returned with `VecRestoreSubVector()`.
1410: `X` and must be defined on the same communicator
1412: This function may return a subvector without making a copy, therefore it is not safe to use the original vector while
1413: modifying the subvector. Other non-overlapping subvectors can still be obtained from X using this function.
1414: The resulting subvector inherits the block size from the IS if greater than one. Otherwise, the block size is guessed from the block size of the original vec.
1416: .seealso: [](chapter_vectors), `Vec`, `IS`, `VECNEST`, `MatCreateSubMatrix()`
1417: @*/
1418: PetscErrorCode VecGetSubVector(Vec X, IS is, Vec *Y)
1419: {
1420: Vec Z;
1422: PetscFunctionBegin;
1425: PetscCheckSameComm(X, 1, is, 2);
1427: if (X->ops->getsubvector) {
1428: PetscUseTypeMethod(X, getsubvector, is, &Z);
1429: } else { /* Default implementation currently does no caching */
1430: PetscBool contig;
1431: PetscInt n, N, start, bs;
1433: PetscCall(ISGetLocalSize(is, &n));
1434: PetscCall(ISGetSize(is, &N));
1435: PetscCall(VecGetSubVectorContiguityAndBS_Private(X, is, &contig, &start, &bs));
1436: if (contig) { /* We can do a no-copy implementation */
1437: const PetscScalar *x;
1438: PetscInt state = 0;
1439: PetscBool isstd, iscuda, iship;
1441: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &isstd, VECSEQ, VECMPI, VECSTANDARD, ""));
1442: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &iscuda, VECSEQCUDA, VECMPICUDA, ""));
1443: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &iship, VECSEQHIP, VECMPIHIP, ""));
1444: if (iscuda) {
1445: #if defined(PETSC_HAVE_CUDA)
1446: const PetscScalar *x_d;
1447: PetscMPIInt size;
1448: PetscOffloadMask flg;
1450: PetscCall(VecCUDAGetArrays_Private(X, &x, &x_d, &flg));
1451: PetscCheck(flg != PETSC_OFFLOAD_UNALLOCATED, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not for PETSC_OFFLOAD_UNALLOCATED");
1452: PetscCheck(!n || x || x_d, PETSC_COMM_SELF, PETSC_ERR_SUP, "Missing vector data");
1453: if (x) x += start;
1454: if (x_d) x_d += start;
1455: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)X), &size));
1456: if (size == 1) {
1457: PetscCall(VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)X), bs, n, x, x_d, &Z));
1458: } else {
1459: PetscCall(VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)X), bs, n, N, x, x_d, &Z));
1460: }
1461: Z->offloadmask = flg;
1462: #endif
1463: } else if (iship) {
1464: #if defined(PETSC_HAVE_HIP)
1465: const PetscScalar *x_d;
1466: PetscMPIInt size;
1467: PetscOffloadMask flg;
1469: PetscCall(VecHIPGetArrays_Private(X, &x, &x_d, &flg));
1470: PetscCheck(flg != PETSC_OFFLOAD_UNALLOCATED, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not for PETSC_OFFLOAD_UNALLOCATED");
1471: PetscCheck(!n || x || x_d, PETSC_COMM_SELF, PETSC_ERR_SUP, "Missing vector data");
1472: if (x) x += start;
1473: if (x_d) x_d += start;
1474: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)X), &size));
1475: if (size == 1) {
1476: PetscCall(VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)X), bs, n, x, x_d, &Z));
1477: } else {
1478: PetscCall(VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)X), bs, n, N, x, x_d, &Z));
1479: }
1480: Z->offloadmask = flg;
1481: #endif
1482: } else if (isstd) {
1483: PetscMPIInt size;
1485: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)X), &size));
1486: PetscCall(VecGetArrayRead(X, &x));
1487: if (x) x += start;
1488: if (size == 1) {
1489: PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)X), bs, n, x, &Z));
1490: } else {
1491: PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)X), bs, n, N, x, &Z));
1492: }
1493: PetscCall(VecRestoreArrayRead(X, &x));
1494: } else { /* default implementation: use place array */
1495: PetscCall(VecGetArrayRead(X, &x));
1496: PetscCall(VecCreate(PetscObjectComm((PetscObject)X), &Z));
1497: PetscCall(VecSetType(Z, ((PetscObject)X)->type_name));
1498: PetscCall(VecSetSizes(Z, n, N));
1499: PetscCall(VecSetBlockSize(Z, bs));
1500: PetscCall(VecPlaceArray(Z, x ? x + start : NULL));
1501: PetscCall(VecRestoreArrayRead(X, &x));
1502: }
1504: /* this is relevant only in debug mode */
1505: PetscCall(VecLockGet(X, &state));
1506: if (state) PetscCall(VecLockReadPush(Z));
1507: Z->ops->placearray = NULL;
1508: Z->ops->replacearray = NULL;
1509: } else { /* Have to create a scatter and do a copy */
1510: PetscCall(VecGetSubVectorThroughVecScatter_Private(X, is, bs, &Z));
1511: }
1512: }
1513: /* Record the state when the subvector was gotten so we know whether its values need to be put back */
1514: if (VecGetSubVectorSavedStateId < 0) PetscCall(PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId));
1515: PetscCall(PetscObjectComposedDataSetInt((PetscObject)Z, VecGetSubVectorSavedStateId, 1));
1516: *Y = Z;
1517: PetscFunctionReturn(PETSC_SUCCESS);
1518: }
1520: /*@
1521: VecRestoreSubVector - Restores a subvector extracted using `VecGetSubVector()`
1523: Collective
1525: Input Parameters:
1526: + X - vector from which subvector was obtained
1527: . is - index set representing the subset of `X`
1528: - Y - subvector being restored
1530: Level: advanced
1532: .seealso: [](chapter_vectors), `Vec`, `IS`, `VecGetSubVector()`
1533: @*/
1534: PetscErrorCode VecRestoreSubVector(Vec X, IS is, Vec *Y)
1535: {
1536: PETSC_UNUSED PetscObjectState dummystate = 0;
1537: PetscBool unchanged;
1539: PetscFunctionBegin;
1542: PetscCheckSameComm(X, 1, is, 2);
1546: if (X->ops->restoresubvector) PetscUseTypeMethod(X, restoresubvector, is, Y);
1547: else {
1548: PetscCall(PetscObjectComposedDataGetInt((PetscObject)*Y, VecGetSubVectorSavedStateId, dummystate, unchanged));
1549: if (!unchanged) { /* If Y's state has not changed since VecGetSubVector(), we only need to destroy Y */
1550: VecScatter scatter;
1551: PetscInt state;
1553: PetscCall(VecLockGet(X, &state));
1554: PetscCheck(state == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Vec X is locked for read-only or read/write access");
1556: PetscCall(PetscObjectQuery((PetscObject)*Y, "VecGetSubVector_Scatter", (PetscObject *)&scatter));
1557: if (scatter) {
1558: PetscCall(VecScatterBegin(scatter, *Y, X, INSERT_VALUES, SCATTER_REVERSE));
1559: PetscCall(VecScatterEnd(scatter, *Y, X, INSERT_VALUES, SCATTER_REVERSE));
1560: } else {
1561: PetscBool iscuda, iship;
1562: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &iscuda, VECSEQCUDA, VECMPICUDA, ""));
1563: PetscCall(PetscObjectTypeCompareAny((PetscObject)X, &iship, VECSEQHIP, VECMPIHIP, ""));
1565: if (iscuda) {
1566: #if defined(PETSC_HAVE_CUDA)
1567: PetscOffloadMask ymask = (*Y)->offloadmask;
1569: /* The offloadmask of X dictates where to move memory
1570: If X GPU data is valid, then move Y data on GPU if needed
1571: Otherwise, move back to the CPU */
1572: switch (X->offloadmask) {
1573: case PETSC_OFFLOAD_BOTH:
1574: if (ymask == PETSC_OFFLOAD_CPU) {
1575: PetscCall(VecCUDAResetArray(*Y));
1576: } else if (ymask == PETSC_OFFLOAD_GPU) {
1577: X->offloadmask = PETSC_OFFLOAD_GPU;
1578: }
1579: break;
1580: case PETSC_OFFLOAD_GPU:
1581: if (ymask == PETSC_OFFLOAD_CPU) PetscCall(VecCUDAResetArray(*Y));
1582: break;
1583: case PETSC_OFFLOAD_CPU:
1584: if (ymask == PETSC_OFFLOAD_GPU) PetscCall(VecResetArray(*Y));
1585: break;
1586: case PETSC_OFFLOAD_UNALLOCATED:
1587: case PETSC_OFFLOAD_KOKKOS:
1588: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "This should not happen");
1589: }
1590: #endif
1591: } else if (iship) {
1592: #if defined(PETSC_HAVE_HIP)
1593: PetscOffloadMask ymask = (*Y)->offloadmask;
1595: /* The offloadmask of X dictates where to move memory
1596: If X GPU data is valid, then move Y data on GPU if needed
1597: Otherwise, move back to the CPU */
1598: switch (X->offloadmask) {
1599: case PETSC_OFFLOAD_BOTH:
1600: if (ymask == PETSC_OFFLOAD_CPU) {
1601: PetscCall(VecHIPResetArray(*Y));
1602: } else if (ymask == PETSC_OFFLOAD_GPU) {
1603: X->offloadmask = PETSC_OFFLOAD_GPU;
1604: }
1605: break;
1606: case PETSC_OFFLOAD_GPU:
1607: if (ymask == PETSC_OFFLOAD_CPU) PetscCall(VecHIPResetArray(*Y));
1608: break;
1609: case PETSC_OFFLOAD_CPU:
1610: if (ymask == PETSC_OFFLOAD_GPU) PetscCall(VecResetArray(*Y));
1611: break;
1612: case PETSC_OFFLOAD_UNALLOCATED:
1613: case PETSC_OFFLOAD_KOKKOS:
1614: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "This should not happen");
1615: }
1616: #endif
1617: } else {
1618: /* If OpenCL vecs updated the device memory, this triggers a copy on the CPU */
1619: PetscCall(VecResetArray(*Y));
1620: }
1621: PetscCall(PetscObjectStateIncrease((PetscObject)X));
1622: }
1623: }
1624: }
1625: PetscCall(VecDestroy(Y));
1626: PetscFunctionReturn(PETSC_SUCCESS);
1627: }
1629: /*@
1630: VecCreateLocalVector - Creates a vector object suitable for use with `VecGetLocalVector()` and friends. You must call `VecDestroy()` when the
1631: vector is no longer needed.
1633: Not collective.
1635: Input parameter:
1636: . v - The vector for which the local vector is desired.
1638: Output parameter:
1639: . w - Upon exit this contains the local vector.
1641: Level: beginner
1643: .seealso: [](chapter_vectors), `Vec`, `VecGetLocalVectorRead()`, `VecRestoreLocalVectorRead()`, `VecGetLocalVector()`, `VecRestoreLocalVector()`
1644: @*/
1645: PetscErrorCode VecCreateLocalVector(Vec v, Vec *w)
1646: {
1647: PetscMPIInt size;
1649: PetscFunctionBegin;
1652: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)v), &size));
1653: if (size == 1) PetscCall(VecDuplicate(v, w));
1654: else if (v->ops->createlocalvector) PetscUseTypeMethod(v, createlocalvector, w);
1655: else {
1656: VecType type;
1657: PetscInt n;
1659: PetscCall(VecCreate(PETSC_COMM_SELF, w));
1660: PetscCall(VecGetLocalSize(v, &n));
1661: PetscCall(VecSetSizes(*w, n, n));
1662: PetscCall(VecGetBlockSize(v, &n));
1663: PetscCall(VecSetBlockSize(*w, n));
1664: PetscCall(VecGetType(v, &type));
1665: PetscCall(VecSetType(*w, type));
1666: }
1667: PetscFunctionReturn(PETSC_SUCCESS);
1668: }
1670: /*@
1671: VecGetLocalVectorRead - Maps the local portion of a vector into a
1672: vector. You must call `VecRestoreLocalVectorRead()` when the local
1673: vector is no longer needed.
1675: Not collective.
1677: Input parameter:
1678: . v - The vector for which the local vector is desired.
1680: Output parameter:
1681: . w - Upon exit this contains the local vector.
1683: Level: beginner
1685: Notes:
1686: This function is similar to `VecGetArrayRead()` which maps the local
1687: portion into a raw pointer. `VecGetLocalVectorRead()` is usually
1688: almost as efficient as `VecGetArrayRead()` but in certain circumstances
1689: `VecGetLocalVectorRead()` can be much more efficient than
1690: `VecGetArrayRead()`. This is because the construction of a contiguous
1691: array representing the vector data required by `VecGetArrayRead()` can
1692: be an expensive operation for certain vector types. For example, for
1693: GPU vectors `VecGetArrayRead()` requires that the data between device
1694: and host is synchronized.
1696: Unlike `VecGetLocalVector()`, this routine is not collective and
1697: preserves cached information.
1699: .seealso: [](chapter_vectors), `Vec`, `VecCreateLocalVector()`, `VecRestoreLocalVectorRead()`, `VecGetLocalVector()`, `VecGetArrayRead()`, `VecGetArray()`
1700: @*/
1701: PetscErrorCode VecGetLocalVectorRead(Vec v, Vec w)
1702: {
1703: PetscFunctionBegin;
1706: VecCheckSameLocalSize(v, 1, w, 2);
1707: if (v->ops->getlocalvectorread) {
1708: PetscUseTypeMethod(v, getlocalvectorread, w);
1709: } else {
1710: PetscScalar *a;
1712: PetscCall(VecGetArrayRead(v, (const PetscScalar **)&a));
1713: PetscCall(VecPlaceArray(w, a));
1714: }
1715: PetscCall(PetscObjectStateIncrease((PetscObject)w));
1716: PetscCall(VecLockReadPush(v));
1717: PetscCall(VecLockReadPush(w));
1718: PetscFunctionReturn(PETSC_SUCCESS);
1719: }
1721: /*@
1722: VecRestoreLocalVectorRead - Unmaps the local portion of a vector
1723: previously mapped into a vector using `VecGetLocalVectorRead()`.
1725: Not collective.
1727: Input parameter:
1728: + v - The local portion of this vector was previously mapped into w using `VecGetLocalVectorRead()`.
1729: - w - The vector into which the local portion of v was mapped.
1731: Level: beginner
1733: .seealso: [](chapter_vectors), `Vec`, `VecCreateLocalVector()`, `VecGetLocalVectorRead()`, `VecGetLocalVector()`, `VecGetArrayRead()`, `VecGetArray()`
1734: @*/
1735: PetscErrorCode VecRestoreLocalVectorRead(Vec v, Vec w)
1736: {
1737: PetscFunctionBegin;
1740: if (v->ops->restorelocalvectorread) {
1741: PetscUseTypeMethod(v, restorelocalvectorread, w);
1742: } else {
1743: const PetscScalar *a;
1745: PetscCall(VecGetArrayRead(w, &a));
1746: PetscCall(VecRestoreArrayRead(v, &a));
1747: PetscCall(VecResetArray(w));
1748: }
1749: PetscCall(VecLockReadPop(v));
1750: PetscCall(VecLockReadPop(w));
1751: PetscCall(PetscObjectStateIncrease((PetscObject)w));
1752: PetscFunctionReturn(PETSC_SUCCESS);
1753: }
1755: /*@
1756: VecGetLocalVector - Maps the local portion of a vector into a
1757: vector.
1759: Collective on v, not collective on w.
1761: Input parameter:
1762: . v - The vector for which the local vector is desired.
1764: Output parameter:
1765: . w - Upon exit this contains the local vector.
1767: Level: beginner
1769: Notes:
1770: This function is similar to `VecGetArray()` which maps the local
1771: portion into a raw pointer. `VecGetLocalVector()` is usually about as
1772: efficient as `VecGetArray()` but in certain circumstances
1773: `VecGetLocalVector()` can be much more efficient than `VecGetArray()`.
1774: This is because the construction of a contiguous array representing
1775: the vector data required by `VecGetArray()` can be an expensive
1776: operation for certain vector types. For example, for GPU vectors
1777: `VecGetArray()` requires that the data between device and host is
1778: synchronized.
1780: .seealso: [](chapter_vectors), `Vec`, `VecCreateLocalVector()`, `VecRestoreLocalVector()`, `VecGetLocalVectorRead()`, `VecGetArrayRead()`, `VecGetArray()`
1781: @*/
1782: PetscErrorCode VecGetLocalVector(Vec v, Vec w)
1783: {
1784: PetscFunctionBegin;
1787: VecCheckSameLocalSize(v, 1, w, 2);
1788: if (v->ops->getlocalvector) {
1789: PetscUseTypeMethod(v, getlocalvector, w);
1790: } else {
1791: PetscScalar *a;
1793: PetscCall(VecGetArray(v, &a));
1794: PetscCall(VecPlaceArray(w, a));
1795: }
1796: PetscCall(PetscObjectStateIncrease((PetscObject)w));
1797: PetscFunctionReturn(PETSC_SUCCESS);
1798: }
1800: /*@
1801: VecRestoreLocalVector - Unmaps the local portion of a vector
1802: previously mapped into a vector using `VecGetLocalVector()`.
1804: Logically collective.
1806: Input parameter:
1807: + v - The local portion of this vector was previously mapped into `w` using `VecGetLocalVector()`.
1808: - w - The vector into which the local portion of v was mapped.
1810: Level: beginner
1812: .seealso: [](chapter_vectors), `Vec`, `VecCreateLocalVector()`, `VecGetLocalVector()`, `VecGetLocalVectorRead()`, `VecRestoreLocalVectorRead()`, `LocalVectorRead()`, `VecGetArrayRead()`, `VecGetArray()`
1813: @*/
1814: PetscErrorCode VecRestoreLocalVector(Vec v, Vec w)
1815: {
1816: PetscFunctionBegin;
1819: if (v->ops->restorelocalvector) {
1820: PetscUseTypeMethod(v, restorelocalvector, w);
1821: } else {
1822: PetscScalar *a;
1823: PetscCall(VecGetArray(w, &a));
1824: PetscCall(VecRestoreArray(v, &a));
1825: PetscCall(VecResetArray(w));
1826: }
1827: PetscCall(PetscObjectStateIncrease((PetscObject)w));
1828: PetscCall(PetscObjectStateIncrease((PetscObject)v));
1829: PetscFunctionReturn(PETSC_SUCCESS);
1830: }
1832: /*@C
1833: VecGetArray - Returns a pointer to a contiguous array that contains this
1834: processor's portion of the vector data. For the standard PETSc
1835: vectors, VecGetArray() returns a pointer to the local data array and
1836: does not use any copies. If the underlying vector data is not stored
1837: in a contiguous array this routine will copy the data to a contiguous
1838: array and return a pointer to that. You MUST call `VecRestoreArray()`
1839: when you no longer need access to the array.
1841: Logically Collective
1843: Input Parameter:
1844: . x - the vector
1846: Output Parameter:
1847: . a - location to put pointer to the array
1849: Level: beginner
1851: Fortran Note:
1852: `VecGetArray()` Fortran binding is deprecated (since PETSc 3.19), use `VecGetArrayF90()`
1854: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecGetArrayReadF90()`, `VecPlaceArray()`, `VecGetArray2d()`,
1855: `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayWrite()`, `VecRestoreArrayWrite()`
1856: @*/
1857: PetscErrorCode VecGetArray(Vec x, PetscScalar **a)
1858: {
1859: PetscFunctionBegin;
1861: PetscCall(VecSetErrorIfLocked(x, 1));
1862: if (x->ops->getarray) { /* The if-else order matters! VECNEST, VECCUDA etc should have ops->getarray while VECCUDA etc are petscnative */
1863: PetscUseTypeMethod(x, getarray, a);
1864: } else if (x->petscnative) { /* VECSTANDARD */
1865: *a = *((PetscScalar **)x->data);
1866: } else SETERRQ(PetscObjectComm((PetscObject)x), PETSC_ERR_SUP, "Cannot get array for vector type \"%s\"", ((PetscObject)x)->type_name);
1867: PetscFunctionReturn(PETSC_SUCCESS);
1868: }
1870: /*@C
1871: VecRestoreArray - Restores a vector after `VecGetArray()` has been called.
1873: Logically Collective
1875: Input Parameters:
1876: + x - the vector
1877: - a - location of pointer to array obtained from `VecGetArray()`
1879: Level: beginner
1881: Fortran Note:
1882: `VecRestoreArray()` Fortran binding is deprecated (since PETSc 3.19), use `VecRestoreArrayF90()`
1884: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArrayRead()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecRestoreArrayReadF90()`, `VecPlaceArray()`, `VecRestoreArray2d()`,
1885: `VecGetArrayPair()`, `VecRestoreArrayPair()`
1886: @*/
1887: PetscErrorCode VecRestoreArray(Vec x, PetscScalar **a)
1888: {
1889: PetscFunctionBegin;
1892: if (x->ops->restorearray) {
1893: PetscUseTypeMethod(x, restorearray, a);
1894: } else PetscCheck(x->petscnative, PetscObjectComm((PetscObject)x), PETSC_ERR_SUP, "Cannot restore array for vector type \"%s\"", ((PetscObject)x)->type_name);
1895: if (a) *a = NULL;
1896: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1897: PetscFunctionReturn(PETSC_SUCCESS);
1898: }
1899: /*@C
1900: VecGetArrayRead - Get read-only pointer to contiguous array containing this processor's portion of the vector data.
1902: Not Collective
1904: Input Parameter:
1905: . x - the vector
1907: Output Parameter:
1908: . a - the array
1910: Level: beginner
1912: Notes:
1913: The array must be returned using a matching call to `VecRestoreArrayRead()`.
1915: Unlike `VecGetArray()`, preserves cached information like vector norms.
1917: Standard PETSc vectors use contiguous storage so that this routine does not perform a copy. Other vector
1918: implementations may require a copy, but such implementations should cache the contiguous representation so that
1919: only one copy is performed when this routine is called multiple times in sequence.
1921: Fortran Note:
1922: `VecGetArrayRead()` Fortran binding is deprecated (since PETSc 3.19), use `VecGetArrayReadF90()`
1924: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayReadF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
1925: @*/
1926: PetscErrorCode VecGetArrayRead(Vec x, const PetscScalar **a)
1927: {
1928: PetscFunctionBegin;
1931: if (x->ops->getarrayread) {
1932: PetscUseTypeMethod(x, getarrayread, a);
1933: } else if (x->ops->getarray) {
1934: PetscObjectState state;
1936: /* VECNEST, VECCUDA, VECKOKKOS etc */
1937: // x->ops->getarray may bump the object state, but since we know this is a read-only get
1938: // we can just undo that
1939: PetscCall(PetscObjectStateGet((PetscObject)x, &state));
1940: PetscUseTypeMethod(x, getarray, (PetscScalar **)a);
1941: PetscCall(PetscObjectStateSet((PetscObject)x, state));
1942: } else if (x->petscnative) {
1943: /* VECSTANDARD */
1944: *a = *((PetscScalar **)x->data);
1945: } else SETERRQ(PetscObjectComm((PetscObject)x), PETSC_ERR_SUP, "Cannot get array read for vector type \"%s\"", ((PetscObject)x)->type_name);
1946: PetscFunctionReturn(PETSC_SUCCESS);
1947: }
1949: /*@C
1950: VecRestoreArrayRead - Restore array obtained with `VecGetArrayRead()`
1952: Not Collective
1954: Input Parameters:
1955: + vec - the vector
1956: - array - the array
1958: Level: beginner
1960: Fortran Note:
1961: `VecRestoreArrayRead()` Fortran binding is deprecated (since PETSc 3.19), use `VecRestoreArrayReadF90()`
1963: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayReadF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
1964: @*/
1965: PetscErrorCode VecRestoreArrayRead(Vec x, const PetscScalar **a)
1966: {
1967: PetscFunctionBegin;
1970: if (x->petscnative) { /* VECSTANDARD, VECCUDA, VECKOKKOS etc */
1971: /* nothing */
1972: } else if (x->ops->restorearrayread) { /* VECNEST */
1973: PetscUseTypeMethod(x, restorearrayread, a);
1974: } else { /* No one? */
1975: PetscObjectState state;
1977: // x->ops->restorearray may bump the object state, but since we know this is a read-restore
1978: // we can just undo that
1979: PetscCall(PetscObjectStateGet((PetscObject)x, &state));
1980: PetscUseTypeMethod(x, restorearray, (PetscScalar **)a);
1981: PetscCall(PetscObjectStateSet((PetscObject)x, state));
1982: }
1983: if (a) *a = NULL;
1984: PetscFunctionReturn(PETSC_SUCCESS);
1985: }
1987: /*@C
1988: VecGetArrayWrite - Returns a pointer to a contiguous array that WILL contain this
1989: processor's portion of the vector data. The values in this array are NOT valid, the caller of this
1990: routine is responsible for putting values into the array; any values it does not set will be invalid
1992: Logically Collective
1994: Input Parameter:
1995: . x - the vector
1997: Output Parameter:
1998: . a - location to put pointer to the array
2000: Level: intermediate
2002: Note:
2003: For vectors associated with GPUs, the host and device vectors are not synchronized before giving access. If you need correct
2004: values in the array use `VecGetArray()`
2006: Fortran Note:
2007: `VecGetArrayWrite()` Fortran binding is deprecated (since PETSc 3.19), use `VecGetArrayWriteF90()`
2009: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayWriteF90()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecGetArrayReadF90()`, `VecPlaceArray()`, `VecGetArray2d()`,
2010: `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArray()`, `VecRestoreArrayWrite()`
2011: @*/
2012: PetscErrorCode VecGetArrayWrite(Vec x, PetscScalar **a)
2013: {
2014: PetscFunctionBegin;
2017: PetscCall(VecSetErrorIfLocked(x, 1));
2018: if (x->ops->getarraywrite) {
2019: PetscUseTypeMethod(x, getarraywrite, a);
2020: } else {
2021: PetscCall(VecGetArray(x, a));
2022: }
2023: PetscFunctionReturn(PETSC_SUCCESS);
2024: }
2026: /*@C
2027: VecRestoreArrayWrite - Restores a vector after `VecGetArrayWrite()` has been called.
2029: Logically Collective
2031: Input Parameters:
2032: + x - the vector
2033: - a - location of pointer to array obtained from `VecGetArray()`
2035: Level: beginner
2037: Fortran Note:
2038: `VecRestoreArrayWrite()` Fortran binding is deprecated (since PETSc 3.19), use `VecRestoreArrayWriteF90()`
2040: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayWriteF90()`, `VecGetArray()`, `VecRestoreArrayRead()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecRestoreArrayReadF90()`, `VecPlaceArray()`, `VecRestoreArray2d()`,
2041: `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayWrite()`
2042: @*/
2043: PetscErrorCode VecRestoreArrayWrite(Vec x, PetscScalar **a)
2044: {
2045: PetscFunctionBegin;
2048: if (x->ops->restorearraywrite) {
2049: PetscUseTypeMethod(x, restorearraywrite, a);
2050: } else if (x->ops->restorearray) {
2051: PetscUseTypeMethod(x, restorearray, a);
2052: }
2053: if (a) *a = NULL;
2054: PetscCall(PetscObjectStateIncrease((PetscObject)x));
2055: PetscFunctionReturn(PETSC_SUCCESS);
2056: }
2058: /*@C
2059: VecGetArrays - Returns a pointer to the arrays in a set of vectors
2060: that were created by a call to `VecDuplicateVecs()`. You MUST call
2061: `VecRestoreArrays()` when you no longer need access to the array.
2063: Logically Collective; No Fortran Support
2065: Input Parameters:
2066: + x - the vectors
2067: - n - the number of vectors
2069: Output Parameter:
2070: . a - location to put pointer to the array
2072: Level: intermediate
2074: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArrays()`
2075: @*/
2076: PetscErrorCode VecGetArrays(const Vec x[], PetscInt n, PetscScalar **a[])
2077: {
2078: PetscInt i;
2079: PetscScalar **q;
2081: PetscFunctionBegin;
2085: PetscCheck(n > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Must get at least one array n = %" PetscInt_FMT, n);
2086: PetscCall(PetscMalloc1(n, &q));
2087: for (i = 0; i < n; ++i) PetscCall(VecGetArray(x[i], &q[i]));
2088: *a = q;
2089: PetscFunctionReturn(PETSC_SUCCESS);
2090: }
2092: /*@C
2093: VecRestoreArrays - Restores a group of vectors after `VecGetArrays()`
2094: has been called.
2096: Logically Collective; No Fortran Support
2098: Input Parameters:
2099: + x - the vector
2100: . n - the number of vectors
2101: - a - location of pointer to arrays obtained from `VecGetArrays()`
2103: Notes:
2104: For regular PETSc vectors this routine does not involve any copies. For
2105: any special vectors that do not store local vector data in a contiguous
2106: array, this routine will copy the data back into the underlying
2107: vector data structure from the arrays obtained with `VecGetArrays()`.
2109: Level: intermediate
2111: .seealso: [](chapter_vectors), `Vec`, `VecGetArrays()`, `VecRestoreArray()`
2112: @*/
2113: PetscErrorCode VecRestoreArrays(const Vec x[], PetscInt n, PetscScalar **a[])
2114: {
2115: PetscInt i;
2116: PetscScalar **q = *a;
2118: PetscFunctionBegin;
2123: for (i = 0; i < n; ++i) PetscCall(VecRestoreArray(x[i], &q[i]));
2124: PetscCall(PetscFree(q));
2125: PetscFunctionReturn(PETSC_SUCCESS);
2126: }
2128: /*@C
2129: VecGetArrayAndMemType - Like `VecGetArray()`, but if this is a standard device vector (e.g., `VECCUDA`), the returned pointer will be a device
2130: pointer to the device memory that contains this processor's portion of the vector data. Device data is guaranteed to have the latest value.
2131: Otherwise, when this is a host vector (e.g., `VECMPI`), this routine functions the same as `VecGetArray()` and returns a host pointer.
2133: For `VECKOKKOS`, if Kokkos is configured without device (e.g., use serial or openmp), per this function, the vector works like `VECSEQ`/`VECMPI`;
2134: otherwise, it works like `VECCUDA` or `VECHIP` etc.
2136: Logically Collective; No Fortran Support
2138: Input Parameter:
2139: . x - the vector
2141: Output Parameters:
2142: + a - location to put pointer to the array
2143: - mtype - memory type of the array
2145: Level: beginner
2147: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayAndMemType()`, `VecGetArrayReadAndMemType()`, `VecGetArrayWriteAndMemType()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecGetArrayReadF90()`,
2148: `VecPlaceArray()`, `VecGetArray2d()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayWrite()`, `VecRestoreArrayWrite()`
2149: @*/
2150: PetscErrorCode VecGetArrayAndMemType(Vec x, PetscScalar **a, PetscMemType *mtype)
2151: {
2152: PetscFunctionBegin;
2157: PetscCall(VecSetErrorIfLocked(x, 1));
2158: if (x->ops->getarrayandmemtype) {
2159: /* VECCUDA, VECKOKKOS etc */
2160: PetscUseTypeMethod(x, getarrayandmemtype, a, mtype);
2161: } else {
2162: /* VECSTANDARD, VECNEST, VECVIENNACL */
2163: PetscCall(VecGetArray(x, a));
2164: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2165: }
2166: PetscFunctionReturn(PETSC_SUCCESS);
2167: }
2169: /*@C
2170: VecRestoreArrayAndMemType - Restores a vector after `VecGetArrayAndMemType()` has been called.
2172: Logically Collective; No Fortran Support
2174: Input Parameters:
2175: + x - the vector
2176: - a - location of pointer to array obtained from `VecGetArrayAndMemType()`
2178: Level: beginner
2180: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayAndMemType()`, `VecGetArray()`, `VecRestoreArrayRead()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecRestoreArrayReadF90()`,
2181: `VecPlaceArray()`, `VecRestoreArray2d()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
2182: @*/
2183: PetscErrorCode VecRestoreArrayAndMemType(Vec x, PetscScalar **a)
2184: {
2185: PetscFunctionBegin;
2189: if (x->ops->restorearrayandmemtype) {
2190: /* VECCUDA, VECKOKKOS etc */
2191: PetscUseTypeMethod(x, restorearrayandmemtype, a);
2192: } else {
2193: /* VECNEST, VECVIENNACL */
2194: PetscCall(VecRestoreArray(x, a));
2195: } /* VECSTANDARD does nothing */
2196: if (a) *a = NULL;
2197: PetscCall(PetscObjectStateIncrease((PetscObject)x));
2198: PetscFunctionReturn(PETSC_SUCCESS);
2199: }
2201: /*@C
2202: VecGetArrayReadAndMemType - Like `VecGetArrayRead()`, but if the input vector is a device vector, it will return a read-only device pointer. The returned pointer is guaranteed to point to up-to-date data. For host vectors, it functions as `VecGetArrayRead()`.
2204: Not Collective; No Fortran Support
2206: Input Parameter:
2207: . x - the vector
2209: Output Parameters:
2210: + a - the array
2211: - mtype - memory type of the array
2213: Level: beginner
2215: Notes:
2216: The array must be returned using a matching call to `VecRestoreArrayReadAndMemType()`.
2218: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayReadAndMemType()`, `VecGetArrayAndMemType()`, `VecGetArrayWriteAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayAndMemType()`
2219: @*/
2220: PetscErrorCode VecGetArrayReadAndMemType(Vec x, const PetscScalar **a, PetscMemType *mtype)
2221: {
2222: PetscFunctionBegin;
2227: if (x->ops->getarrayreadandmemtype) {
2228: /* VECCUDA/VECHIP though they are also petscnative */
2229: PetscUseTypeMethod(x, getarrayreadandmemtype, a, mtype);
2230: } else if (x->ops->getarrayandmemtype) {
2231: /* VECKOKKOS */
2232: PetscObjectState state;
2234: // see VecGetArrayRead() for why
2235: PetscCall(PetscObjectStateGet((PetscObject)x, &state));
2236: PetscUseTypeMethod(x, getarrayandmemtype, (PetscScalar **)a, mtype);
2237: PetscCall(PetscObjectStateSet((PetscObject)x, state));
2238: } else {
2239: PetscCall(VecGetArrayRead(x, a));
2240: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2241: }
2242: PetscFunctionReturn(PETSC_SUCCESS);
2243: }
2245: /*@C
2246: VecRestoreArrayReadAndMemType - Restore array obtained with `VecGetArrayReadAndMemType()`
2248: Not Collective; No Fortran Support
2250: Input Parameters:
2251: + vec - the vector
2252: - array - the array
2254: Level: beginner
2256: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayReadAndMemType()`, `VecRestoreArrayAndMemType()`, `VecRestoreArrayWriteAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
2257: @*/
2258: PetscErrorCode VecRestoreArrayReadAndMemType(Vec x, const PetscScalar **a)
2259: {
2260: PetscFunctionBegin;
2264: if (x->ops->restorearrayreadandmemtype) {
2265: /* VECCUDA/VECHIP */
2266: PetscUseTypeMethod(x, restorearrayreadandmemtype, a);
2267: } else if (!x->petscnative) {
2268: /* VECNEST */
2269: PetscCall(VecRestoreArrayRead(x, a));
2270: }
2271: if (a) *a = NULL;
2272: PetscFunctionReturn(PETSC_SUCCESS);
2273: }
2275: /*@C
2276: VecGetArrayWriteAndMemType - Like `VecGetArrayWrite()`, but if this is a device vector it will always return
2277: a device pointer to the device memory that contains this processor's portion of the vector data.
2279: Not Collective; No Fortran Support
2281: Input Parameter:
2282: . x - the vector
2284: Output Parameters:
2285: + a - the array
2286: - mtype - memory type of the array
2288: Level: beginner
2290: Note:
2291: The array must be returned using a matching call to `VecRestoreArrayWriteAndMemType()`, where it will label the device memory as most recent.
2293: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayWriteAndMemType()`, `VecGetArrayReadAndMemType()`, `VecGetArrayAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`,
2294: @*/
2295: PetscErrorCode VecGetArrayWriteAndMemType(Vec x, PetscScalar **a, PetscMemType *mtype)
2296: {
2297: PetscFunctionBegin;
2300: PetscCall(VecSetErrorIfLocked(x, 1));
2303: if (x->ops->getarraywriteandmemtype) {
2304: /* VECCUDA, VECHIP, VECKOKKOS etc, though they are also petscnative */
2305: PetscUseTypeMethod(x, getarraywriteandmemtype, a, mtype);
2306: } else if (x->ops->getarrayandmemtype) {
2307: PetscCall(VecGetArrayAndMemType(x, a, mtype));
2308: } else {
2309: /* VECNEST, VECVIENNACL */
2310: PetscCall(VecGetArrayWrite(x, a));
2311: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2312: }
2313: PetscFunctionReturn(PETSC_SUCCESS);
2314: }
2316: /*@C
2317: VecRestoreArrayWriteAndMemType - Restore array obtained with `VecGetArrayWriteAndMemType()`
2319: Not Collective; No Fortran Support
2321: Input Parameters:
2322: + vec - the vector
2323: - array - the array
2325: Level: beginner
2327: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayWriteAndMemType()`, `VecRestoreArrayAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
2328: @*/
2329: PetscErrorCode VecRestoreArrayWriteAndMemType(Vec x, PetscScalar **a)
2330: {
2331: PetscFunctionBegin;
2334: PetscCall(VecSetErrorIfLocked(x, 1));
2336: if (x->ops->restorearraywriteandmemtype) {
2337: /* VECCUDA/VECHIP */
2338: PetscMemType PETSC_UNUSED mtype; // since this function doesn't accept a memtype?
2339: PetscUseTypeMethod(x, restorearraywriteandmemtype, a, &mtype);
2340: } else if (x->ops->restorearrayandmemtype) {
2341: PetscCall(VecRestoreArrayAndMemType(x, a));
2342: } else {
2343: PetscCall(VecRestoreArray(x, a));
2344: }
2345: if (a) *a = NULL;
2346: PetscFunctionReturn(PETSC_SUCCESS);
2347: }
2349: /*@
2350: VecPlaceArray - Allows one to replace the array in a vector with an
2351: array provided by the user. This is useful to avoid copying an array
2352: into a vector.
2354: Not Collective; No Fortran Support
2356: Input Parameters:
2357: + vec - the vector
2358: - array - the array
2360: Notes:
2361: You can return to the original array with a call to `VecResetArray()`. `vec` does not take
2362: ownership of `array` in any way. The user must free `array` themselves but be careful not to
2363: do so before the vector has either been destroyed, had its original array restored with
2364: `VecResetArray()` or permanently replaced with `VecReplaceArray()`.
2366: Level: developer
2368: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecResetArray()`
2369: @*/
2370: PetscErrorCode VecPlaceArray(Vec vec, const PetscScalar array[])
2371: {
2372: PetscFunctionBegin;
2376: PetscUseTypeMethod(vec, placearray, array);
2377: PetscCall(PetscObjectStateIncrease((PetscObject)vec));
2378: PetscFunctionReturn(PETSC_SUCCESS);
2379: }
2381: /*@C
2382: VecReplaceArray - Allows one to replace the array in a vector with an
2383: array provided by the user. This is useful to avoid copying an array
2384: into a vector.
2386: Not Collective; No Fortran Support
2388: Input Parameters:
2389: + vec - the vector
2390: - array - the array
2392: Level: developer
2394: Notes:
2395: This permanently replaces the array and frees the memory associated
2396: with the old array.
2398: The memory passed in MUST be obtained with `PetscMalloc()` and CANNOT be
2399: freed by the user. It will be freed when the vector is destroyed.
2401: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecPlaceArray()`, `VecResetArray()`
2402: @*/
2403: PetscErrorCode VecReplaceArray(Vec vec, const PetscScalar array[])
2404: {
2405: PetscFunctionBegin;
2408: PetscUseTypeMethod(vec, replacearray, array);
2409: PetscCall(PetscObjectStateIncrease((PetscObject)vec));
2410: PetscFunctionReturn(PETSC_SUCCESS);
2411: }
2413: /*MC
2414: VecDuplicateVecsF90 - Creates several vectors of the same type as an existing vector
2415: and makes them accessible via a Fortran pointer.
2417: Synopsis:
2418: VecDuplicateVecsF90(Vec x,PetscInt n,{Vec, pointer :: y(:)},integer ierr)
2420: Collective
2422: Input Parameters:
2423: + x - a vector to mimic
2424: - n - the number of vectors to obtain
2426: Output Parameters:
2427: + y - Fortran pointer to the array of vectors
2428: - ierr - error code
2430: Example of Usage:
2431: .vb
2432: #include <petsc/finclude/petscvec.h>
2433: use petscvec
2435: Vec x
2436: Vec, pointer :: y(:)
2437: ....
2438: call VecDuplicateVecsF90(x,2,y,ierr)
2439: call VecSet(y(2),alpha,ierr)
2440: call VecSet(y(2),alpha,ierr)
2441: ....
2442: call VecDestroyVecsF90(2,y,ierr)
2443: .ve
2445: Level: beginner
2447: Note:
2448: Use `VecDestroyVecsF90()` to free the space.
2450: .seealso: [](chapter_vectors), `Vec`, `VecDestroyVecsF90()`, `VecDuplicateVecs()`
2451: M*/
2453: /*MC
2454: VecRestoreArrayF90 - Restores a vector to a usable state after a call to
2455: `VecGetArrayF90()`.
2457: Synopsis:
2458: VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2460: Logically Collective
2462: Input Parameters:
2463: + x - vector
2464: - xx_v - the Fortran pointer to the array
2466: Output Parameter:
2467: . ierr - error code
2469: Example of Usage:
2470: .vb
2471: #include <petsc/finclude/petscvec.h>
2472: use petscvec
2474: PetscScalar, pointer :: xx_v(:)
2475: ....
2476: call VecGetArrayF90(x,xx_v,ierr)
2477: xx_v(3) = a
2478: call VecRestoreArrayF90(x,xx_v,ierr)
2479: .ve
2481: Level: beginner
2483: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrayReadF90()`
2484: M*/
2486: /*MC
2487: VecDestroyVecsF90 - Frees a block of vectors obtained with `VecDuplicateVecsF90()`.
2489: Synopsis:
2490: VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)
2492: Collective
2494: Input Parameters:
2495: + n - the number of vectors previously obtained
2496: - x - pointer to array of vector pointers
2498: Output Parameter:
2499: . ierr - error code
2501: Level: beginner
2503: .seealso: [](chapter_vectors), `Vec`, `VecDestroyVecs()`, `VecDuplicateVecsF90()`
2504: M*/
2506: /*MC
2507: VecGetArrayF90 - Accesses a vector array from Fortran. For default PETSc
2508: vectors, `VecGetArrayF90()` returns a pointer to the local data array. Otherwise,
2509: this routine is implementation dependent. You MUST call `VecRestoreArrayF90()`
2510: when you no longer need access to the array.
2512: Synopsis:
2513: VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2515: Logically Collective
2517: Input Parameter:
2518: . x - vector
2520: Output Parameters:
2521: + xx_v - the Fortran pointer to the array
2522: - ierr - error code
2524: Example of Usage:
2525: .vb
2526: #include <petsc/finclude/petscvec.h>
2527: use petscvec
2529: PetscScalar, pointer :: xx_v(:)
2530: ....
2531: call VecGetArrayF90(x,xx_v,ierr)
2532: xx_v(3) = a
2533: call VecRestoreArrayF90(x,xx_v,ierr)
2534: .ve
2536: Level: beginner
2538: Note:
2539: If you ONLY intend to read entries from the array and not change any entries you should use `VecGetArrayReadF90()`.
2541: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayReadF90()`
2542: M*/
2544: /*MC
2545: VecGetArrayReadF90 - Accesses a read only array from Fortran. For default PETSc
2546: vectors, `VecGetArrayF90()` returns a pointer to the local data array. Otherwise,
2547: this routine is implementation dependent. You MUST call `VecRestoreArrayReadF90()`
2548: when you no longer need access to the array.
2550: Synopsis:
2551: VecGetArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2553: Logically Collective
2555: Input Parameter:
2556: . x - vector
2558: Output Parameters:
2559: + xx_v - the Fortran pointer to the array
2560: - ierr - error code
2562: Example of Usage:
2563: .vb
2564: #include <petsc/finclude/petscvec.h>
2565: use petscvec
2567: PetscScalar, pointer :: xx_v(:)
2568: ....
2569: call VecGetArrayReadF90(x,xx_v,ierr)
2570: a = xx_v(3)
2571: call VecRestoreArrayReadF90(x,xx_v,ierr)
2572: .ve
2574: Level: beginner
2576: Note:
2577: If you intend to write entries into the array you must use `VecGetArrayF90()`.
2579: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArrayReadF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecRestoreArrayRead()`, `VecGetArrayF90()`
2580: M*/
2582: /*MC
2583: VecRestoreArrayReadF90 - Restores a readonly vector to a usable state after a call to
2584: `VecGetArrayReadF90()`.
2586: Synopsis:
2587: VecRestoreArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2589: Logically Collective
2591: Input Parameters:
2592: + x - vector
2593: - xx_v - the Fortran pointer to the array
2595: Output Parameter:
2596: . ierr - error code
2598: Example of Usage:
2599: .vb
2600: #include <petsc/finclude/petscvec.h>
2601: use petscvec
2603: PetscScalar, pointer :: xx_v(:)
2604: ....
2605: call VecGetArrayReadF90(x,xx_v,ierr)
2606: a = xx_v(3)
2607: call VecRestoreArrayReadF90(x,xx_v,ierr)
2608: .ve
2610: Level: beginner
2612: .seealso: [](chapter_vectors), `Vec`, `VecGetArrayReadF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecRestoreArrayRead()`, `VecRestoreArrayF90()`
2613: M*/
2615: /*@C
2616: VecGetArray2d - Returns a pointer to a 2d contiguous array that contains this
2617: processor's portion of the vector data. You MUST call `VecRestoreArray2d()`
2618: when you no longer need access to the array.
2620: Logically Collective
2622: Input Parameters:
2623: + x - the vector
2624: . m - first dimension of two dimensional array
2625: . n - second dimension of two dimensional array
2626: . mstart - first index you will use in first coordinate direction (often 0)
2627: - nstart - first index in the second coordinate direction (often 0)
2629: Output Parameter:
2630: . a - location to put pointer to the array
2632: Level: developer
2634: Notes:
2635: For a vector obtained from `DMCreateLocalVector()` mstart and nstart are likely
2636: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2637: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
2638: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray2d()`.
2640: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2642: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2643: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
2644: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2645: @*/
2646: PetscErrorCode VecGetArray2d(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
2647: {
2648: PetscInt i, N;
2649: PetscScalar *aa;
2651: PetscFunctionBegin;
2655: PetscCall(VecGetLocalSize(x, &N));
2656: 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);
2657: PetscCall(VecGetArray(x, &aa));
2659: PetscCall(PetscMalloc1(m, a));
2660: for (i = 0; i < m; i++) (*a)[i] = aa + i * n - nstart;
2661: *a -= mstart;
2662: PetscFunctionReturn(PETSC_SUCCESS);
2663: }
2665: /*@C
2666: VecGetArray2dWrite - Returns a pointer to a 2d contiguous array that will contain this
2667: processor's portion of the vector data. You MUST call `VecRestoreArray2dWrite()`
2668: when you no longer need access to the array.
2670: Logically Collective
2672: Input Parameters:
2673: + x - the vector
2674: . m - first dimension of two dimensional array
2675: . n - second dimension of two dimensional array
2676: . mstart - first index you will use in first coordinate direction (often 0)
2677: - nstart - first index in the second coordinate direction (often 0)
2679: Output Parameter:
2680: . a - location to put pointer to the array
2682: Level: developer
2684: Notes:
2685: For a vector obtained from `DMCreateLocalVector()` mstart and nstart are likely
2686: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2687: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
2688: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray2d()`.
2690: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2692: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2693: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
2694: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2695: @*/
2696: PetscErrorCode VecGetArray2dWrite(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
2697: {
2698: PetscInt i, N;
2699: PetscScalar *aa;
2701: PetscFunctionBegin;
2705: PetscCall(VecGetLocalSize(x, &N));
2706: 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);
2707: PetscCall(VecGetArrayWrite(x, &aa));
2709: PetscCall(PetscMalloc1(m, a));
2710: for (i = 0; i < m; i++) (*a)[i] = aa + i * n - nstart;
2711: *a -= mstart;
2712: PetscFunctionReturn(PETSC_SUCCESS);
2713: }
2715: /*@C
2716: VecRestoreArray2d - Restores a vector after `VecGetArray2d()` has been called.
2718: Logically Collective
2720: Input Parameters:
2721: + x - the vector
2722: . m - first dimension of two dimensional array
2723: . n - second dimension of the two dimensional array
2724: . mstart - first index you will use in first coordinate direction (often 0)
2725: . nstart - first index in the second coordinate direction (often 0)
2726: - a - location of pointer to array obtained from `VecGetArray2d()`
2728: Level: developer
2730: Notes:
2731: For regular PETSc vectors this routine does not involve any copies. For
2732: any special vectors that do not store local vector data in a contiguous
2733: array, this routine will copy the data back into the underlying
2734: vector data structure from the array obtained with `VecGetArray()`.
2736: This routine actually zeros out the a pointer.
2738: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
2739: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
2740: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2741: @*/
2742: PetscErrorCode VecRestoreArray2d(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
2743: {
2744: void *dummy;
2746: PetscFunctionBegin;
2750: dummy = (void *)(*a + mstart);
2751: PetscCall(PetscFree(dummy));
2752: PetscCall(VecRestoreArray(x, NULL));
2753: PetscFunctionReturn(PETSC_SUCCESS);
2754: }
2756: /*@C
2757: VecRestoreArray2dWrite - Restores a vector after VecGetArray2dWrite`()` has been called.
2759: Logically Collective
2761: Input Parameters:
2762: + x - the vector
2763: . m - first dimension of two dimensional array
2764: . n - second dimension of the two dimensional array
2765: . mstart - first index you will use in first coordinate direction (often 0)
2766: . nstart - first index in the second coordinate direction (often 0)
2767: - a - location of pointer to array obtained from `VecGetArray2d()`
2769: Level: developer
2771: Notes:
2772: For regular PETSc vectors this routine does not involve any copies. For
2773: any special vectors that do not store local vector data in a contiguous
2774: array, this routine will copy the data back into the underlying
2775: vector data structure from the array obtained with `VecGetArray()`.
2777: This routine actually zeros out the a pointer.
2779: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
2780: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
2781: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2782: @*/
2783: PetscErrorCode VecRestoreArray2dWrite(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
2784: {
2785: void *dummy;
2787: PetscFunctionBegin;
2791: dummy = (void *)(*a + mstart);
2792: PetscCall(PetscFree(dummy));
2793: PetscCall(VecRestoreArrayWrite(x, NULL));
2794: PetscFunctionReturn(PETSC_SUCCESS);
2795: }
2797: /*@C
2798: VecGetArray1d - Returns a pointer to a 1d contiguous array that contains this
2799: processor's portion of the vector data. You MUST call `VecRestoreArray1d()`
2800: when you no longer need access to the array.
2802: Logically Collective
2804: Input Parameters:
2805: + x - the vector
2806: . m - first dimension of two dimensional array
2807: - mstart - first index you will use in first coordinate direction (often 0)
2809: Output Parameter:
2810: . a - location to put pointer to the array
2812: Level: developer
2814: Notes:
2815: For a vector obtained from `DMCreateLocalVector()` mstart are likely
2816: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2817: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`.
2819: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2821: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2822: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
2823: `VecGetArray2d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2824: @*/
2825: PetscErrorCode VecGetArray1d(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
2826: {
2827: PetscInt N;
2829: PetscFunctionBegin;
2833: PetscCall(VecGetLocalSize(x, &N));
2834: 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);
2835: PetscCall(VecGetArray(x, a));
2836: *a -= mstart;
2837: PetscFunctionReturn(PETSC_SUCCESS);
2838: }
2840: /*@C
2841: VecGetArray1dWrite - Returns a pointer to a 1d contiguous array that will contain this
2842: processor's portion of the vector data. You MUST call `VecRestoreArray1dWrite()`
2843: when you no longer need access to the array.
2845: Logically Collective
2847: Input Parameters:
2848: + x - the vector
2849: . m - first dimension of two dimensional array
2850: - mstart - first index you will use in first coordinate direction (often 0)
2852: Output Parameter:
2853: . a - location to put pointer to the array
2855: Level: developer
2857: Notes:
2858: For a vector obtained from `DMCreateLocalVector()` mstart are likely
2859: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2860: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`.
2862: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2864: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2865: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
2866: `VecGetArray2d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2867: @*/
2868: PetscErrorCode VecGetArray1dWrite(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
2869: {
2870: PetscInt N;
2872: PetscFunctionBegin;
2876: PetscCall(VecGetLocalSize(x, &N));
2877: 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);
2878: PetscCall(VecGetArrayWrite(x, a));
2879: *a -= mstart;
2880: PetscFunctionReturn(PETSC_SUCCESS);
2881: }
2883: /*@C
2884: VecRestoreArray1d - Restores a vector after `VecGetArray1d()` has been called.
2886: Logically Collective
2888: Input Parameters:
2889: + x - the vector
2890: . m - first dimension of two dimensional array
2891: . mstart - first index you will use in first coordinate direction (often 0)
2892: - a - location of pointer to array obtained from `VecGetArray1d()`
2894: Level: developer
2896: Notes:
2897: For regular PETSc vectors this routine does not involve any copies. For
2898: any special vectors that do not store local vector data in a contiguous
2899: array, this routine will copy the data back into the underlying
2900: vector data structure from the array obtained with `VecGetArray1d()`.
2902: This routine actually zeros out the a pointer.
2904: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
2905: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
2906: `VecGetArray1d()`, `VecRestoreArray2d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2907: @*/
2908: PetscErrorCode VecRestoreArray1d(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
2909: {
2910: PetscFunctionBegin;
2913: PetscCall(VecRestoreArray(x, NULL));
2914: PetscFunctionReturn(PETSC_SUCCESS);
2915: }
2917: /*@C
2918: VecRestoreArray1dWrite - Restores a vector after `VecGetArray1dWrite()` has been called.
2920: Logically Collective
2922: Input Parameters:
2923: + x - the vector
2924: . m - first dimension of two dimensional array
2925: . mstart - first index you will use in first coordinate direction (often 0)
2926: - a - location of pointer to array obtained from `VecGetArray1d()`
2928: Level: developer
2930: Notes:
2931: For regular PETSc vectors this routine does not involve any copies. For
2932: any special vectors that do not store local vector data in a contiguous
2933: array, this routine will copy the data back into the underlying
2934: vector data structure from the array obtained with `VecGetArray1d()`.
2936: This routine actually zeros out the a pointer.
2938: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
2939: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
2940: `VecGetArray1d()`, `VecRestoreArray2d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2941: @*/
2942: PetscErrorCode VecRestoreArray1dWrite(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
2943: {
2944: PetscFunctionBegin;
2947: PetscCall(VecRestoreArrayWrite(x, NULL));
2948: PetscFunctionReturn(PETSC_SUCCESS);
2949: }
2951: /*@C
2952: VecGetArray3d - Returns a pointer to a 3d contiguous array that contains this
2953: processor's portion of the vector data. You MUST call `VecRestoreArray3d()`
2954: when you no longer need access to the array.
2956: Logically Collective
2958: Input Parameters:
2959: + x - the vector
2960: . m - first dimension of three dimensional array
2961: . n - second dimension of three dimensional array
2962: . p - third dimension of three dimensional array
2963: . mstart - first index you will use in first coordinate direction (often 0)
2964: . nstart - first index in the second coordinate direction (often 0)
2965: - pstart - first index in the third coordinate direction (often 0)
2967: Output Parameter:
2968: . a - location to put pointer to the array
2970: Level: developer
2972: Notes:
2973: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
2974: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
2975: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
2976: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
2978: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2980: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
2981: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
2982: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
2983: @*/
2984: PetscErrorCode VecGetArray3d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
2985: {
2986: PetscInt i, N, j;
2987: PetscScalar *aa, **b;
2989: PetscFunctionBegin;
2993: PetscCall(VecGetLocalSize(x, &N));
2994: 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);
2995: PetscCall(VecGetArray(x, &aa));
2997: PetscCall(PetscMalloc(m * sizeof(PetscScalar **) + m * n * sizeof(PetscScalar *), a));
2998: b = (PetscScalar **)((*a) + m);
2999: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3000: for (i = 0; i < m; i++)
3001: for (j = 0; j < n; j++) b[i * n + j] = aa + i * n * p + j * p - pstart;
3002: *a -= mstart;
3003: PetscFunctionReturn(PETSC_SUCCESS);
3004: }
3006: /*@C
3007: VecGetArray3dWrite - Returns a pointer to a 3d contiguous array that will contain this
3008: processor's portion of the vector data. You MUST call `VecRestoreArray3dWrite()`
3009: when you no longer need access to the array.
3011: Logically Collective
3013: Input Parameters:
3014: + x - the vector
3015: . m - first dimension of three dimensional array
3016: . n - second dimension of three dimensional array
3017: . p - third dimension of three dimensional array
3018: . mstart - first index you will use in first coordinate direction (often 0)
3019: . nstart - first index in the second coordinate direction (often 0)
3020: - pstart - first index in the third coordinate direction (often 0)
3022: Output Parameter:
3023: . a - location to put pointer to the array
3025: Level: developer
3027: Notes:
3028: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3029: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3030: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3031: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
3033: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3035: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3036: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3037: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3038: @*/
3039: PetscErrorCode VecGetArray3dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3040: {
3041: PetscInt i, N, j;
3042: PetscScalar *aa, **b;
3044: PetscFunctionBegin;
3048: PetscCall(VecGetLocalSize(x, &N));
3049: 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);
3050: PetscCall(VecGetArrayWrite(x, &aa));
3052: PetscCall(PetscMalloc(m * sizeof(PetscScalar **) + m * n * sizeof(PetscScalar *), a));
3053: b = (PetscScalar **)((*a) + m);
3054: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3055: for (i = 0; i < m; i++)
3056: for (j = 0; j < n; j++) b[i * n + j] = aa + i * n * p + j * p - pstart;
3058: *a -= mstart;
3059: PetscFunctionReturn(PETSC_SUCCESS);
3060: }
3062: /*@C
3063: VecRestoreArray3d - Restores a vector after `VecGetArray3d()` has been called.
3065: Logically Collective
3067: Input Parameters:
3068: + x - the vector
3069: . m - first dimension of three dimensional array
3070: . n - second dimension of the three dimensional array
3071: . p - third dimension of the three dimensional array
3072: . mstart - first index you will use in first coordinate direction (often 0)
3073: . nstart - first index in the second coordinate direction (often 0)
3074: . pstart - first index in the third coordinate direction (often 0)
3075: - a - location of pointer to array obtained from VecGetArray3d()
3077: Level: developer
3079: Notes:
3080: For regular PETSc vectors this routine does not involve any copies. For
3081: any special vectors that do not store local vector data in a contiguous
3082: array, this routine will copy the data back into the underlying
3083: vector data structure from the array obtained with `VecGetArray()`.
3085: This routine actually zeros out the a pointer.
3087: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3088: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3089: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3090: @*/
3091: PetscErrorCode VecRestoreArray3d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3092: {
3093: void *dummy;
3095: PetscFunctionBegin;
3099: dummy = (void *)(*a + mstart);
3100: PetscCall(PetscFree(dummy));
3101: PetscCall(VecRestoreArray(x, NULL));
3102: PetscFunctionReturn(PETSC_SUCCESS);
3103: }
3105: /*@C
3106: VecRestoreArray3dWrite - Restores a vector after `VecGetArray3dWrite()` has been called.
3108: Logically Collective
3110: Input Parameters:
3111: + x - the vector
3112: . m - first dimension of three dimensional array
3113: . n - second dimension of the three dimensional array
3114: . p - third dimension of the three dimensional array
3115: . mstart - first index you will use in first coordinate direction (often 0)
3116: . nstart - first index in the second coordinate direction (often 0)
3117: . pstart - first index in the third coordinate direction (often 0)
3118: - a - location of pointer to array obtained from VecGetArray3d()
3120: Level: developer
3122: Notes:
3123: For regular PETSc vectors this routine does not involve any copies. For
3124: any special vectors that do not store local vector data in a contiguous
3125: array, this routine will copy the data back into the underlying
3126: vector data structure from the array obtained with `VecGetArray()`.
3128: This routine actually zeros out the a pointer.
3130: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3131: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3132: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3133: @*/
3134: PetscErrorCode VecRestoreArray3dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3135: {
3136: void *dummy;
3138: PetscFunctionBegin;
3142: dummy = (void *)(*a + mstart);
3143: PetscCall(PetscFree(dummy));
3144: PetscCall(VecRestoreArrayWrite(x, NULL));
3145: PetscFunctionReturn(PETSC_SUCCESS);
3146: }
3148: /*@C
3149: VecGetArray4d - Returns a pointer to a 4d contiguous array that contains this
3150: processor's portion of the vector data. You MUST call `VecRestoreArray4d()`
3151: when you no longer need access to the array.
3153: Logically Collective
3155: Input Parameters:
3156: + x - the vector
3157: . m - first dimension of four dimensional array
3158: . n - second dimension of four dimensional array
3159: . p - third dimension of four dimensional array
3160: . q - fourth dimension of four dimensional array
3161: . mstart - first index you will use in first coordinate direction (often 0)
3162: . nstart - first index in the second coordinate direction (often 0)
3163: . pstart - first index in the third coordinate direction (often 0)
3164: - qstart - first index in the fourth coordinate direction (often 0)
3166: Output Parameter:
3167: . a - location to put pointer to the array
3169: Level: beginner
3171: Notes:
3172: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3173: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3174: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3175: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
3177: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3179: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3180: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3181: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3182: @*/
3183: PetscErrorCode VecGetArray4d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3184: {
3185: PetscInt i, N, j, k;
3186: PetscScalar *aa, ***b, **c;
3188: PetscFunctionBegin;
3192: PetscCall(VecGetLocalSize(x, &N));
3193: 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);
3194: PetscCall(VecGetArray(x, &aa));
3196: PetscCall(PetscMalloc(m * sizeof(PetscScalar ***) + m * n * sizeof(PetscScalar **) + m * n * p * sizeof(PetscScalar *), a));
3197: b = (PetscScalar ***)((*a) + m);
3198: c = (PetscScalar **)(b + m * n);
3199: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3200: for (i = 0; i < m; i++)
3201: for (j = 0; j < n; j++) b[i * n + j] = c + i * n * p + j * p - pstart;
3202: for (i = 0; i < m; i++)
3203: for (j = 0; j < n; j++)
3204: for (k = 0; k < p; k++) c[i * n * p + j * p + k] = aa + i * n * p * q + j * p * q + k * q - qstart;
3205: *a -= mstart;
3206: PetscFunctionReturn(PETSC_SUCCESS);
3207: }
3209: /*@C
3210: VecGetArray4dWrite - Returns a pointer to a 4d contiguous array that will contain this
3211: processor's portion of the vector data. You MUST call `VecRestoreArray4dWrite()`
3212: when you no longer need access to the array.
3214: Logically Collective
3216: Input Parameters:
3217: + x - the vector
3218: . m - first dimension of four dimensional array
3219: . n - second dimension of four dimensional array
3220: . p - third dimension of four dimensional array
3221: . q - fourth dimension of four dimensional array
3222: . mstart - first index you will use in first coordinate direction (often 0)
3223: . nstart - first index in the second coordinate direction (often 0)
3224: . pstart - first index in the third coordinate direction (often 0)
3225: - qstart - first index in the fourth coordinate direction (often 0)
3227: Output Parameter:
3228: . a - location to put pointer to the array
3230: Level: beginner
3232: Notes:
3233: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3234: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3235: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3236: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
3238: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3240: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3241: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3242: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3243: @*/
3244: PetscErrorCode VecGetArray4dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3245: {
3246: PetscInt i, N, j, k;
3247: PetscScalar *aa, ***b, **c;
3249: PetscFunctionBegin;
3253: PetscCall(VecGetLocalSize(x, &N));
3254: 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);
3255: PetscCall(VecGetArrayWrite(x, &aa));
3257: PetscCall(PetscMalloc(m * sizeof(PetscScalar ***) + m * n * sizeof(PetscScalar **) + m * n * p * sizeof(PetscScalar *), a));
3258: b = (PetscScalar ***)((*a) + m);
3259: c = (PetscScalar **)(b + m * n);
3260: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3261: for (i = 0; i < m; i++)
3262: for (j = 0; j < n; j++) b[i * n + j] = c + i * n * p + j * p - pstart;
3263: for (i = 0; i < m; i++)
3264: for (j = 0; j < n; j++)
3265: for (k = 0; k < p; k++) c[i * n * p + j * p + k] = aa + i * n * p * q + j * p * q + k * q - qstart;
3266: *a -= mstart;
3267: PetscFunctionReturn(PETSC_SUCCESS);
3268: }
3270: /*@C
3271: VecRestoreArray4d - Restores a vector after `VecGetArray4d()` has been called.
3273: Logically Collective
3275: Input Parameters:
3276: + x - the vector
3277: . m - first dimension of four dimensional array
3278: . n - second dimension of the four dimensional array
3279: . p - third dimension of the four dimensional array
3280: . q - fourth dimension of the four dimensional array
3281: . mstart - first index you will use in first coordinate direction (often 0)
3282: . nstart - first index in the second coordinate direction (often 0)
3283: . pstart - first index in the third coordinate direction (often 0)
3284: . qstart - first index in the fourth coordinate direction (often 0)
3285: - a - location of pointer to array obtained from VecGetArray4d()
3287: Level: beginner
3289: Notes:
3290: For regular PETSc vectors this routine does not involve any copies. For
3291: any special vectors that do not store local vector data in a contiguous
3292: array, this routine will copy the data back into the underlying
3293: vector data structure from the array obtained with `VecGetArray()`.
3295: This routine actually zeros out the a pointer.
3297: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3298: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3299: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3300: @*/
3301: PetscErrorCode VecRestoreArray4d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3302: {
3303: void *dummy;
3305: PetscFunctionBegin;
3309: dummy = (void *)(*a + mstart);
3310: PetscCall(PetscFree(dummy));
3311: PetscCall(VecRestoreArray(x, NULL));
3312: PetscFunctionReturn(PETSC_SUCCESS);
3313: }
3315: /*@C
3316: VecRestoreArray4dWrite - Restores a vector after `VecGetArray4dWrite()` has been called.
3318: Logically Collective
3320: Input Parameters:
3321: + x - the vector
3322: . m - first dimension of four dimensional array
3323: . n - second dimension of the four dimensional array
3324: . p - third dimension of the four dimensional array
3325: . q - fourth dimension of the four dimensional array
3326: . mstart - first index you will use in first coordinate direction (often 0)
3327: . nstart - first index in the second coordinate direction (often 0)
3328: . pstart - first index in the third coordinate direction (often 0)
3329: . qstart - first index in the fourth coordinate direction (often 0)
3330: - a - location of pointer to array obtained from `VecGetArray4d()`
3332: Level: beginner
3334: Notes:
3335: For regular PETSc vectors this routine does not involve any copies. For
3336: any special vectors that do not store local vector data in a contiguous
3337: array, this routine will copy the data back into the underlying
3338: vector data structure from the array obtained with `VecGetArray()`.
3340: This routine actually zeros out the a pointer.
3342: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3343: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3344: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3345: @*/
3346: PetscErrorCode VecRestoreArray4dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3347: {
3348: void *dummy;
3350: PetscFunctionBegin;
3354: dummy = (void *)(*a + mstart);
3355: PetscCall(PetscFree(dummy));
3356: PetscCall(VecRestoreArrayWrite(x, NULL));
3357: PetscFunctionReturn(PETSC_SUCCESS);
3358: }
3360: /*@C
3361: VecGetArray2dRead - Returns a pointer to a 2d contiguous array that contains this
3362: processor's portion of the vector data. You MUST call `VecRestoreArray2dRead()`
3363: when you no longer need access to the array.
3365: Logically Collective
3367: Input Parameters:
3368: + x - the vector
3369: . m - first dimension of two dimensional array
3370: . n - second dimension of two dimensional array
3371: . mstart - first index you will use in first coordinate direction (often 0)
3372: - nstart - first index in the second coordinate direction (often 0)
3374: Output Parameter:
3375: . a - location to put pointer to the array
3377: Level: developer
3379: Notes:
3380: For a vector obtained from `DMCreateLocalVector()` mstart and nstart are likely
3381: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3382: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3383: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray2d()`.
3385: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3387: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3388: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3389: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3390: @*/
3391: PetscErrorCode VecGetArray2dRead(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
3392: {
3393: PetscInt i, N;
3394: const PetscScalar *aa;
3396: PetscFunctionBegin;
3400: PetscCall(VecGetLocalSize(x, &N));
3401: 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);
3402: PetscCall(VecGetArrayRead(x, &aa));
3404: PetscCall(PetscMalloc1(m, a));
3405: for (i = 0; i < m; i++) (*a)[i] = (PetscScalar *)aa + i * n - nstart;
3406: *a -= mstart;
3407: PetscFunctionReturn(PETSC_SUCCESS);
3408: }
3410: /*@C
3411: VecRestoreArray2dRead - Restores a vector after `VecGetArray2dRead()` has been called.
3413: Logically Collective
3415: Input Parameters:
3416: + x - the vector
3417: . m - first dimension of two dimensional array
3418: . n - second dimension of the two dimensional array
3419: . mstart - first index you will use in first coordinate direction (often 0)
3420: . nstart - first index in the second coordinate direction (often 0)
3421: - a - location of pointer to array obtained from VecGetArray2d()
3423: Level: developer
3425: Notes:
3426: For regular PETSc vectors this routine does not involve any copies. For
3427: any special vectors that do not store local vector data in a contiguous
3428: array, this routine will copy the data back into the underlying
3429: vector data structure from the array obtained with `VecGetArray()`.
3431: This routine actually zeros out the a pointer.
3433: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3434: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3435: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3436: @*/
3437: PetscErrorCode VecRestoreArray2dRead(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
3438: {
3439: void *dummy;
3441: PetscFunctionBegin;
3445: dummy = (void *)(*a + mstart);
3446: PetscCall(PetscFree(dummy));
3447: PetscCall(VecRestoreArrayRead(x, NULL));
3448: PetscFunctionReturn(PETSC_SUCCESS);
3449: }
3451: /*@C
3452: VecGetArray1dRead - Returns a pointer to a 1d contiguous array that contains this
3453: processor's portion of the vector data. You MUST call `VecRestoreArray1dRead()`
3454: when you no longer need access to the array.
3456: Logically Collective
3458: Input Parameters:
3459: + x - the vector
3460: . m - first dimension of two dimensional array
3461: - mstart - first index you will use in first coordinate direction (often 0)
3463: Output Parameter:
3464: . a - location to put pointer to the array
3466: Level: developer
3468: Notes:
3469: For a vector obtained from `DMCreateLocalVector()` mstart are likely
3470: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3471: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`.
3473: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3475: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3476: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3477: `VecGetArray2d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3478: @*/
3479: PetscErrorCode VecGetArray1dRead(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
3480: {
3481: PetscInt N;
3483: PetscFunctionBegin;
3487: PetscCall(VecGetLocalSize(x, &N));
3488: 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);
3489: PetscCall(VecGetArrayRead(x, (const PetscScalar **)a));
3490: *a -= mstart;
3491: PetscFunctionReturn(PETSC_SUCCESS);
3492: }
3494: /*@C
3495: VecRestoreArray1dRead - Restores a vector after `VecGetArray1dRead()` has been called.
3497: Logically Collective
3499: Input Parameters:
3500: + x - the vector
3501: . m - first dimension of two dimensional array
3502: . mstart - first index you will use in first coordinate direction (often 0)
3503: - a - location of pointer to array obtained from `VecGetArray1dRead()`
3505: Level: developer
3507: Notes:
3508: For regular PETSc vectors this routine does not involve any copies. For
3509: any special vectors that do not store local vector data in a contiguous
3510: array, this routine will copy the data back into the underlying
3511: vector data structure from the array obtained with `VecGetArray1dRead()`.
3513: This routine actually zeros out the a pointer.
3515: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3516: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3517: `VecGetArray1d()`, `VecRestoreArray2d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3518: @*/
3519: PetscErrorCode VecRestoreArray1dRead(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
3520: {
3521: PetscFunctionBegin;
3524: PetscCall(VecRestoreArrayRead(x, NULL));
3525: PetscFunctionReturn(PETSC_SUCCESS);
3526: }
3528: /*@C
3529: VecGetArray3dRead - Returns a pointer to a 3d contiguous array that contains this
3530: processor's portion of the vector data. You MUST call `VecRestoreArray3dRead()`
3531: when you no longer need access to the array.
3533: Logically Collective
3535: Input Parameters:
3536: + x - the vector
3537: . m - first dimension of three dimensional array
3538: . n - second dimension of three dimensional array
3539: . p - third dimension of three dimensional array
3540: . mstart - first index you will use in first coordinate direction (often 0)
3541: . nstart - first index in the second coordinate direction (often 0)
3542: - pstart - first index in the third coordinate direction (often 0)
3544: Output Parameter:
3545: . a - location to put pointer to the array
3547: Level: developer
3549: Notes:
3550: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3551: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3552: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3553: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3dRead()`.
3555: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3557: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3558: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3559: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3560: @*/
3561: PetscErrorCode VecGetArray3dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3562: {
3563: PetscInt i, N, j;
3564: const PetscScalar *aa;
3565: PetscScalar **b;
3567: PetscFunctionBegin;
3571: PetscCall(VecGetLocalSize(x, &N));
3572: 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);
3573: PetscCall(VecGetArrayRead(x, &aa));
3575: PetscCall(PetscMalloc(m * sizeof(PetscScalar **) + m * n * sizeof(PetscScalar *), a));
3576: b = (PetscScalar **)((*a) + m);
3577: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3578: for (i = 0; i < m; i++)
3579: for (j = 0; j < n; j++) b[i * n + j] = (PetscScalar *)aa + i * n * p + j * p - pstart;
3580: *a -= mstart;
3581: PetscFunctionReturn(PETSC_SUCCESS);
3582: }
3584: /*@C
3585: VecRestoreArray3dRead - Restores a vector after `VecGetArray3dRead()` has been called.
3587: Logically Collective
3589: Input Parameters:
3590: + x - the vector
3591: . m - first dimension of three dimensional array
3592: . n - second dimension of the three dimensional array
3593: . p - third dimension of the three dimensional array
3594: . mstart - first index you will use in first coordinate direction (often 0)
3595: . nstart - first index in the second coordinate direction (often 0)
3596: . pstart - first index in the third coordinate direction (often 0)
3597: - a - location of pointer to array obtained from `VecGetArray3dRead()`
3599: Level: developer
3601: Notes:
3602: For regular PETSc vectors this routine does not involve any copies. For
3603: any special vectors that do not store local vector data in a contiguous
3604: array, this routine will copy the data back into the underlying
3605: vector data structure from the array obtained with `VecGetArray()`.
3607: This routine actually zeros out the a pointer.
3609: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3610: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3611: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3612: @*/
3613: PetscErrorCode VecRestoreArray3dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3614: {
3615: void *dummy;
3617: PetscFunctionBegin;
3621: dummy = (void *)(*a + mstart);
3622: PetscCall(PetscFree(dummy));
3623: PetscCall(VecRestoreArrayRead(x, NULL));
3624: PetscFunctionReturn(PETSC_SUCCESS);
3625: }
3627: /*@C
3628: VecGetArray4dRead - Returns a pointer to a 4d contiguous array that contains this
3629: processor's portion of the vector data. You MUST call `VecRestoreArray4dRead()`
3630: when you no longer need access to the array.
3632: Logically Collective
3634: Input Parameters:
3635: + x - the vector
3636: . m - first dimension of four dimensional array
3637: . n - second dimension of four dimensional array
3638: . p - third dimension of four dimensional array
3639: . q - fourth dimension of four dimensional array
3640: . mstart - first index you will use in first coordinate direction (often 0)
3641: . nstart - first index in the second coordinate direction (often 0)
3642: . pstart - first index in the third coordinate direction (often 0)
3643: - qstart - first index in the fourth coordinate direction (often 0)
3645: Output Parameter:
3646: . a - location to put pointer to the array
3648: Level: beginner
3650: Notes:
3651: For a vector obtained from `DMCreateLocalVector()` mstart, nstart, and pstart are likely
3652: obtained from the corner indices obtained from `DMDAGetGhostCorners()` while for
3653: `DMCreateGlobalVector()` they are the corner indices from `DMDAGetCorners()`. In both cases
3654: the arguments from `DMDAGet[Ghost]Corners()` are reversed in the call to `VecGetArray3d()`.
3656: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3658: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3659: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3660: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3661: @*/
3662: PetscErrorCode VecGetArray4dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3663: {
3664: PetscInt i, N, j, k;
3665: const PetscScalar *aa;
3666: PetscScalar ***b, **c;
3668: PetscFunctionBegin;
3672: PetscCall(VecGetLocalSize(x, &N));
3673: 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);
3674: PetscCall(VecGetArrayRead(x, &aa));
3676: PetscCall(PetscMalloc(m * sizeof(PetscScalar ***) + m * n * sizeof(PetscScalar **) + m * n * p * sizeof(PetscScalar *), a));
3677: b = (PetscScalar ***)((*a) + m);
3678: c = (PetscScalar **)(b + m * n);
3679: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3680: for (i = 0; i < m; i++)
3681: for (j = 0; j < n; j++) b[i * n + j] = c + i * n * p + j * p - pstart;
3682: for (i = 0; i < m; i++)
3683: for (j = 0; j < n; j++)
3684: 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;
3685: *a -= mstart;
3686: PetscFunctionReturn(PETSC_SUCCESS);
3687: }
3689: /*@C
3690: VecRestoreArray4dRead - Restores a vector after `VecGetArray4d()` has been called.
3692: Logically Collective
3694: Input Parameters:
3695: + x - the vector
3696: . m - first dimension of four dimensional array
3697: . n - second dimension of the four dimensional array
3698: . p - third dimension of the four dimensional array
3699: . q - fourth dimension of the four dimensional array
3700: . mstart - first index you will use in first coordinate direction (often 0)
3701: . nstart - first index in the second coordinate direction (often 0)
3702: . pstart - first index in the third coordinate direction (often 0)
3703: . qstart - first index in the fourth coordinate direction (often 0)
3704: - a - location of pointer to array obtained from `VecGetArray4dRead()`
3706: Level: beginner
3708: Notes:
3709: For regular PETSc vectors this routine does not involve any copies. For
3710: any special vectors that do not store local vector data in a contiguous
3711: array, this routine will copy the data back into the underlying
3712: vector data structure from the array obtained with `VecGetArray()`.
3714: This routine actually zeros out the a pointer.
3716: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3717: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3718: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3719: @*/
3720: PetscErrorCode VecRestoreArray4dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3721: {
3722: void *dummy;
3724: PetscFunctionBegin;
3728: dummy = (void *)(*a + mstart);
3729: PetscCall(PetscFree(dummy));
3730: PetscCall(VecRestoreArrayRead(x, NULL));
3731: PetscFunctionReturn(PETSC_SUCCESS);
3732: }
3734: #if defined(PETSC_USE_DEBUG)
3736: /*@
3737: VecLockGet - Gets the current lock status of a vector
3739: Logically Collective
3741: Input Parameter:
3742: . x - the vector
3744: Output Parameter:
3745: . state - greater than zero indicates the vector is locked for read; less then zero indicates the vector is
3746: locked for write; equal to zero means the vector is unlocked, that is, it is free to read or write.
3748: Level: beginner
3750: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPush()`, `VecLockReadPop()`
3751: @*/
3752: PetscErrorCode VecLockGet(Vec x, PetscInt *state)
3753: {
3754: PetscFunctionBegin;
3756: *state = x->lock;
3757: PetscFunctionReturn(PETSC_SUCCESS);
3758: }
3760: PetscErrorCode VecLockGetLocation(Vec x, const char *file[], const char *func[], int *line)
3761: {
3762: PetscFunctionBegin;
3767: #if !PetscDefined(HAVE_THREADSAFETY)
3768: {
3769: const int index = x->lockstack.currentsize - 1;
3771: PetscCheck(index >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Corrupted vec lock stack, have negative index %d", index);
3772: *file = x->lockstack.file[index];
3773: *func = x->lockstack.function[index];
3774: *line = x->lockstack.line[index];
3775: }
3776: #else
3777: *file = NULL;
3778: *func = NULL;
3779: *line = 0;
3780: #endif
3781: PetscFunctionReturn(PETSC_SUCCESS);
3782: }
3784: /*@
3785: VecLockReadPush - Pushes a read-only lock on a vector to prevent it from writing
3787: Logically Collective
3789: Input Parameter:
3790: . x - the vector
3792: Level: beginner
3794: Notes:
3795: If this is set then calls to `VecGetArray()` or `VecSetValues()` or any other routines that change the vectors values will fail.
3797: The call can be nested, i.e., called multiple times on the same vector, but each `VecLockReadPush()` has to have one matching
3798: `VecLockReadPop()`, which removes the latest read-only lock.
3800: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPop()`, `VecLockGet()`
3801: @*/
3802: PetscErrorCode VecLockReadPush(Vec x)
3803: {
3804: PetscFunctionBegin;
3806: 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");
3807: #if !PetscDefined(HAVE_THREADSAFETY)
3808: {
3809: const char *file, *func;
3810: int index, line;
3812: if ((index = petscstack.currentsize - 2) == -1) {
3813: // vec was locked "outside" of petsc, either in user-land or main. the error message will
3814: // now show this function as the culprit, but it will include the stacktrace
3815: file = "unknown user-file";
3816: func = "unknown_user_function";
3817: line = 0;
3818: } else {
3819: PetscCheck(index >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected petscstack, have negative index %d", index);
3820: file = petscstack.file[index];
3821: func = petscstack.function[index];
3822: line = petscstack.line[index];
3823: }
3824: PetscStackPush_Private(x->lockstack, file, func, line, petscstack.petscroutine[index], PETSC_FALSE);
3825: }
3826: #endif
3827: PetscFunctionReturn(PETSC_SUCCESS);
3828: }
3830: /*@
3831: VecLockReadPop - Pops a read-only lock from a vector
3833: Logically Collective
3835: Input Parameter:
3836: . x - the vector
3838: Level: beginner
3840: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPush()`, `VecLockGet()`
3841: @*/
3842: PetscErrorCode VecLockReadPop(Vec x)
3843: {
3844: PetscFunctionBegin;
3846: PetscCheck(--x->lock >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Vector has been unlocked from read-only access too many times");
3847: #if !PetscDefined(HAVE_THREADSAFETY)
3848: {
3849: const char *previous = x->lockstack.function[x->lockstack.currentsize - 1];
3851: PetscStackPop_Private(x->lockstack, previous);
3852: }
3853: #endif
3854: PetscFunctionReturn(PETSC_SUCCESS);
3855: }
3857: /*@C
3858: VecLockWriteSet - Lock or unlock a vector for exclusive read/write access
3860: Logically Collective
3862: Input Parameters:
3863: + x - the vector
3864: - flg - PETSC_TRUE to lock the vector for exclusive read/write access; PETSC_FALSE to unlock it.
3866: Level: beginner
3868: Notes:
3869: The function is useful in split-phase computations, which usually have a begin phase and an end phase.
3870: One can call `VecLockWriteSet`(x,`PETSC_TRUE`) in the begin phase to lock a vector for exclusive
3871: access, and call `VecLockWriteSet`(x,`PETSC_FALSE`) in the end phase to unlock the vector from exclusive
3872: access. In this way, one is ensured no other operations can access the vector in between. The code may like
3874: .vb
3875: VecGetArray(x,&xdata); // begin phase
3876: VecLockWriteSet(v,PETSC_TRUE);
3878: Other operations, which can not access x anymore (they can access xdata, of course)
3880: VecRestoreArray(x,&vdata); // end phase
3881: VecLockWriteSet(v,PETSC_FALSE);
3882: .ve
3884: The call can not be nested on the same vector, in other words, one can not call `VecLockWriteSet`(x,`PETSC_TRUE`)
3885: again before calling `VecLockWriteSet`(v,`PETSC_FALSE`).
3887: .seealso: [](chapter_vectors), `Vec`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPush()`, `VecLockReadPop()`, `VecLockGet()`
3888: @*/
3889: PetscErrorCode VecLockWriteSet(Vec x, PetscBool flg)
3890: {
3891: PetscFunctionBegin;
3893: if (flg) {
3894: 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");
3895: 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");
3896: x->lock = -1;
3897: } else {
3898: 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");
3899: x->lock = 0;
3900: }
3901: PetscFunctionReturn(PETSC_SUCCESS);
3902: }
3904: /*@
3905: VecLockPush - Pushes a read-only lock on a vector to prevent it from writing
3907: Level: deprecated
3909: .seealso: [](chapter_vectors), `Vec`, `VecLockReadPush()`
3910: @*/
3911: PetscErrorCode VecLockPush(Vec x)
3912: {
3913: PetscFunctionBegin;
3914: PetscCall(VecLockReadPush(x));
3915: PetscFunctionReturn(PETSC_SUCCESS);
3916: }
3918: /*@
3919: VecLockPop - Pops a read-only lock from a vector
3921: Level: deprecated
3923: .seealso: [](chapter_vectors), `Vec`, `VecLockReadPop()`
3924: @*/
3925: PetscErrorCode VecLockPop(Vec x)
3926: {
3927: PetscFunctionBegin;
3928: PetscCall(VecLockReadPop(x));
3929: PetscFunctionReturn(PETSC_SUCCESS);
3930: }
3932: #endif