Actual source code: vector.c

  1: /*
  2:      Provides the interface functions for vector operations that do NOT have PetscScalar/PetscReal in the signature
  3:    These are the vector functions the user calls.
  4: */
  5: #include <petsc/private/vecimpl.h>
  6: #include <petsc/private/deviceimpl.h>

  8: /* Logging support */
  9: PetscClassId  VEC_CLASSID;
 10: PetscLogEvent VEC_View, VEC_Max, VEC_Min, VEC_Dot, VEC_MDot, VEC_TDot;
 11: PetscLogEvent VEC_Norm, VEC_Normalize, VEC_Scale, VEC_Shift, VEC_Copy, VEC_Set, VEC_AXPY, VEC_AYPX, VEC_WAXPY;
 12: PetscLogEvent VEC_MTDot, VEC_MAXPY, VEC_Swap, VEC_AssemblyBegin, VEC_ScatterBegin, VEC_ScatterEnd;
 13: PetscLogEvent VEC_AssemblyEnd, VEC_PointwiseMult, VEC_PointwiseDivide, VEC_Reciprocal, VEC_SetValues, VEC_Load, VEC_SetPreallocateCOO, VEC_SetValuesCOO;
 14: PetscLogEvent VEC_SetRandom, VEC_ReduceArithmetic, VEC_ReduceCommunication, VEC_ReduceBegin, VEC_ReduceEnd, VEC_Ops;
 15: PetscLogEvent VEC_DotNorm2, VEC_AXPBYPCZ;
 16: PetscLogEvent VEC_ViennaCLCopyFromGPU, VEC_ViennaCLCopyToGPU;
 17: PetscLogEvent VEC_CUDACopyFromGPU, VEC_CUDACopyToGPU;
 18: PetscLogEvent VEC_HIPCopyFromGPU, VEC_HIPCopyToGPU;

 20: /*@
 21:   VecStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
 22:   to be communicated to other processors during the `VecAssemblyBegin()`/`VecAssemblyEnd()` process

 24:   Not Collective

 26:   Input Parameter:
 27: . vec - the vector

 29:   Output Parameters:
 30: + nstash    - the size of the stash
 31: . reallocs  - the number of additional mallocs incurred in building the stash
 32: . bnstash   - the size of the block stash
 33: - breallocs - the number of additional mallocs incurred in building the block stash (from `VecSetValuesBlocked()`)

 35:   Level: advanced

 37: .seealso: [](ch_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecStashSetInitialSize()`, `VecStashView()`
 38: @*/
 39: PetscErrorCode VecStashGetInfo(Vec vec, PetscInt *nstash, PetscInt *reallocs, PetscInt *bnstash, PetscInt *breallocs)
 40: {
 41:   PetscFunctionBegin;
 42:   PetscCall(VecStashGetInfo_Private(&vec->stash, nstash, reallocs));
 43:   PetscCall(VecStashGetInfo_Private(&vec->bstash, bnstash, breallocs));
 44:   PetscFunctionReturn(PETSC_SUCCESS);
 45: }

 47: /*@
 48:   VecSetLocalToGlobalMapping - Sets a local numbering to global numbering used
 49:   by the routine `VecSetValuesLocal()` to allow users to insert vector entries
 50:   using a local (per-processor) numbering.

 52:   Logically Collective

 54:   Input Parameters:
 55: + x       - vector
 56: - mapping - mapping created with `ISLocalToGlobalMappingCreate()` or `ISLocalToGlobalMappingCreateIS()`

 58:   Level: intermediate

 60:   Notes:
 61:   All vectors obtained with `VecDuplicate()` from this vector inherit the same mapping.

 63:   Vectors obtained with `DMCreateGlobaVector()` will often have this attribute attached to the vector so this call is not needed

 65: .seealso: [](ch_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`, `VecSetValuesLocal()`,
 66:            `VecGetLocalToGlobalMapping()`, `VecSetValuesBlockedLocal()`
 67: @*/
 68: PetscErrorCode VecSetLocalToGlobalMapping(Vec x, ISLocalToGlobalMapping mapping)
 69: {
 70:   PetscFunctionBegin;
 73:   if (x->ops->setlocaltoglobalmapping) PetscUseTypeMethod(x, setlocaltoglobalmapping, mapping);
 74:   else PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->map, mapping));
 75:   PetscFunctionReturn(PETSC_SUCCESS);
 76: }

 78: /*@
 79:   VecGetLocalToGlobalMapping - Gets the local-to-global numbering set by `VecSetLocalToGlobalMapping()`

 81:   Not Collective

 83:   Input Parameter:
 84: . X - the vector

 86:   Output Parameter:
 87: . mapping - the mapping

 89:   Level: advanced

 91: .seealso: [](ch_vectors), `Vec`, `VecSetValuesLocal()`, `VecSetLocalToGlobalMapping()`
 92: @*/
 93: PetscErrorCode VecGetLocalToGlobalMapping(Vec X, ISLocalToGlobalMapping *mapping)
 94: {
 95:   PetscFunctionBegin;
 98:   PetscAssertPointer(mapping, 2);
 99:   if (X->ops->getlocaltoglobalmapping) PetscUseTypeMethod(X, getlocaltoglobalmapping, mapping);
100:   else *mapping = X->map->mapping;
101:   PetscFunctionReturn(PETSC_SUCCESS);
102: }

104: /*@
105:   VecAssemblyBegin - Begins assembling the vector; that is ensuring all the vector's entries are stored on the correct MPI process. This routine should
106:   be called after completing all calls to `VecSetValues()`.

108:   Collective

110:   Input Parameter:
111: . vec - the vector

113:   Level: beginner

115: .seealso: [](ch_vectors), `Vec`, `VecAssemblyEnd()`, `VecSetValues()`
116: @*/
117: PetscErrorCode VecAssemblyBegin(Vec vec)
118: {
119:   PetscFunctionBegin;
122:   PetscCall(VecStashViewFromOptions(vec, NULL, "-vec_view_stash"));
123:   PetscCall(PetscLogEventBegin(VEC_AssemblyBegin, vec, 0, 0, 0));
124:   PetscTryTypeMethod(vec, assemblybegin);
125:   PetscCall(PetscLogEventEnd(VEC_AssemblyBegin, vec, 0, 0, 0));
126:   PetscCall(PetscObjectStateIncrease((PetscObject)vec));
127:   PetscFunctionReturn(PETSC_SUCCESS);
128: }

130: /*@
131:   VecAssemblyEnd - Completes assembling the vector.  This routine should be called after `VecAssemblyBegin()`.

133:   Collective

135:   Input Parameter:
136: . vec - the vector

138:   Options Database Keys:
139: + -vec_view [viewertype][:...]      - Display the vector. See `VecViewFromOptions()`/`PetscObjectViewFromOptions()` for the possible arguments
140: - -vecstash_view [viewertype][:...] - Display the vector stash. See `VecStashViewFromOptions()`/`PetscObjectViewFromOptions()` for the possible arguments

142:   Level: beginner

144: .seealso: [](ch_vectors), `Vec`, `VecAssemblyBegin()`, `VecSetValues()`, `VecViewFromOptions()`, `VecStashViewFromOptions()`,
145:           `PetscObjectViewFromOptions()`
146: @*/
147: PetscErrorCode VecAssemblyEnd(Vec vec)
148: {
149:   PetscFunctionBegin;
151:   PetscCall(PetscLogEventBegin(VEC_AssemblyEnd, vec, 0, 0, 0));
153:   PetscTryTypeMethod(vec, assemblyend);
154:   PetscCall(PetscLogEventEnd(VEC_AssemblyEnd, vec, 0, 0, 0));
155:   PetscCall(VecViewFromOptions(vec, NULL, "-vec_view"));
156:   PetscFunctionReturn(PETSC_SUCCESS);
157: }

159: /*@
160:   VecSetPreallocationCOO - set preallocation for a vector using a coordinate format of the entries with global indices

162:   Collective

164:   Input Parameters:
165: + x     - vector being preallocated
166: . ncoo  - number of entries
167: - coo_i - entry indices

169:   Level: beginner

171:   Notes:
172:   This and `VecSetValuesCOO()` provide an alternative API to using `VecSetValues()` to provide vector values.

174:   This API is particularly efficient for use on GPUs.

176:   Entries can be repeated, see `VecSetValuesCOO()`. Negative indices are not allowed unless vector option `VEC_IGNORE_NEGATIVE_INDICES` is set,
177:   in which case they, along with the corresponding entries in `VecSetValuesCOO()`, are ignored. If vector option `VEC_NO_OFF_PROC_ENTRIES` is set,
178:   remote entries are ignored, otherwise, they will be properly added or inserted to the vector.

180:   The array coo_i[] may be freed immediately after calling this function.

182: .seealso: [](ch_vectors), `Vec`, `VecSetValuesCOO()`, `VecSetPreallocationCOOLocal()`
183: @*/
184: PetscErrorCode VecSetPreallocationCOO(Vec x, PetscCount ncoo, const PetscInt coo_i[])
185: {
186:   PetscFunctionBegin;
189:   if (ncoo) PetscAssertPointer(coo_i, 3);
190:   PetscCall(PetscLogEventBegin(VEC_SetPreallocateCOO, x, 0, 0, 0));
191:   PetscCall(PetscLayoutSetUp(x->map));
192:   if (x->ops->setpreallocationcoo) {
193:     PetscUseTypeMethod(x, setpreallocationcoo, ncoo, coo_i);
194:   } else {
195:     PetscInt ncoo_i;
196:     IS       is_coo_i;

198:     PetscCall(PetscIntCast(ncoo, &ncoo_i));
199:     PetscCall(ISCreateGeneral(PETSC_COMM_SELF, ncoo_i, coo_i, PETSC_COPY_VALUES, &is_coo_i));
200:     PetscCall(PetscObjectCompose((PetscObject)x, "__PETSc_coo_i", (PetscObject)is_coo_i));
201:     PetscCall(ISDestroy(&is_coo_i));
202:   }
203:   PetscCall(PetscLogEventEnd(VEC_SetPreallocateCOO, x, 0, 0, 0));
204:   PetscFunctionReturn(PETSC_SUCCESS);
205: }

207: /*@
208:   VecSetPreallocationCOOLocal - set preallocation for vectors using a coordinate format of the entries with local indices

210:   Collective

212:   Input Parameters:
213: + x     - vector being preallocated
214: . ncoo  - number of entries
215: - coo_i - row indices (local numbering; may be modified)

217:   Level: beginner

219:   Notes:
220:   This and `VecSetValuesCOO()` provide an alternative API to using `VecSetValuesLocal()` to provide vector values.

222:   This API is particularly efficient for use on GPUs.

224:   The local indices are translated using the local to global mapping, thus `VecSetLocalToGlobalMapping()` must have been
225:   called prior to this function.

227:   The indices coo_i may be modified within this function. They might be translated to corresponding global
228:   indices, but the caller should not rely on them having any specific value after this function returns. The arrays
229:   can be freed or reused immediately after this function returns.

231:   Entries can be repeated. Negative indices and remote indices might be allowed. see `VecSetPreallocationCOO()`.

233: .seealso: [](ch_vectors), `Vec`, `VecSetPreallocationCOO()`, `VecSetValuesCOO()`
234: @*/
235: PetscErrorCode VecSetPreallocationCOOLocal(Vec x, PetscCount ncoo, PetscInt coo_i[])
236: {
237:   PetscInt               ncoo_i;
238:   ISLocalToGlobalMapping ltog;

240:   PetscFunctionBegin;
243:   if (ncoo) PetscAssertPointer(coo_i, 3);
244:   PetscCall(PetscIntCast(ncoo, &ncoo_i));
245:   PetscCall(PetscLayoutSetUp(x->map));
246:   PetscCall(VecGetLocalToGlobalMapping(x, &ltog));
247:   if (ltog) PetscCall(ISLocalToGlobalMappingApply(ltog, ncoo_i, coo_i, coo_i));
248:   PetscCall(VecSetPreallocationCOO(x, ncoo, coo_i));
249:   PetscFunctionReturn(PETSC_SUCCESS);
250: }

252: /*@
253:   VecSetValuesCOO - set values at once in a vector preallocated using `VecSetPreallocationCOO()`

255:   Collective

257:   Input Parameters:
258: + x     - vector being set
259: . coo_v - the value array
260: - imode - the insert mode

262:   Level: beginner

264:   Note:
265:   This and `VecSetPreallocationCOO() or ``VecSetPreallocationCOOLocal()` provide an alternative API to using `VecSetValues()` to provide vector values.

267:   This API is particularly efficient for use on GPUs.

269:   The values must follow the order of the indices prescribed with `VecSetPreallocationCOO()` or `VecSetPreallocationCOOLocal()`.
270:   When repeated entries are specified in the COO indices the `coo_v` values are first properly summed, regardless of the value of `imode`.
271:   The imode flag indicates if `coo_v` must be added to the current values of the vector (`ADD_VALUES`) or overwritten (`INSERT_VALUES`).
272:   `VecAssemblyBegin()` and `VecAssemblyEnd()` do not need to be called after this routine. It automatically handles the assembly process.

274: .seealso: [](ch_vectors), `Vec`, `VecSetPreallocationCOO()`, `VecSetPreallocationCOOLocal()`, `VecSetValues()`
275: @*/
276: PetscErrorCode VecSetValuesCOO(Vec x, const PetscScalar coo_v[], InsertMode imode)
277: {
278:   PetscFunctionBegin;
282:   PetscCall(PetscLogEventBegin(VEC_SetValuesCOO, x, 0, 0, 0));
283:   if (x->ops->setvaluescoo) {
284:     PetscUseTypeMethod(x, setvaluescoo, coo_v, imode);
285:     PetscCall(PetscObjectStateIncrease((PetscObject)x));
286:   } else {
287:     IS              is_coo_i;
288:     const PetscInt *coo_i;
289:     PetscInt        ncoo;
290:     PetscMemType    mtype;

292:     PetscCall(PetscGetMemType(coo_v, &mtype));
293:     PetscCheck(mtype == PETSC_MEMTYPE_HOST, PetscObjectComm((PetscObject)x), PETSC_ERR_ARG_WRONG, "The basic VecSetValuesCOO() only supports v[] on host");
294:     PetscCall(PetscObjectQuery((PetscObject)x, "__PETSc_coo_i", (PetscObject *)&is_coo_i));
295:     PetscCheck(is_coo_i, PetscObjectComm((PetscObject)x), PETSC_ERR_COR, "Missing coo_i IS");
296:     PetscCall(ISGetLocalSize(is_coo_i, &ncoo));
297:     PetscCall(ISGetIndices(is_coo_i, &coo_i));
298:     if (imode != ADD_VALUES) PetscCall(VecZeroEntries(x));
299:     PetscCall(VecSetValues(x, ncoo, coo_i, coo_v, ADD_VALUES));
300:     PetscCall(ISRestoreIndices(is_coo_i, &coo_i));
301:     PetscCall(VecAssemblyBegin(x));
302:     PetscCall(VecAssemblyEnd(x));
303:   }
304:   PetscCall(PetscLogEventEnd(VEC_SetValuesCOO, x, 0, 0, 0));
305:   PetscFunctionReturn(PETSC_SUCCESS);
306: }

308: static PetscErrorCode VecPointwiseApply_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx, PetscLogEvent event, const char async_name[], PetscErrorCode (*const pointwise_op)(Vec, Vec, Vec))
309: {
310:   PetscErrorCode (*async_fn)(Vec, Vec, Vec, PetscDeviceContext) = NULL;

312:   PetscFunctionBegin;
319:   PetscCheckSameTypeAndComm(x, 2, y, 3);
320:   PetscCheckSameTypeAndComm(y, 3, w, 1);
321:   VecCheckSameSize(w, 1, x, 2);
322:   VecCheckSameSize(w, 1, y, 3);
323:   VecCheckAssembled(x);
324:   VecCheckAssembled(y);
325:   PetscCall(VecSetErrorIfLocked(w, 1));

328:   if (dctx) PetscCall(PetscObjectQueryFunction((PetscObject)w, async_name, &async_fn));
329:   if (event) PetscCall(PetscLogEventBegin(event, x, y, w, 0));
330:   if (async_fn) PetscCall((*async_fn)(w, x, y, dctx));
331:   else PetscCall((*pointwise_op)(w, x, y));
332:   if (event) PetscCall(PetscLogEventEnd(event, x, y, w, 0));
333:   PetscCall(PetscObjectStateIncrease((PetscObject)w));
334:   PetscFunctionReturn(PETSC_SUCCESS);
335: }

337: PetscErrorCode VecPointwiseMaxAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
338: {
339:   PetscFunctionBegin;
340:   // REVIEW ME: no log event?
341:   PetscCall(VecPointwiseApply_Private(w, x, y, dctx, 0, VecAsyncFnName(PointwiseMax), w->ops->pointwisemax));
342:   PetscFunctionReturn(PETSC_SUCCESS);
343: }

345: /*@
346:   VecPointwiseMax - Computes the component-wise maximum `w[i] = max(x[i], y[i])`.

348:   Logically Collective

350:   Input Parameters:
351: + x - the first input vector
352: - y - the second input vector

354:   Output Parameter:
355: . w - the result

357:   Level: advanced

359:   Notes:
360:   Any subset of the `x`, `y`, and `w` may be the same vector.

362:   For complex numbers compares only the real part

364: .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
365: @*/
366: PetscErrorCode VecPointwiseMax(Vec w, Vec x, Vec y)
367: {
368:   PetscFunctionBegin;
369:   PetscCall(VecPointwiseMaxAsync_Private(w, x, y, NULL));
370:   PetscFunctionReturn(PETSC_SUCCESS);
371: }

373: PetscErrorCode VecPointwiseMinAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
374: {
375:   PetscFunctionBegin;
376:   // REVIEW ME: no log event?
377:   PetscCall(VecPointwiseApply_Private(w, x, y, dctx, 0, VecAsyncFnName(PointwiseMin), w->ops->pointwisemin));
378:   PetscFunctionReturn(PETSC_SUCCESS);
379: }

381: /*@
382:   VecPointwiseMin - Computes the component-wise minimum `w[i] = min(x[i], y[i])`.

384:   Logically Collective

386:   Input Parameters:
387: + x - the first input vector
388: - y - the second input vector

390:   Output Parameter:
391: . w - the result

393:   Level: advanced

395:   Notes:
396:   Any subset of the `x`, `y`, and `w` may be the same vector.

398:   For complex numbers compares only the real part

400: .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
401: @*/
402: PetscErrorCode VecPointwiseMin(Vec w, Vec x, Vec y)
403: {
404:   PetscFunctionBegin;
405:   PetscCall(VecPointwiseMinAsync_Private(w, x, y, NULL));
406:   PetscFunctionReturn(PETSC_SUCCESS);
407: }

409: PetscErrorCode VecPointwiseMaxAbsAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
410: {
411:   PetscFunctionBegin;
412:   // REVIEW ME: no log event?
413:   PetscCall(VecPointwiseApply_Private(w, x, y, dctx, 0, VecAsyncFnName(PointwiseMaxAbs), w->ops->pointwisemaxabs));
414:   PetscFunctionReturn(PETSC_SUCCESS);
415: }

417: /*@
418:   VecPointwiseMaxAbs - Computes the component-wise maximum of the absolute values `w[i] = max(abs(x[i]), abs(y[i]))`.

420:   Logically Collective

422:   Input Parameters:
423: + x - the first input vector
424: - y - the second input vector

426:   Output Parameter:
427: . w - the result

429:   Level: advanced

431:   Notes:
432:   Any subset of the `x`, `y`, and `w` may be the same vector.

434: .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMin()`, `VecPointwiseMax()`, `VecMaxPointwiseDivide()`
435: @*/
436: PetscErrorCode VecPointwiseMaxAbs(Vec w, Vec x, Vec y)
437: {
438:   PetscFunctionBegin;
439:   PetscCall(VecPointwiseMaxAbsAsync_Private(w, x, y, NULL));
440:   PetscFunctionReturn(PETSC_SUCCESS);
441: }

443: PetscErrorCode VecPointwiseDivideAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
444: {
445:   PetscFunctionBegin;
446:   PetscCall(VecPointwiseApply_Private(w, x, y, dctx, VEC_PointwiseDivide, VecAsyncFnName(PointwiseDivide), w->ops->pointwisedivide));
447:   PetscFunctionReturn(PETSC_SUCCESS);
448: }

450: /*@
451:   VecPointwiseDivide - Computes the component-wise division `w[i] = x[i] / y[i]`.

453:   Logically Collective

455:   Input Parameters:
456: + x - the numerator vector
457: - y - the denominator vector

459:   Output Parameter:
460: . w - the result

462:   Level: advanced

464:   Note:
465:   Any subset of the `x`, `y`, and `w` may be the same vector.

467: .seealso: [](ch_vectors), `Vec`, `VecPointwiseMult()`, `VecPointwiseMax()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
468: @*/
469: PetscErrorCode VecPointwiseDivide(Vec w, Vec x, Vec y)
470: {
471:   PetscFunctionBegin;
472:   PetscCall(VecPointwiseDivideAsync_Private(w, x, y, NULL));
473:   PetscFunctionReturn(PETSC_SUCCESS);
474: }

476: #define VEC_POINTWISE_SIGN_LOOP(y, x, n, func) \
477:   PetscPragmaSIMD \
478:   for (PetscInt i = 0; i < (n); i++) (y)[i] = func(PetscRealPart((x)[i]))

480: #define VEC_POINTWISE_SIGN_DISPATCH(y, x, n, sign_type) \
481:   do { \
482:     switch (sign_type) { \
483:     case VEC_SIGN_ZERO_TO_ZERO: \
484:       VEC_POINTWISE_SIGN_LOOP(y, x, n, VecSignZeroToZero_Private); \
485:       break; \
486:     case VEC_SIGN_ZERO_TO_SIGNED_ZERO: \
487:       VEC_POINTWISE_SIGN_LOOP(y, x, n, VecSignZeroToSignedZero_Private); \
488:       break; \
489:     case VEC_SIGN_ZERO_TO_SIGNED_UNIT: \
490:       VEC_POINTWISE_SIGN_LOOP(y, x, n, VecSignZeroToSignedUnit_Private); \
491:       break; \
492:     default: \
493:       PetscUnreachable(); \
494:     } \
495:   } while (0)

497: PetscErrorCode VecPointwiseSignAsync_Private(Vec y, Vec x, VecSignMode sign_type, PetscDeviceContext dctx)
498: {
499:   PetscOffloadMask mask;
500:   PetscBool        is_host;
501:   PetscErrorCode (*async_fn)(Vec, Vec, VecSignMode, PetscDeviceContext) = NULL;

503:   PetscFunctionBegin;
508:   VecCheckSameSize(y, 1, x, 2);
509:   VecCheckAssembled(x);
510:   VecCheckAssembled(y);
511:   PetscCall(VecSetErrorIfLocked(y, 1));

513:   PetscCall(VecGetOffloadMask(x, &mask));
514:   is_host = PetscOffloadHost(mask) ? PETSC_TRUE : PETSC_FALSE;
515:   if (!is_host) PetscCall(PetscObjectQueryFunction((PetscObject)y, VEC_ASYNC_FN_NAME("PointwiseSign"), &async_fn));
516:   if (async_fn) PetscCall((*async_fn)(y, x, sign_type, dctx));
517:   else {
518:     PetscInt n;

520:     PetscCall(VecGetLocalSize(y, &n));
521:     if (y == x) {
522:       PetscScalar *_y;

524:       PetscCall(VecGetArray(y, &_y));
525:       VEC_POINTWISE_SIGN_DISPATCH(_y, _y, n, sign_type);
526:       PetscCall(VecRestoreArray(y, &_y));
527:     } else {
528:       PetscScalar       *_y;
529:       const PetscScalar *_x;

531:       PetscCall(VecGetArrayWrite(y, &_y));
532:       PetscCall(VecGetArrayRead(x, &_x));
533:       VEC_POINTWISE_SIGN_DISPATCH(_y, _x, n, sign_type);
534:       PetscCall(VecRestoreArrayRead(x, &_x));
535:       PetscCall(VecRestoreArrayWrite(y, &_y));
536:     }
537:   }
538:   PetscCall(PetscObjectStateIncrease((PetscObject)y));
539:   PetscFunctionReturn(PETSC_SUCCESS);
540: }

542: /*@
543:   VecPointwiseSign - Computes the component-wise sign `y[i] = sign(x[i])`.

545:   Logically Collective

547:   Input Parameters:
548: + x         - the input vector
549: - sign_type - `VecSignMode` indicating how the function should map zero values.

551:   Output Parameter:
552: . y - the sign vector of `x`

554:   Level: beginner

556: .seealso: [](ch_vectors), `Vec`, `VecSignMode`
557: @*/
558: PetscErrorCode VecPointwiseSign(Vec y, Vec x, VecSignMode sign_type)
559: {
560:   PetscFunctionBegin;
561:   PetscCall(VecPointwiseSignAsync_Private(y, x, sign_type, NULL));
562:   PetscFunctionReturn(PETSC_SUCCESS);
563: }

565: PetscErrorCode VecPointwiseMultAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
566: {
567:   PetscFunctionBegin;
569:   PetscCall(VecPointwiseApply_Private(w, x, y, dctx, VEC_PointwiseMult, VecAsyncFnName(PointwiseMult), w->ops->pointwisemult));
570:   PetscFunctionReturn(PETSC_SUCCESS);
571: }

573: /*@
574:   VecPointwiseMult - Computes the component-wise multiplication `w[i] = x[i] * y[i]`.

576:   Logically Collective

578:   Input Parameters:
579: + x - the first vector
580: - y - the second vector

582:   Output Parameter:
583: . w - the result

585:   Level: advanced

587:   Note:
588:   Any subset of the `x`, `y`, and `w` may be the same vector.

590: .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMax()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
591: @*/
592: PetscErrorCode VecPointwiseMult(Vec w, Vec x, Vec y)
593: {
594:   PetscFunctionBegin;
595:   PetscCall(VecPointwiseMultAsync_Private(w, x, y, NULL));
596:   PetscFunctionReturn(PETSC_SUCCESS);
597: }

599: /*@
600:   VecDuplicate - Creates a new vector of the same type as an existing vector.

602:   Collective

604:   Input Parameter:
605: . v - a vector to mimic

607:   Output Parameter:
608: . newv - location to put new vector

610:   Level: beginner

612:   Notes:
613:   `VecDuplicate()` DOES NOT COPY the vector entries, but rather allocates storage
614:   for the new vector.  Use `VecCopy()` to copy a vector.

616:   PETSc `Vec` always have all zero entries when created with `VecDuplicate()` until routines such as `VecSet()` or `VecSetValues()`
617:   are used to change the values. There is no reason to call `VecZeroEntries()` after creation.

619:   Use `VecDestroy()` to free the space. Use `VecDuplicateVecs()` to get several
620:   vectors.

622: .seealso: [](ch_vectors), `Vec`, `VecDestroy()`, `VecDuplicateVecs()`, `VecCreate()`, `VecCopy()`
623: @*/
624: PetscErrorCode VecDuplicate(Vec v, Vec *newv)
625: {
626:   PetscFunctionBegin;
628:   PetscAssertPointer(newv, 2);
630:   PetscUseTypeMethod(v, duplicate, newv);
631: #if PetscDefined(HAVE_DEVICE)
632:   if (v->boundtocpu && v->bindingpropagates) {
633:     PetscCall(VecSetBindingPropagates(*newv, PETSC_TRUE));
634:     PetscCall(VecBindToCPU(*newv, PETSC_TRUE));
635:   }
636: #endif
637:   PetscCall(PetscObjectStateIncrease((PetscObject)*newv));
638:   PetscFunctionReturn(PETSC_SUCCESS);
639: }

641: /*@
642:   VecDestroy - Destroys a vector.

644:   Collective

646:   Input Parameter:
647: . v - the vector

649:   Level: beginner

651: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecDuplicate()`, `VecDestroyVecs()`
652: @*/
653: PetscErrorCode VecDestroy(Vec *v)
654: {
655:   PetscFunctionBegin;
656:   PetscAssertPointer(v, 1);
657:   if (!*v) PetscFunctionReturn(PETSC_SUCCESS);
659:   if (--((PetscObject)*v)->refct > 0) {
660:     *v = NULL;
661:     PetscFunctionReturn(PETSC_SUCCESS);
662:   }

664:   PetscCall(PetscObjectSAWsViewOff((PetscObject)*v));
665:   /* destroy the internal part */
666:   PetscTryTypeMethod(*v, destroy);
667:   PetscCall(PetscFree((*v)->defaultrandtype));
668:   /* destroy the external/common part */
669:   PetscCall(PetscLayoutDestroy(&(*v)->map));
670:   PetscCall(PetscHeaderDestroy(v));
671:   PetscFunctionReturn(PETSC_SUCCESS);
672: }

674: /*@C
675:   VecDuplicateVecs - Creates several vectors of the same type as an existing vector.

677:   Collective

679:   Input Parameters:
680: + m - the number of vectors to obtain
681: - v - a vector to mimic

683:   Output Parameter:
684: . V - location to put pointer to array of vectors

686:   Level: intermediate

688:   Notes:
689:   Use `VecDestroyVecs()` to free the space. Use `VecDuplicate()` to form a single
690:   vector.

692:   PETSc `Vec` always have all zero entries when created with `VecDuplicateVecs()` until routines such as `VecSet()` or `VecSetValues()`
693:   are used to change the values. There is no reason to call `VecZeroEntries()` after creation.

695:   Some implementations ensure that the arrays accessed by each vector are contiguous in memory. Certain `VecMDot()` and `VecMAXPY()`
696:   implementations utilize this property to use BLAS 2 operations for higher efficiency. This is especially useful in `KSPGMRES`, see
697:   `KSPGMRESSetPreAllocateVectors()`.

699:   Fortran Note:
700: .vb
701:   Vec, pointer :: V(:)
702: .ve

704: .seealso: [](ch_vectors), `Vec`, [](ch_fortran), `VecDestroyVecs()`, `VecDuplicate()`, `VecCreate()`, `VecMDot()`, `VecMAXPY()`, `KSPGMRES`,
705:           `KSPGMRESSetPreAllocateVectors()`
706: @*/
707: PetscErrorCode VecDuplicateVecs(Vec v, PetscInt m, Vec *V[])
708: {
709:   PetscFunctionBegin;
711:   PetscAssertPointer(V, 3);
713:   PetscUseTypeMethod(v, duplicatevecs, m, V);
714: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
715:   if (v->boundtocpu && v->bindingpropagates) {
716:     PetscInt i;

718:     for (i = 0; i < m; i++) {
719:       /* Since ops->duplicatevecs might itself propagate the value of boundtocpu,
720:        * avoid unnecessary overhead by only calling VecBindToCPU() if the vector isn't already bound. */
721:       if (!(*V)[i]->boundtocpu) {
722:         PetscCall(VecSetBindingPropagates((*V)[i], PETSC_TRUE));
723:         PetscCall(VecBindToCPU((*V)[i], PETSC_TRUE));
724:       }
725:     }
726:   }
727: #endif
728:   PetscFunctionReturn(PETSC_SUCCESS);
729: }

731: /*@C
732:   VecDestroyVecs - Frees a block of vectors obtained with `VecDuplicateVecs()`.

734:   Collective

736:   Input Parameters:
737: + m  - the number of vectors previously obtained, if zero no vectors are destroyed
738: - vv - pointer to pointer to array of vector pointers, if `NULL` no vectors are destroyed

740:   Level: intermediate

742: .seealso: [](ch_vectors), `Vec`, [](ch_fortran), `VecDuplicateVecs()`, `VecDestroyVecsf90()`
743: @*/
744: PetscErrorCode VecDestroyVecs(PetscInt m, Vec *vv[])
745: {
746:   PetscFunctionBegin;
747:   PetscAssertPointer(vv, 2);
748:   PetscCheck(m >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Trying to destroy negative number of vectors %" PetscInt_FMT, m);
749:   if (!m || !*vv) {
750:     *vv = NULL;
751:     PetscFunctionReturn(PETSC_SUCCESS);
752:   }
755:   PetscCall((*(**vv)->ops->destroyvecs)(m, *vv));
756:   *vv = NULL;
757:   PetscFunctionReturn(PETSC_SUCCESS);
758: }

760: /*@
761:   VecViewFromOptions - View a vector based on values in the options database

763:   Collective

765:   Input Parameters:
766: + A    - the vector
767: . obj  - optional object that provides the options prefix for this viewing, use `NULL` to use the prefix of `A`
768: - name - command line option

770:   Options Database Key:
771: . -name [viewertype][:...] - option name and values. See `PetscObjectViewFromOptions()` for the possible arguments

773:   Level: intermediate

775: .seealso: [](ch_vectors), `Vec`, `VecView`, `PetscObjectViewFromOptions()`, `VecCreate()`
776: @*/
777: PetscErrorCode VecViewFromOptions(Vec A, PeOp PetscObject obj, const char name[])
778: {
779:   PetscFunctionBegin;
781:   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
782:   PetscFunctionReturn(PETSC_SUCCESS);
783: }

785: /*@
786:   VecView - Views a vector object.

788:   Collective

790:   Input Parameters:
791: + vec    - the vector
792: - viewer - an optional `PetscViewer` visualization context

794:   Level: beginner

796:   Notes:
797:   The available visualization contexts include
798: +     `PETSC_VIEWER_STDOUT_SELF` - for sequential vectors
799: .     `PETSC_VIEWER_STDOUT_WORLD` - for parallel vectors created on `PETSC_COMM_WORLD`
800: -     `PETSC_VIEWER_STDOUT`_(comm) - for parallel vectors created on MPI communicator comm

802:   You can change the format the vector is printed using the
803:   option `PetscViewerPushFormat()`.

805:   The user can open alternative viewers with
806: +    `PetscViewerASCIIOpen()` - Outputs vector to a specified file
807: .    `PetscViewerBinaryOpen()` - Outputs vector in binary to a
808:   specified file; corresponding input uses `VecLoad()`
809: .    `PetscViewerDrawOpen()` - Outputs vector to an X window display
810: .    `PetscViewerSocketOpen()` - Outputs vector to Socket viewer
811: -    `PetscViewerHDF5Open()` - Outputs vector to HDF5 file viewer

813:   The user can call `PetscViewerPushFormat()` to specify the output
814:   format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`,
815:   `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`).  Available formats include
816: +    `PETSC_VIEWER_DEFAULT` - default, prints vector contents
817: .    `PETSC_VIEWER_ASCII_MATLAB` - prints vector contents in MATLAB format
818: .    `PETSC_VIEWER_ASCII_INDEX` - prints vector contents, including indices of vector elements
819: -    `PETSC_VIEWER_ASCII_COMMON` - prints vector contents, using a
820:   format common among all vector types

822:   You can pass any number of vector objects, or other PETSc objects to the same viewer.

824:   In the debugger you can do call `VecView`(v,0) to display the vector. (The same holds for any PETSc object viewer).

826:   Notes for binary viewer:
827:   If you pass multiple vectors to a binary viewer you can read them back in the same order
828:   with `VecLoad()`.

830:   If the blocksize of the vector is greater than one then you must provide a unique prefix to
831:   the vector with `PetscObjectSetOptionsPrefix`((`PetscObject`)vec,"uniqueprefix"); BEFORE calling `VecView()` on the
832:   vector to be stored and then set that same unique prefix on the vector that you pass to `VecLoad()`. The blocksize
833:   information is stored in an ASCII file with the same name as the binary file plus a ".info" appended to the
834:   filename. If you copy the binary file, make sure you copy the associated .info file with it.

836:   See the manual page for `VecLoad()` on the exact format the binary viewer stores
837:   the values in the file.

839:   Notes for HDF5 Viewer:
840:   The name of the `Vec` (given with `PetscObjectSetName()` is the name that is used
841:   for the object in the HDF5 file. If you wish to store the same Vec into multiple
842:   datasets in the same file (typically with different values), you must change its
843:   name each time before calling the `VecView()`. To load the same vector,
844:   the name of the Vec object passed to `VecLoad()` must be the same.

846:   If the block size of the vector is greater than 1 then it is used as the first dimension in the HDF5 array.
847:   If the function `PetscViewerHDF5SetBaseDimension2()`is called then even if the block size is one it will
848:   be used as the first dimension in the HDF5 array (that is the HDF5 array will always be two dimensional)
849:   See also `PetscViewerHDF5SetTimestep()` which adds an additional complication to reading and writing `Vec`
850:   with the HDF5 viewer.

852: .seealso: [](ch_vectors), `Vec`, `VecViewFromOptions()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscDrawLGCreate()`,
853:           `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `VecLoad()`, `PetscViewerCreate()`,
854:           `PetscRealView()`, `PetscScalarView()`, `PetscIntView()`, `PetscViewerHDF5SetTimestep()`
855: @*/
856: PetscErrorCode VecView(Vec vec, PetscViewer viewer)
857: {
858:   PetscBool         isascii;
859:   PetscViewerFormat format;
860:   PetscMPIInt       size;

862:   PetscFunctionBegin;
865:   VecCheckAssembled(vec);
866:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec), &viewer));
868:   PetscCall(PetscViewerGetFormat(viewer, &format));
869:   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size));
870:   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(PETSC_SUCCESS);

872:   PetscCheck(!vec->stash.n && !vec->bstash.n, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call VecAssemblyBegin/End() before viewing this vector");

874:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
875:   if (isascii) {
876:     PetscInt rows, bs;

878:     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)vec, viewer));
879:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
880:       PetscCall(PetscViewerASCIIPushTab(viewer));
881:       PetscCall(VecGetSize(vec, &rows));
882:       PetscCall(VecGetBlockSize(vec, &bs));
883:       if (bs != 1) {
884:         PetscCall(PetscViewerASCIIPrintf(viewer, "length=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n", rows, bs));
885:       } else {
886:         PetscCall(PetscViewerASCIIPrintf(viewer, "length=%" PetscInt_FMT "\n", rows));
887:       }
888:       PetscCall(PetscViewerASCIIPopTab(viewer));
889:     }
890:   }
891:   PetscCall(VecLockReadPush(vec));
892:   PetscCall(PetscLogEventBegin(VEC_View, vec, viewer, 0, 0));
893:   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && vec->ops->viewnative) {
894:     PetscUseTypeMethod(vec, viewnative, viewer);
895:   } else {
896:     PetscUseTypeMethod(vec, view, viewer);
897:   }
898:   PetscCall(VecLockReadPop(vec));
899:   PetscCall(PetscLogEventEnd(VEC_View, vec, viewer, 0, 0));
900:   PetscFunctionReturn(PETSC_SUCCESS);
901: }

903: #if defined(PETSC_USE_DEBUG)
904: #include <../src/sys/totalview/tv_data_display.h>
905: PETSC_UNUSED static int TV_display_type(const struct _p_Vec *v)
906: {
907:   const PetscScalar *values;
908:   char               type[32];

910:   TV_add_row("Local rows", "int", &v->map->n);
911:   TV_add_row("Global rows", "int", &v->map->N);
912:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)v)->type_name);
913:   PetscCall(VecGetArrayRead((Vec)v, &values));
914:   PetscCall(PetscSNPrintf(type, 32, "double[%" PetscInt_FMT "]", v->map->n));
915:   TV_add_row("values", type, values);
916:   PetscCall(VecRestoreArrayRead((Vec)v, &values));
917:   return TV_format_OK;
918: }
919: #endif

921: /*@C
922:   VecViewNative - Views a vector object with the original type specific viewer

924:   Collective

926:   Input Parameters:
927: + vec    - the vector
928: - viewer - an optional `PetscViewer` visualization context

930:   Level: developer

932:   Note:
933:   This can be used with, for example, vectors obtained with `DMCreateGlobalVector()` for a `DMDA` to display the vector
934:   in the PETSc storage format (each MPI process values follow the previous MPI processes) instead of the "natural" grid
935:   ordering.

937: .seealso: [](ch_vectors), `Vec`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscDrawLGCreate()`, `VecView()`,
938:           `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `VecLoad()`, `PetscViewerCreate()`,
939:           `PetscRealView()`, `PetscScalarView()`, `PetscIntView()`, `PetscViewerHDF5SetTimestep()`
940: @*/
941: PetscErrorCode VecViewNative(Vec vec, PetscViewer viewer)
942: {
943:   PetscFunctionBegin;
946:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec), &viewer));
948:   PetscUseTypeMethod(vec, viewnative, viewer);
949:   PetscFunctionReturn(PETSC_SUCCESS);
950: }

952: /*@
953:   VecGetSize - Returns the global number of elements of the vector.

955:   Not Collective

957:   Input Parameter:
958: . x - the vector

960:   Output Parameter:
961: . size - the global length of the vector

963:   Level: beginner

965: .seealso: [](ch_vectors), `Vec`, `VecGetLocalSize()`
966: @*/
967: PetscErrorCode VecGetSize(Vec x, PetscInt *size)
968: {
969:   PetscFunctionBegin;
971:   PetscAssertPointer(size, 2);
973:   PetscUseTypeMethod(x, getsize, size);
974:   PetscFunctionReturn(PETSC_SUCCESS);
975: }

977: /*@
978:   VecGetLocalSize - Returns the number of elements of the vector stored
979:   in local memory (that is on this MPI process)

981:   Not Collective

983:   Input Parameter:
984: . x - the vector

986:   Output Parameter:
987: . size - the length of the local piece of the vector

989:   Level: beginner

991: .seealso: [](ch_vectors), `Vec`, `VecGetSize()`
992: @*/
993: PetscErrorCode VecGetLocalSize(Vec x, PetscInt *size)
994: {
995:   PetscFunctionBegin;
997:   PetscAssertPointer(size, 2);
999:   PetscUseTypeMethod(x, getlocalsize, size);
1000:   PetscFunctionReturn(PETSC_SUCCESS);
1001: }

1003: /*@
1004:   VecGetOwnershipRange - Returns the range of indices owned by
1005:   this process. The vector is laid out with the
1006:   first `n1` elements on the first processor, next `n2` elements on the
1007:   second, etc.  For certain parallel layouts this range may not be
1008:   well defined.

1010:   Not Collective

1012:   Input Parameter:
1013: . x - the vector

1015:   Output Parameters:
1016: + low  - the first local element, pass in `NULL` if not interested
1017: - high - one more than the last local element, pass in `NULL` if not interested

1019:   Level: beginner

1021:   Notes:
1022:   If the `Vec` was obtained from a `DM` with `DMCreateGlobalVector()`, then the range values are determined by the specific `DM`.

1024:   If the `Vec` was created directly the range values are determined by the local size passed to `VecSetSizes()` or `VecCreateMPI()`.
1025:   If `PETSC_DECIDE` was passed as the local size, then the vector uses default values for the range using `PetscSplitOwnership()`.

1027:   The high argument is one more than the last element stored locally.

1029:   For certain `DM`, such as `DMDA`, it is better to use `DM` specific routines, such as `DMDAGetGhostCorners()`, to determine
1030:   the local values in the vector.

1032: .seealso: [](ch_vectors), `Vec`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `VecGetOwnershipRanges()`, `PetscSplitOwnership()`,
1033:           `VecSetSizes()`, `VecCreateMPI()`, `PetscLayout`, `DMDAGetGhostCorners()`, `DM`
1034: @*/
1035: PetscErrorCode VecGetOwnershipRange(Vec x, PetscInt *low, PetscInt *high)
1036: {
1037:   PetscFunctionBegin;
1040:   if (low) PetscAssertPointer(low, 2);
1041:   if (high) PetscAssertPointer(high, 3);
1042:   if (low) *low = x->map->rstart;
1043:   if (high) *high = x->map->rend;
1044:   PetscFunctionReturn(PETSC_SUCCESS);
1045: }

1047: /*@C
1048:   VecGetOwnershipRanges - Returns the range of indices owned by EACH processor,
1049:   The vector is laid out with the
1050:   first `n1` elements on the first processor, next `n2` elements on the
1051:   second, etc.  For certain parallel layouts this range may not be
1052:   well defined.

1054:   Not Collective

1056:   Input Parameter:
1057: . x - the vector

1059:   Output Parameter:
1060: . ranges - array of length `size` + 1 with the start and end+1 for each process

1062:   Level: beginner

1064:   Notes:
1065:   If the `Vec` was obtained from a `DM` with `DMCreateGlobalVector()`, then the range values are determined by the specific `DM`.

1067:   If the `Vec` was created directly the range values are determined by the local size passed to `VecSetSizes()` or `VecCreateMPI()`.
1068:   If `PETSC_DECIDE` was passed as the local size, then the vector uses default values for the range using `PetscSplitOwnership()`.

1070:   The high argument is one more than the last element stored locally.

1072:   For certain `DM`, such as `DMDA`, it is better to use `DM` specific routines, such as `DMDAGetGhostCorners()`, to determine
1073:   the local values in the vector.

1075:   The high argument is one more than the last element stored locally.

1077:   If `ranges` are used after all vectors that share the ranges has been destroyed, then the program will crash accessing `ranges`.

1079:   Fortran Note:
1080:   The argument `ranges` must be declared as
1081: .vb
1082:   PetscInt, pointer :: ranges(:)
1083: .ve
1084:   and you have to return it with a call to `VecRestoreOwnershipRanges()` when no longer needed

1086: .seealso: [](ch_vectors), `Vec`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `VecGetOwnershipRange()`, `PetscSplitOwnership()`,
1087:           `VecSetSizes()`, `VecCreateMPI()`, `PetscLayout`, `DMDAGetGhostCorners()`, `DM`
1088: @*/
1089: PetscErrorCode VecGetOwnershipRanges(Vec x, const PetscInt *ranges[])
1090: {
1091:   PetscFunctionBegin;
1094:   PetscCall(PetscLayoutGetRanges(x->map, ranges));
1095:   PetscFunctionReturn(PETSC_SUCCESS);
1096: }

1098: /*@
1099:   VecSetOption - Sets an option for controlling a vector's behavior with `VecSetValues()` and related routines

1101:   Collective

1103:   Input Parameters:
1104: + x    - the vector
1105: . op   - the `VecOption`
1106: - flag - turn the option on or off

1108:   Level: intermediate

1110: .seealso: [](ch_vectors), `Vec`, `VecSetValues()`, `VecOption`, `MatSetOption()`
1111: @*/
1112: PetscErrorCode VecSetOption(Vec x, VecOption op, PetscBool flag)
1113: {
1114:   PetscFunctionBegin;
1117:   PetscTryTypeMethod(x, setoption, op, flag);
1118:   PetscFunctionReturn(PETSC_SUCCESS);
1119: }

1121: /* Default routines for obtaining and releasing; */
1122: /* may be used by any implementation */
1123: PetscErrorCode VecDuplicateVecs_Default(Vec w, PetscInt m, Vec *V[])
1124: {
1125:   PetscFunctionBegin;
1126:   PetscCheck(m > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "m must be > 0: m = %" PetscInt_FMT, m);
1127:   PetscCall(PetscMalloc1(m, V));
1128:   for (PetscInt i = 0; i < m; i++) PetscCall(VecDuplicate(w, *V + i));
1129:   PetscFunctionReturn(PETSC_SUCCESS);
1130: }

1132: PetscErrorCode VecDestroyVecs_Default(PetscInt m, Vec v[])
1133: {
1134:   PetscInt i;

1136:   PetscFunctionBegin;
1137:   PetscAssertPointer(v, 2);
1138:   for (i = 0; i < m; i++) PetscCall(VecDestroy(&v[i]));
1139:   PetscCall(PetscFree(v));
1140:   PetscFunctionReturn(PETSC_SUCCESS);
1141: }

1143: /*@
1144:   VecResetArray - Resets a vector to use its default memory. Call this
1145:   after the use of `VecPlaceArray()`.

1147:   Not Collective

1149:   Input Parameter:
1150: . vec - the vector

1152:   Level: developer

1154: .seealso: [](ch_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecPlaceArray()`
1155: @*/
1156: PetscErrorCode VecResetArray(Vec vec)
1157: {
1158:   PetscFunctionBegin;
1161:   PetscUseTypeMethod(vec, resetarray);
1162:   PetscCall(PetscObjectStateIncrease((PetscObject)vec));
1163:   PetscFunctionReturn(PETSC_SUCCESS);
1164: }

1166: /*@
1167:   VecLoad - Loads a vector that has been stored in binary or HDF5 format
1168:   with `VecView()`.

1170:   Collective

1172:   Input Parameters:
1173: + vec    - the newly loaded vector, this needs to have been created with `VecCreate()` or
1174:            some related function before the call to `VecLoad()`.
1175: - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` or
1176:            HDF5 file viewer, obtained from `PetscViewerHDF5Open()`

1178:   Level: intermediate

1180:   Notes:
1181:   Defaults to the standard `VECSEQ` or `VECMPI`, if you want some other type of `Vec` call `VecSetFromOptions()`
1182:   before calling this.

1184:   The input file must contain the full global vector, as
1185:   written by the routine `VecView()`.

1187:   If the type or size of `vec` is not set before a call to `VecLoad()`, PETSc
1188:   sets the type and the local and global sizes based on the vector it is reading in. If type and/or
1189:   sizes are already set, then the same are used.

1191:   If using the binary viewer and the blocksize of the vector is greater than one then you must provide a unique prefix to
1192:   the vector with `PetscObjectSetOptionsPrefix`((`PetscObject`)vec,"uniqueprefix"); BEFORE calling `VecView()` on the
1193:   vector to be stored and then set that same unique prefix on the vector that you pass to VecLoad(). The blocksize
1194:   information is stored in an ASCII file with the same name as the binary file plus a ".info" appended to the
1195:   filename. If you copy the binary file, make sure you copy the associated .info file with it.

1197:   If using HDF5, you must assign the `Vec` the same name as was used in the Vec
1198:   that was stored in the file using `PetscObjectSetName()`. Otherwise you will
1199:   get the error message: "Cannot H5DOpen2() with `Vec` name NAMEOFOBJECT".

1201:   If the HDF5 file contains a two dimensional array the first dimension is treated as the block size
1202:   in loading the vector. Hence, for example, using MATLAB notation h5create('vector.dat','/Test_Vec',[27 1]);
1203:   will load a vector of size 27 and block size 27 thus resulting in all 27 entries being on the first process of
1204:   vectors communicator and the rest of the processes having zero entries

1206:   Notes for advanced users when using the binary viewer:
1207:   Most users should not need to know the details of the binary storage
1208:   format, since `VecLoad()` and `VecView()` completely hide these details.
1209:   But for anyone who's interested, the standard binary vector storage
1210:   format is
1211: .vb
1212:      PetscInt    VEC_FILE_CLASSID
1213:      PetscInt    number of rows
1214:      PetscScalar *values of all entries
1215: .ve

1217:   In addition, PETSc automatically uses byte swapping to work on all machines; the files
1218:   are written ALWAYS using big-endian ordering. On small-endian machines the numbers
1219:   are converted to the small-endian format when they are read in from the file.
1220:   See PetscBinaryRead() and PetscBinaryWrite() to see how this may be done.

1222: .seealso: [](ch_vectors), `Vec`, `PetscViewerBinaryOpen()`, `VecView()`, `MatLoad()`
1223: @*/
1224: PetscErrorCode VecLoad(Vec vec, PetscViewer viewer)
1225: {
1226:   PetscViewerFormat format;

1228:   PetscFunctionBegin;
1231:   PetscCheckSameComm(vec, 1, viewer, 2);

1233:   PetscCall(VecSetErrorIfLocked(vec, 1));
1234:   if (!((PetscObject)vec)->type_name && !vec->ops->create) PetscCall(VecSetType(vec, VECSTANDARD));
1235:   PetscCall(PetscLogEventBegin(VEC_Load, viewer, 0, 0, 0));
1236:   PetscCall(PetscViewerGetFormat(viewer, &format));
1237:   if (format == PETSC_VIEWER_NATIVE && vec->ops->loadnative) {
1238:     PetscUseTypeMethod(vec, loadnative, viewer);
1239:   } else {
1240:     PetscUseTypeMethod(vec, load, viewer);
1241:   }
1242:   PetscCall(PetscLogEventEnd(VEC_Load, viewer, 0, 0, 0));
1243:   PetscFunctionReturn(PETSC_SUCCESS);
1244: }

1246: /*@
1247:   VecReciprocal - Replaces each component of a vector by its reciprocal.

1249:   Logically Collective

1251:   Input Parameter:
1252: . vec - the vector

1254:   Output Parameter:
1255: . vec - the vector reciprocal

1257:   Level: intermediate

1259:   Note:
1260:   Vector entries with value 0.0 are not changed

1262: .seealso: [](ch_vectors), `Vec`, `VecLog()`, `VecExp()`, `VecSqrtAbs()`
1263: @*/
1264: PetscErrorCode VecReciprocal(Vec vec)
1265: {
1266:   PetscFunctionBegin;
1267:   PetscCall(VecReciprocalAsync_Private(vec, NULL));
1268:   PetscFunctionReturn(PETSC_SUCCESS);
1269: }

1271: /*@C
1272:   VecSetOperation - Allows the user to override a particular vector operation.

1274:   Logically Collective; No Fortran Support

1276:   Input Parameters:
1277: + vec - The vector to modify
1278: . op  - The name of the operation
1279: - f   - The function that provides the operation.

1281:   Level: advanced

1283:   Example Usage:
1284: .vb
1285:   // some new VecView() implementation, must have the same signature as the function it seeks
1286:   // to replace
1287:   PetscErrorCode UserVecView(Vec x, PetscViewer viewer)
1288:   {
1289:     PetscFunctionBeginUser;
1290:     // ...
1291:     PetscFunctionReturn(PETSC_SUCCESS);
1292:   }

1294:   // Create a VECMPI which has a pre-defined VecView() implementation
1295:   VecCreateMPI(comm, n, N, &x);
1296:   // Calls the VECMPI implementation for VecView()
1297:   VecView(x, viewer);

1299:   VecSetOperation(x, VECOP_VIEW, (PetscErrorCodeFn *)UserVecView);
1300:   // Now calls UserVecView()
1301:   VecView(x, viewer);
1302: .ve

1304:   Notes:
1305:   `f` may be `NULL` to remove the operation from `vec`. Depending on the operation this may be
1306:   allowed, however some always expect a valid function. In these cases an error will be raised
1307:   when calling the interface routine in question.

1309:   See `VecOperation` for an up-to-date list of override-able operations. The operations listed
1310:   there have the form `VECOP_<OPERATION>`, where `<OPERATION>` is the suffix (in all capital
1311:   letters) of the public interface routine (e.g., `VecView()` -> `VECOP_VIEW`).

1313:   Overriding a particular `Vec`'s operation has no affect on any other `Vec`s past, present,
1314:   or future. The user should also note that overriding a method is "destructive"; the previous
1315:   method is not retained in any way.

1317:   Each function MUST return `PETSC_SUCCESS` on success and
1318:   nonzero on failure.

1320: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecGetOperation()`, `MatSetOperation()`, `MatShellSetOperation()`
1321: @*/
1322: PetscErrorCode VecSetOperation(Vec vec, VecOperation op, PetscErrorCodeFn *f)
1323: {
1324:   PetscFunctionBegin;
1326:   if (op == VECOP_VIEW && !vec->ops->viewnative) {
1327:     vec->ops->viewnative = vec->ops->view;
1328:   } else if (op == VECOP_LOAD && !vec->ops->loadnative) {
1329:     vec->ops->loadnative = vec->ops->load;
1330:   }
1331:   ((PetscErrorCodeFn **)vec->ops)[(int)op] = f;
1332:   PetscFunctionReturn(PETSC_SUCCESS);
1333: }

1335: /*@
1336:   VecStashSetInitialSize - sets the sizes of the vec-stash, that is
1337:   used during the assembly process to store values that belong to
1338:   other processors.

1340:   Not Collective, different processes can have different size stashes

1342:   Input Parameters:
1343: + vec   - the vector
1344: . size  - the initial size of the stash.
1345: - bsize - the initial size of the block-stash(if used).

1347:   Options Database Keys:
1348: + -vecstash_initial_size size or size0,size1,...,sizep-1           - set initial size
1349: - -vecstash_block_initial_size bsize or bsize0,bsize1,...,bsizep-1 - set initial block size

1351:   Level: intermediate

1353:   Notes:
1354:   The block-stash is used for values set with `VecSetValuesBlocked()` while
1355:   the stash is used for values set with `VecSetValues()`

1357:   Run with the option -info and look for output of the form
1358:   VecAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
1359:   to determine the appropriate value, MM, to use for size and
1360:   VecAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
1361:   to determine the value, BMM to use for bsize

1363:   PETSc attempts to smartly manage the stash size so there is little likelihood setting a
1364:   a specific value here will affect performance

1366: .seealso: [](ch_vectors), `Vec`, `VecSetBlockSize()`, `VecSetValues()`, `VecSetValuesBlocked()`, `VecStashView()`
1367: @*/
1368: PetscErrorCode VecStashSetInitialSize(Vec vec, PetscInt size, PetscInt bsize)
1369: {
1370:   PetscFunctionBegin;
1372:   PetscCall(VecStashSetInitialSize_Private(&vec->stash, size));
1373:   PetscCall(VecStashSetInitialSize_Private(&vec->bstash, bsize));
1374:   PetscFunctionReturn(PETSC_SUCCESS);
1375: }

1377: /*@
1378:   VecSetRandom - Sets all components of a vector to random numbers.

1380:   Logically Collective

1382:   Input Parameters:
1383: + x    - the vector
1384: - rctx - the random number context, formed by `PetscRandomCreate()`, or use `NULL` and it will create one internally.

1386:   Output Parameter:
1387: . x - the vector

1389:   Example of Usage:
1390: .vb
1391:      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
1392:      VecSetRandom(x,rctx);
1393:      PetscRandomDestroy(&rctx);
1394: .ve

1396:   Level: intermediate

1398: .seealso: [](ch_vectors), `Vec`, `VecSet()`, `VecSetValues()`, `PetscRandomCreate()`, `PetscRandomDestroy()`
1399: @*/
1400: PetscErrorCode VecSetRandom(Vec x, PetscRandom rctx)
1401: {
1402:   PetscRandom randObj = NULL;

1404:   PetscFunctionBegin;
1408:   VecCheckAssembled(x);
1409:   PetscCall(VecSetErrorIfLocked(x, 1));

1411:   if (!rctx) {
1412:     PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject)x), &randObj));
1413:     PetscCall(PetscRandomSetType(randObj, x->defaultrandtype));
1414:     PetscCall(PetscRandomSetFromOptions(randObj));
1415:     rctx = randObj;
1416:   }

1418:   PetscCall(PetscLogEventBegin(VEC_SetRandom, x, rctx, 0, 0));
1419:   PetscUseTypeMethod(x, setrandom, rctx);
1420:   PetscCall(PetscLogEventEnd(VEC_SetRandom, x, rctx, 0, 0));

1422:   PetscCall(PetscRandomDestroy(&randObj));
1423:   PetscCall(PetscObjectStateIncrease((PetscObject)x));
1424:   PetscFunctionReturn(PETSC_SUCCESS);
1425: }

1427: /*@
1428:   VecSetRandomGaussian - Fills a vector with Gaussian random values of the given mean and standard deviation.

1430:   Collective

1432:   Input Parameters:
1433: + v       - the vector to fill
1434: . rng     - PETSc random number generator
1435: . mean    - desired mean of the Gaussian samples
1436: - std_dev - desired standard deviation

1438:   Level: advanced

1440:   Note:
1441:   For complex builds where `PetscScalar` is complex the imaginary part of all the vector entries is zero

1443:   Developer Note:
1444:   Uses the Box-Muller transform to generate normally distributed random numbers
1445:   from uniform random numbers. Handles edge cases where uniform random values
1446:   approach 0 or 1.

1448: .seealso: [](ch_vectors), [](ch_da), `PetscDA`, `PetscRandom`, `PetscRandomSetInterval()`, `VecSetRandom()`
1449: @*/
1450: PetscErrorCode VecSetRandomGaussian(Vec v, PetscRandom rng, PetscReal mean, PetscReal std_dev)
1451: {
1452:   PetscInt        n, i;
1453:   PetscScalar    *array;
1454:   PetscReal       u1, u2;
1455:   PetscReal       gauss_sample1, gauss_sample2, magnitude, theta;
1456:   const PetscReal min_uniform     = PETSC_MACHINE_EPSILON;
1457:   const PetscInt  max_retry_count = 100;

1459:   PetscFunctionBegin;
1464:   PetscCheck(!PetscIsInfOrNanReal(mean), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mean must be a finite real number");
1465:   PetscCheck(std_dev >= 0.0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Standard deviation must be non-negative, got %g", (double)std_dev);
1466:   PetscCheck(!PetscIsInfOrNanReal(std_dev), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Standard deviation must be a finite real number");

1468:   PetscCall(VecGetLocalSize(v, &n));
1469:   if (n == 0) PetscFunctionReturn(PETSC_SUCCESS);

1471:   if (std_dev == 0.0) {
1472:     PetscCall(VecSet(v, mean));
1473:     PetscFunctionReturn(PETSC_SUCCESS);
1474:   }

1476:   PetscCall(VecGetArrayWrite(v, &array));

1478:   /*
1479:     Generate Gaussian-distributed random values using the Box-Muller transform.
1480:     This transform converts pairs of uniform random variables U1, U2 ~ Uniform(0,1)
1481:     into pairs of independent standard normal variables Z0, Z1 ~ N(0,1):
1482:       Z0 = sqrt(-2 * ln(U1)) * cos(2pi * U2)
1483:       Z1 = sqrt(-2 * ln(U1)) * sin(2pi * U2)
1484:     Then scale and shift to get desired mean and standard deviation.
1485:   */
1486:   for (i = 0; i < n; i += 2) {
1487:     PetscInt retry_count = 0;

1489:     /*
1490:       Generate U1 and ensure it's not too close to 0 to avoid log(0) singularity.
1491:       Add retry limit to prevent infinite loops in case of RNG failure.
1492:     */
1493:     do {
1494:       PetscCall(PetscRandomGetValueReal(rng, &u1));
1495:       retry_count++;
1496:       PetscCheck(retry_count < max_retry_count, PETSC_COMM_SELF, PETSC_ERR_LIB, "Random number generator failed to produce valid values after %" PetscInt_FMT " attempts", (PetscInt)max_retry_count);
1497:     } while (u1 < min_uniform);

1499:     PetscCall(PetscRandomGetValueReal(rng, &u2));

1501:     /*
1502:       Apply Box-Muller transform:
1503:       - magnitude: sqrt(-2 * ln(U1)) represents the radial distance from origin
1504:       - theta: 2pi * U2 represents the angle uniformly distributed on [0, 2pi]
1505:       - Converting from polar to Cartesian coordinates yields two independent samples
1506:     */
1507:     magnitude     = PetscSqrtReal(-2.0 * PetscLogReal(u1));
1508:     theta         = 2.0 * PETSC_PI * u2;
1509:     gauss_sample1 = magnitude * PetscCosReal(theta);
1510:     gauss_sample2 = magnitude * PetscSinReal(theta);

1512:     /* Scale and shift to achieve desired mean and standard deviation */
1513:     array[i] = mean + std_dev * gauss_sample1;
1514:     if (i + 1 < n) array[i + 1] = mean + std_dev * gauss_sample2;
1515:   }

1517:   PetscCall(VecRestoreArrayWrite(v, &array));
1518:   PetscFunctionReturn(PETSC_SUCCESS);
1519: }

1521: /*@
1522:   VecZeroEntries - puts a `0.0` in each element of a vector

1524:   Logically Collective

1526:   Input Parameter:
1527: . vec - The vector

1529:   Level: beginner

1531:   Note:
1532:   If the norm of the vector is known to be zero then this skips the unneeded zeroing process

1534: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecSetOptionsPrefix()`, `VecSet()`, `VecSetValues()`
1535: @*/
1536: PetscErrorCode VecZeroEntries(Vec vec)
1537: {
1538:   PetscFunctionBegin;
1539:   PetscCall(VecSet(vec, 0));
1540:   PetscFunctionReturn(PETSC_SUCCESS);
1541: }

1543: /*
1544:   VecSetTypeFromOptions_Private - Sets the type of vector from user options. Defaults to a PETSc sequential vector on one
1545:   processor and a PETSc MPI vector on more than one processor.

1547:   Collective

1549:   Input Parameter:
1550: . vec - The vector

1552:   Level: intermediate

1554: .seealso: [](ch_vectors), `Vec`, `VecSetFromOptions()`, `VecSetType()`
1555: */
1556: static PetscErrorCode VecSetTypeFromOptions_Private(Vec vec, PetscOptionItems PetscOptionsObject)
1557: {
1558:   PetscBool   opt;
1559:   VecType     defaultType;
1560:   char        typeName[256];
1561:   PetscMPIInt size;

1563:   PetscFunctionBegin;
1564:   if (((PetscObject)vec)->type_name) defaultType = ((PetscObject)vec)->type_name;
1565:   else {
1566:     PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size));
1567:     if (size > 1) defaultType = VECMPI;
1568:     else defaultType = VECSEQ;
1569:   }

1571:   PetscCall(VecRegisterAll());
1572:   PetscCall(PetscOptionsFList("-vec_type", "Vector type", "VecSetType", VecList, defaultType, typeName, 256, &opt));
1573:   if (opt) PetscCall(VecSetType(vec, typeName));
1574:   else PetscCall(VecSetType(vec, defaultType));
1575:   PetscFunctionReturn(PETSC_SUCCESS);
1576: }

1578: /*@
1579:   VecSetFromOptions - Configures the vector from the options database.

1581:   Collective

1583:   Input Parameter:
1584: . vec - The vector

1586:   Level: beginner

1588:   Notes:
1589:   To see all options, run your program with the -help option.

1591:   Must be called after `VecCreate()` but before the vector is used.

1593: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecSetOptionsPrefix()`
1594: @*/
1595: PetscErrorCode VecSetFromOptions(Vec vec)
1596: {
1597:   PetscBool flg;
1598:   PetscInt  bind_below = 0;

1600:   PetscFunctionBegin;

1603:   PetscObjectOptionsBegin((PetscObject)vec);
1604:   /* Handle vector type options */
1605:   PetscCall(VecSetTypeFromOptions_Private(vec, PetscOptionsObject));

1607:   /* Handle specific vector options */
1608:   PetscTryTypeMethod(vec, setfromoptions, PetscOptionsObject);

1610:   /* Bind to CPU if below a user-specified size threshold.
1611:    * This perhaps belongs in the options for the GPU Vec types, but VecBindToCPU() does nothing when called on non-GPU types,
1612:    * and putting it here makes is more maintainable than duplicating this for all. */
1613:   PetscCall(PetscOptionsInt("-vec_bind_below", "Set the size threshold (in local entries) below which the Vec is bound to the CPU", "VecBindToCPU", bind_below, &bind_below, &flg));
1614:   if (flg && vec->map->n < bind_below) PetscCall(VecBindToCPU(vec, PETSC_TRUE));

1616:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
1617:   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)vec, PetscOptionsObject));
1618:   PetscOptionsEnd();
1619:   PetscFunctionReturn(PETSC_SUCCESS);
1620: }

1622: /*@
1623:   VecSetSizes - Sets the local and global sizes, and checks to determine compatibility of the sizes

1625:   Collective

1627:   Input Parameters:
1628: + v - the vector
1629: . n - the local size (or `PETSC_DECIDE` to have it set)
1630: - N - the global size (or `PETSC_DETERMINE` to have it set)

1632:   Level: intermediate

1634:   Notes:
1635:   `N` cannot be `PETSC_DETERMINE` if `n` is `PETSC_DECIDE`

1637:   If one processor calls this with `N` of `PETSC_DETERMINE` then all processors must, otherwise the program will hang.

1639:   If `n` is not `PETSC_DECIDE`, then the value determines the `PetscLayout` of the vector and the ranges returned by
1640:   `VecGetOwnershipRange()` and `VecGetOwnershipRanges()`

1642: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecCreateSeq()`, `VecCreateMPI()`, `VecGetSize()`, `PetscSplitOwnership()`, `PetscLayout`,
1643:           `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`, `MatSetSizes()`
1644: @*/
1645: PetscErrorCode VecSetSizes(Vec v, PetscInt n, PetscInt N)
1646: {
1647:   PetscFunctionBegin;
1649:   if (N >= 0) {
1651:     PetscCheck(n <= N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " cannot be larger than global size %" PetscInt_FMT, n, N);
1652:   }
1653:   PetscCheck(!(v->map->n >= 0 || v->map->N >= 0) || !(v->map->n != n || v->map->N != N), PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot change/reset vector sizes to %" PetscInt_FMT " local %" PetscInt_FMT " global after previously setting them to %" PetscInt_FMT " local %" PetscInt_FMT " global", n, N,
1654:              v->map->n, v->map->N);
1655:   v->map->n = n;
1656:   v->map->N = N;
1657:   PetscTryTypeMethod(v, create);
1658:   v->ops->create = NULL;
1659:   PetscFunctionReturn(PETSC_SUCCESS);
1660: }

1662: /*@
1663:   VecSetBlockSize - Sets the block size for future calls to `VecSetValuesBlocked()`
1664:   and `VecSetValuesBlockedLocal()`.

1666:   Logically Collective

1668:   Input Parameters:
1669: + v  - the vector
1670: - bs - the blocksize

1672:   Level: advanced

1674:   Note:
1675:   All vectors obtained by `VecDuplicate()` inherit the same blocksize.

1677:   Vectors obtained with `DMCreateGlobalVector()` and `DMCreateLocalVector()` generally already have a blocksize set based on the state of the `DM`

1679: .seealso: [](ch_vectors), `Vec`, `VecSetValuesBlocked()`, `VecSetLocalToGlobalMapping()`, `VecGetBlockSize()`
1680: @*/
1681: PetscErrorCode VecSetBlockSize(Vec v, PetscInt bs)
1682: {
1683:   PetscFunctionBegin;
1686:   PetscCall(PetscLayoutSetBlockSize(v->map, bs));
1687:   v->bstash.bs = bs; /* use the same blocksize for the vec's block-stash */
1688:   PetscFunctionReturn(PETSC_SUCCESS);
1689: }

1691: /*@
1692:   VecGetBlockSize - Gets the blocksize for the vector, i.e. what is used for `VecSetValuesBlocked()`
1693:   and `VecSetValuesBlockedLocal()`.

1695:   Not Collective

1697:   Input Parameter:
1698: . v - the vector

1700:   Output Parameter:
1701: . bs - the blocksize

1703:   Level: advanced

1705:   Note:
1706:   All vectors obtained by `VecDuplicate()` inherit the same blocksize.

1708: .seealso: [](ch_vectors), `Vec`, `VecSetValuesBlocked()`, `VecSetLocalToGlobalMapping()`, `VecSetBlockSize()`
1709: @*/
1710: PetscErrorCode VecGetBlockSize(Vec v, PetscInt *bs)
1711: {
1712:   PetscFunctionBegin;
1714:   PetscAssertPointer(bs, 2);
1715:   PetscCall(PetscLayoutGetBlockSize(v->map, bs));
1716:   PetscFunctionReturn(PETSC_SUCCESS);
1717: }

1719: /*@
1720:   VecSetOptionsPrefix - Sets the prefix used for searching for all
1721:   `Vec` options in the database.

1723:   Logically Collective

1725:   Input Parameters:
1726: + v      - the `Vec` context
1727: - prefix - the prefix to prepend to all option names

1729:   Level: advanced

1731:   Note:
1732:   A hyphen (-) must NOT be given at the beginning of the prefix name.
1733:   The first character of all runtime options is AUTOMATICALLY the hyphen.

1735: .seealso: [](ch_vectors), `Vec`, `VecSetFromOptions()`
1736: @*/
1737: PetscErrorCode VecSetOptionsPrefix(Vec v, const char prefix[])
1738: {
1739:   PetscFunctionBegin;
1741:   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)v, prefix));
1742:   PetscFunctionReturn(PETSC_SUCCESS);
1743: }

1745: /*@
1746:   VecAppendOptionsPrefix - Appends to the prefix used for searching for all
1747:   `Vec` options in the database.

1749:   Logically Collective

1751:   Input Parameters:
1752: + v      - the `Vec` context
1753: - prefix - the prefix to prepend to all option names

1755:   Level: advanced

1757:   Note:
1758:   A hyphen (-) must NOT be given at the beginning of the prefix name.
1759:   The first character of all runtime options is AUTOMATICALLY the hyphen.

1761: .seealso: [](ch_vectors), `Vec`, `VecGetOptionsPrefix()`
1762: @*/
1763: PetscErrorCode VecAppendOptionsPrefix(Vec v, const char prefix[])
1764: {
1765:   PetscFunctionBegin;
1767:   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)v, prefix));
1768:   PetscFunctionReturn(PETSC_SUCCESS);
1769: }

1771: /*@
1772:   VecGetOptionsPrefix - Sets the prefix used for searching for all
1773:   Vec options in the database.

1775:   Not Collective

1777:   Input Parameter:
1778: . v - the `Vec` context

1780:   Output Parameter:
1781: . prefix - pointer to the prefix string used

1783:   Level: advanced

1785: .seealso: [](ch_vectors), `Vec`, `VecAppendOptionsPrefix()`
1786: @*/
1787: PetscErrorCode VecGetOptionsPrefix(Vec v, const char *prefix[])
1788: {
1789:   PetscFunctionBegin;
1791:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)v, prefix));
1792:   PetscFunctionReturn(PETSC_SUCCESS);
1793: }

1795: /*@C
1796:   VecGetState - Gets the state of a `Vec`.

1798:   Not Collective

1800:   Input Parameter:
1801: . v - the `Vec` context

1803:   Output Parameter:
1804: . state - the object state

1806:   Level: advanced

1808:   Note:
1809:   Object state is an integer which gets increased every time
1810:   the object is changed. By saving and later querying the object state
1811:   one can determine whether information about the object is still current.

1813: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `PetscObjectStateGet()`
1814: @*/
1815: PetscErrorCode VecGetState(Vec v, PetscObjectState *state)
1816: {
1817:   PetscFunctionBegin;
1819:   PetscAssertPointer(state, 2);
1820:   PetscCall(PetscObjectStateGet((PetscObject)v, state));
1821:   PetscFunctionReturn(PETSC_SUCCESS);
1822: }

1824: /*@
1825:   VecSetUp - Sets up the internal vector data structures for the later use.

1827:   Collective

1829:   Input Parameter:
1830: . v - the `Vec` context

1832:   Level: advanced

1834:   Notes:
1835:   For basic use of the `Vec` classes the user need not explicitly call
1836:   `VecSetUp()`, since these actions will happen automatically.

1838: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecDestroy()`
1839: @*/
1840: PetscErrorCode VecSetUp(Vec v)
1841: {
1842:   PetscMPIInt size;

1844:   PetscFunctionBegin;
1846:   PetscCheck(v->map->n >= 0 || v->map->N >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Sizes not set");
1847:   if (!((PetscObject)v)->type_name) {
1848:     PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)v), &size));
1849:     if (size == 1) PetscCall(VecSetType(v, VECSEQ));
1850:     else PetscCall(VecSetType(v, VECMPI));
1851:   }
1852:   PetscFunctionReturn(PETSC_SUCCESS);
1853: }

1855: /*
1856:     These currently expose the PetscScalar/PetscReal in updating the
1857:     cached norm. If we push those down into the implementation these
1858:     will become independent of PetscScalar/PetscReal
1859: */

1861: PetscErrorCode VecCopyAsync_Private(Vec x, Vec y, PetscDeviceContext dctx)
1862: {
1863:   PetscBool flgs[4];
1864:   PetscReal norms[4] = {0.0, 0.0, 0.0, 0.0};

1866:   PetscFunctionBegin;
1871:   if (x == y) PetscFunctionReturn(PETSC_SUCCESS);
1872:   VecCheckSameLocalSize(x, 1, y, 2);
1873:   VecCheckAssembled(x);
1874:   PetscCall(VecSetErrorIfLocked(y, 2));

1876: #if !defined(PETSC_USE_MIXED_PRECISION)
1877:   for (PetscInt i = 0; i < 4; i++) PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], norms[i], flgs[i]));
1878: #endif

1880:   PetscCall(PetscLogEventBegin(VEC_Copy, x, y, 0, 0));
1881: #if defined(PETSC_USE_MIXED_PRECISION)
1882:   extern PetscErrorCode VecGetArray(Vec, double **);
1883:   extern PetscErrorCode VecRestoreArray(Vec, double **);
1884:   extern PetscErrorCode VecGetArray(Vec, float **);
1885:   extern PetscErrorCode VecRestoreArray(Vec, float **);
1886:   extern PetscErrorCode VecGetArrayRead(Vec, const double **);
1887:   extern PetscErrorCode VecRestoreArrayRead(Vec, const double **);
1888:   extern PetscErrorCode VecGetArrayRead(Vec, const float **);
1889:   extern PetscErrorCode VecRestoreArrayRead(Vec, const float **);
1890:   if ((((PetscObject)x)->precision == PETSC_PRECISION_SINGLE) && (((PetscObject)y)->precision == PETSC_PRECISION_DOUBLE)) {
1891:     PetscInt     i, n;
1892:     const float *xx;
1893:     double      *yy;
1894:     PetscCall(VecGetArrayRead(x, &xx));
1895:     PetscCall(VecGetArray(y, &yy));
1896:     PetscCall(VecGetLocalSize(x, &n));
1897:     for (i = 0; i < n; i++) yy[i] = xx[i];
1898:     PetscCall(VecRestoreArrayRead(x, &xx));
1899:     PetscCall(VecRestoreArray(y, &yy));
1900:   } else if ((((PetscObject)x)->precision == PETSC_PRECISION_DOUBLE) && (((PetscObject)y)->precision == PETSC_PRECISION_SINGLE)) {
1901:     PetscInt      i, n;
1902:     float        *yy;
1903:     const double *xx;
1904:     PetscCall(VecGetArrayRead(x, &xx));
1905:     PetscCall(VecGetArray(y, &yy));
1906:     PetscCall(VecGetLocalSize(x, &n));
1907:     for (i = 0; i < n; i++) yy[i] = (float)xx[i];
1908:     PetscCall(VecRestoreArrayRead(x, &xx));
1909:     PetscCall(VecRestoreArray(y, &yy));
1910:   } else PetscUseTypeMethod(x, copy, y);
1911: #else
1912:   VecMethodDispatch(x, dctx, VecAsyncFnName(Copy), copy, (Vec, Vec, PetscDeviceContext), y);
1913: #endif

1915:   PetscCall(PetscObjectStateIncrease((PetscObject)y));
1916: #if !defined(PETSC_USE_MIXED_PRECISION)
1917:   for (PetscInt i = 0; i < 4; i++) {
1918:     if (flgs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)y, NormIds[i], norms[i]));
1919:   }
1920: #endif

1922:   PetscCall(PetscLogEventEnd(VEC_Copy, x, y, 0, 0));
1923:   PetscFunctionReturn(PETSC_SUCCESS);
1924: }

1926: /*@
1927:   VecCopy - Copies a vector `y = x`

1929:   Logically Collective

1931:   Input Parameter:
1932: . x - the vector

1934:   Output Parameter:
1935: . y - the copy

1937:   Level: beginner

1939:   Note:
1940:   For default parallel PETSc vectors, both `x` and `y` must be distributed in
1941:   the same manner; local copies are done.

1943:   Developer Notes:
1944:   `PetscCheckSameTypeAndComm`(x,1,y,2) is not used on these vectors because we allow one
1945:   of the vectors to be sequential and one to be parallel so long as both have the same
1946:   local sizes. This is used in some internal functions in PETSc.

1948: .seealso: [](ch_vectors), `Vec`, `VecDuplicate()`
1949: @*/
1950: PetscErrorCode VecCopy(Vec x, Vec y)
1951: {
1952:   PetscFunctionBegin;
1953:   PetscCall(VecCopyAsync_Private(x, y, NULL));
1954:   PetscFunctionReturn(PETSC_SUCCESS);
1955: }

1957: PetscErrorCode VecSwapAsync_Private(Vec x, Vec y, PetscDeviceContext dctx)
1958: {
1959:   PetscReal normxs[4], normys[4];
1960:   PetscBool flgxs[4], flgys[4];

1962:   PetscFunctionBegin;
1967:   PetscCheckSameTypeAndComm(x, 1, y, 2);
1968:   VecCheckSameSize(x, 1, y, 2);
1969:   VecCheckAssembled(x);
1970:   VecCheckAssembled(y);
1971:   PetscCall(VecSetErrorIfLocked(x, 1));
1972:   PetscCall(VecSetErrorIfLocked(y, 2));

1974:   for (PetscInt i = 0; i < 4; i++) {
1975:     PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], normxs[i], flgxs[i]));
1976:     PetscCall(PetscObjectComposedDataGetReal((PetscObject)y, NormIds[i], normys[i], flgys[i]));
1977:   }

1979:   PetscCall(PetscLogEventBegin(VEC_Swap, x, y, 0, 0));
1980:   VecMethodDispatch(x, dctx, VecAsyncFnName(Swap), swap, (Vec, Vec, PetscDeviceContext), y);
1981:   PetscCall(PetscLogEventEnd(VEC_Swap, x, y, 0, 0));

1983:   PetscCall(PetscObjectStateIncrease((PetscObject)x));
1984:   PetscCall(PetscObjectStateIncrease((PetscObject)y));
1985:   for (PetscInt i = 0; i < 4; i++) {
1986:     if (flgxs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)y, NormIds[i], normxs[i]));
1987:     if (flgys[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[i], normys[i]));
1988:   }
1989:   PetscFunctionReturn(PETSC_SUCCESS);
1990: }
1991: /*@
1992:   VecSwap - Swaps the values between two vectors, `x` and `y`.

1994:   Logically Collective

1996:   Input Parameters:
1997: + x - the first vector
1998: - y - the second vector

2000:   Level: advanced

2002: .seealso: [](ch_vectors), `Vec`, `VecSet()`
2003: @*/
2004: PetscErrorCode VecSwap(Vec x, Vec y)
2005: {
2006:   PetscFunctionBegin;
2007:   PetscCall(VecSwapAsync_Private(x, y, NULL));
2008:   PetscFunctionReturn(PETSC_SUCCESS);
2009: }

2011: /*@
2012:   VecStashViewFromOptions - Processes command line options to determine if/how a `VecStash` object is to be viewed.

2014:   Collective

2016:   Input Parameters:
2017: + obj  - the `Vec` containing a stash
2018: . bobj - optional other object that provides the prefix
2019: - name - option to activate viewing

2021:   Options Database Key:
2022: . -name [viewertype][:...] - option name and values. See `PetscObjectViewFromOptions()` for the possible arguments

2024:   Level: intermediate

2026:   Developer Notes:
2027:   This cannot use `PetscObjectViewFromOptions()` because it takes a `Vec` as an argument but does not use `VecView()`

2029: .seealso: [](ch_vectors), `Vec`, `VecStashSetInitialSize()`
2030: @*/
2031: PetscErrorCode VecStashViewFromOptions(Vec obj, PetscObject bobj, const char name[])
2032: {
2033:   PetscViewer       viewer;
2034:   PetscBool         flg;
2035:   PetscViewerFormat format;
2036:   char             *prefix;

2038:   PetscFunctionBegin;
2039:   prefix = bobj ? bobj->prefix : ((PetscObject)obj)->prefix;
2040:   PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)obj), ((PetscObject)obj)->options, prefix, name, &viewer, &format, &flg));
2041:   if (flg) {
2042:     PetscCall(PetscViewerPushFormat(viewer, format));
2043:     PetscCall(VecStashView(obj, viewer));
2044:     PetscCall(PetscViewerPopFormat(viewer));
2045:     PetscCall(PetscViewerDestroy(&viewer));
2046:   }
2047:   PetscFunctionReturn(PETSC_SUCCESS);
2048: }

2050: /*@
2051:   VecStashView - Prints the entries in the vector stash and block stash.

2053:   Collective

2055:   Input Parameters:
2056: + v      - the vector
2057: - viewer - the viewer

2059:   Level: advanced

2061: .seealso: [](ch_vectors), `Vec`, `VecSetBlockSize()`, `VecSetValues()`, `VecSetValuesBlocked()`
2062: @*/
2063: PetscErrorCode VecStashView(Vec v, PetscViewer viewer)
2064: {
2065:   PetscMPIInt rank;
2066:   PetscInt    i, j;
2067:   PetscBool   match;
2068:   VecStash   *s;
2069:   PetscScalar val;

2071:   PetscFunctionBegin;
2074:   PetscCheckSameComm(v, 1, viewer, 2);

2076:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &match));
2077:   PetscCheck(match, PETSC_COMM_SELF, PETSC_ERR_SUP, "Stash viewer only works with ASCII viewer not %s", ((PetscObject)v)->type_name);
2078:   PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
2079:   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)v), &rank));
2080:   s = &v->bstash;

2082:   /* print block stash */
2083:   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
2084:   PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Vector Block stash size %" PetscInt_FMT " block size %" PetscInt_FMT "\n", rank, s->n, s->bs));
2085:   for (i = 0; i < s->n; i++) {
2086:     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " ", rank, s->idx[i]));
2087:     for (j = 0; j < s->bs; j++) {
2088:       val = s->array[i * s->bs + j];
2089: #if defined(PETSC_USE_COMPLEX)
2090:       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "(%18.16e %18.16e) ", (double)PetscRealPart(val), (double)PetscImaginaryPart(val)));
2091: #else
2092:       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%18.16e ", (double)val));
2093: #endif
2094:     }
2095:     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
2096:   }
2097:   PetscCall(PetscViewerFlush(viewer));

2099:   s = &v->stash;

2101:   /* print basic stash */
2102:   PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Vector stash size %" PetscInt_FMT "\n", rank, s->n));
2103:   for (i = 0; i < s->n; i++) {
2104:     val = s->array[i];
2105: #if defined(PETSC_USE_COMPLEX)
2106:     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " (%18.16e %18.16e) ", rank, s->idx[i], (double)PetscRealPart(val), (double)PetscImaginaryPart(val)));
2107: #else
2108:     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " %18.16e\n", rank, s->idx[i], (double)val));
2109: #endif
2110:   }
2111:   PetscCall(PetscViewerFlush(viewer));
2112:   PetscCall(PetscViewerASCIIPopSynchronized(viewer));
2113:   PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
2114:   PetscFunctionReturn(PETSC_SUCCESS);
2115: }

2117: PetscErrorCode PetscOptionsGetVec(PetscOptions options, const char prefix[], const char key[], Vec v, PetscBool *set)
2118: {
2119:   PetscInt     i, N, rstart, rend;
2120:   PetscScalar *xx;
2121:   PetscReal   *xreal;
2122:   PetscBool    iset;

2124:   PetscFunctionBegin;
2125:   PetscCall(VecGetOwnershipRange(v, &rstart, &rend));
2126:   PetscCall(VecGetSize(v, &N));
2127:   PetscCall(PetscCalloc1(N, &xreal));
2128:   PetscCall(PetscOptionsGetRealArray(options, prefix, key, xreal, &N, &iset));
2129:   if (iset) {
2130:     PetscCall(VecGetArray(v, &xx));
2131:     for (i = rstart; i < rend; i++) xx[i - rstart] = xreal[i];
2132:     PetscCall(VecRestoreArray(v, &xx));
2133:   }
2134:   PetscCall(PetscFree(xreal));
2135:   if (set) *set = iset;
2136:   PetscFunctionReturn(PETSC_SUCCESS);
2137: }

2139: /*@
2140:   VecGetLayout - get `PetscLayout` describing a vector layout

2142:   Not Collective

2144:   Input Parameter:
2145: . x - the vector

2147:   Output Parameter:
2148: . map - the layout

2150:   Level: developer

2152:   Note:
2153:   The layout determines what vector elements are contained on each MPI process

2155: .seealso: [](ch_vectors), `PetscLayout`, `Vec`, `VecGetSize()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
2156: @*/
2157: PetscErrorCode VecGetLayout(Vec x, PetscLayout *map)
2158: {
2159:   PetscFunctionBegin;
2161:   PetscAssertPointer(map, 2);
2162:   *map = x->map;
2163:   PetscFunctionReturn(PETSC_SUCCESS);
2164: }

2166: /*@
2167:   VecSetLayout - set `PetscLayout` describing vector layout

2169:   Not Collective

2171:   Input Parameters:
2172: + x   - the vector
2173: - map - the layout

2175:   Level: developer

2177:   Note:
2178:   It is normally only valid to replace the layout with a layout known to be equivalent.

2180: .seealso: [](ch_vectors), `Vec`, `PetscLayout`, `VecGetLayout()`, `VecGetSize()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
2181: @*/
2182: PetscErrorCode VecSetLayout(Vec x, PetscLayout map)
2183: {
2184:   PetscFunctionBegin;
2186:   PetscCall(PetscLayoutReference(map, &x->map));
2187:   PetscFunctionReturn(PETSC_SUCCESS);
2188: }

2190: /*@
2191:   VecFlag - set infinity into the local part of the vector on any subset of MPI processes

2193:   Logically Collective

2195:   Input Parameters:
2196: + xin - the vector, can be `NULL` but only if on all processes
2197: - flg - indicates if this processes portion of the vector should be set to infinity

2199:   Level: developer

2201:   Note:
2202:   This removes the values from the vector norm cache for all processes by calling `PetscObjectIncrease()`.

2204:   This is used for any subset of MPI processes to indicate an failure in a solver, after the next use of `VecNorm()` if
2205:   `KSPCheckNorm()` detects an infinity and at least one of the MPI processes has a not converged reason then the `KSP`
2206:   object collectively is labeled as not converged.

2208: .seealso: [](ch_vectors), `Vec`, `PetscLayout`, `VecGetLayout()`, `VecGetSize()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
2209: @*/
2210: PetscErrorCode VecFlag(Vec xin, PetscInt flg)
2211: {
2212:   // MSVC gives "divide by zero" error at compile time - so declare as volatile to skip this check.
2213:   volatile PetscReal one = 1.0, zero = 0.0;
2214:   PetscScalar        inf;

2216:   PetscFunctionBegin;
2217:   if (!xin) PetscFunctionReturn(PETSC_SUCCESS);
2219:   PetscCall(PetscObjectStateIncrease((PetscObject)xin));
2220:   if (flg) {
2221:     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
2222:     inf = one / zero;
2223:     PetscCall(PetscFPTrapPop());
2224:     if (xin->ops->set) PetscUseTypeMethod(xin, set, inf);
2225:     else {
2226:       PetscInt     n;
2227:       PetscScalar *xx;

2229:       PetscCall(VecGetLocalSize(xin, &n));
2230:       PetscCall(VecGetArrayWrite(xin, &xx));
2231:       for (PetscInt i = 0; i < n; ++i) xx[i] = inf;
2232:       PetscCall(VecRestoreArrayWrite(xin, &xx));
2233:     }
2234:   }
2235:   PetscFunctionReturn(PETSC_SUCCESS);
2236: }

2238: /*@
2239:   VecSetInf - set infinity into the local part of the vector

2241:   Not Collective

2243:   Input Parameters:
2244: . xin - the vector

2246:   Level: developer

2248:   Note:
2249:   Deprecated, see  `VecFlag()`
2250:   This is used for any subset of MPI processes to indicate an failure in a solver, after the next use of `VecNorm()` if
2251:   `KSPCheckNorm()` detects an infinity and at least one of the MPI processes has a not converged reason then the `KSP`
2252:   object collectively is labeled as not converged.

2254:   This cannot be called if `xin` has a cached norm available

2256: .seealso: [](ch_vectors), `VecFlag()`, `Vec`, `PetscLayout`, `VecGetLayout()`, `VecGetSize()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
2257: @*/
2258: PetscErrorCode VecSetInf(Vec xin)
2259: {
2260:   // MSVC gives "divide by zero" error at compile time - so declare as volatile to skip this check.
2261:   volatile PetscReal one = 1.0, zero = 0.0;
2262:   PetscScalar        inf;
2263:   PetscBool          flg;

2265:   PetscFunctionBegin;
2266:   PetscCall(VecNormAvailable(xin, NORM_2, &flg, NULL));
2267:   PetscCheck(!flg, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot call VecSetInf() if the vector has a cached norm");
2268:   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
2269:   inf = one / zero;
2270:   PetscCall(PetscFPTrapPop());
2271:   if (xin->ops->set) PetscUseTypeMethod(xin, set, inf);
2272:   else {
2273:     PetscInt     n;
2274:     PetscScalar *xx;

2276:     PetscCall(VecGetLocalSize(xin, &n));
2277:     PetscCall(VecGetArrayWrite(xin, &xx));
2278:     for (PetscInt i = 0; i < n; ++i) xx[i] = inf;
2279:     PetscCall(VecRestoreArrayWrite(xin, &xx));
2280:   }
2281:   PetscFunctionReturn(PETSC_SUCCESS);
2282: }

2284: /*@
2285:   VecBindToCPU - marks a vector to temporarily stay on the CPU and perform computations on the CPU

2287:   Logically collective

2289:   Input Parameters:
2290: + v   - the vector
2291: - flg - bind to the CPU if value of `PETSC_TRUE`

2293:   Level: intermediate

2295: .seealso: [](ch_vectors), `Vec`, `VecBoundToCPU()`
2296: @*/
2297: PetscErrorCode VecBindToCPU(Vec v, PetscBool flg)
2298: {
2299:   PetscFunctionBegin;
2302: #if defined(PETSC_HAVE_DEVICE)
2303:   if (v->boundtocpu == flg) PetscFunctionReturn(PETSC_SUCCESS);
2304:   v->boundtocpu = flg;
2305:   PetscTryTypeMethod(v, bindtocpu, flg);
2306: #endif
2307:   PetscFunctionReturn(PETSC_SUCCESS);
2308: }

2310: /*@
2311:   VecBoundToCPU - query if a vector is bound to the CPU

2313:   Not collective

2315:   Input Parameter:
2316: . v - the vector

2318:   Output Parameter:
2319: . flg - the logical flag

2321:   Level: intermediate

2323: .seealso: [](ch_vectors), `Vec`, `VecBindToCPU()`
2324: @*/
2325: PetscErrorCode VecBoundToCPU(Vec v, PetscBool *flg)
2326: {
2327:   PetscFunctionBegin;
2329:   PetscAssertPointer(flg, 2);
2330: #if defined(PETSC_HAVE_DEVICE)
2331:   *flg = v->boundtocpu;
2332: #else
2333:   *flg = PETSC_TRUE;
2334: #endif
2335:   PetscFunctionReturn(PETSC_SUCCESS);
2336: }

2338: /*@
2339:   VecSetBindingPropagates - Sets whether the state of being bound to the CPU for a GPU vector type propagates to child and some other associated objects

2341:   Input Parameters:
2342: + v   - the vector
2343: - flg - flag indicating whether the boundtocpu flag should be propagated

2345:   Level: developer

2347:   Notes:
2348:   If the value of flg is set to true, then `VecDuplicate()` and `VecDuplicateVecs()` will bind created vectors to GPU if the input vector is bound to the CPU.
2349:   The created vectors will also have their bindingpropagates flag set to true.

2351:   Developer Notes:
2352:   If a `DMDA` has the `-dm_bind_below option` set to true, then vectors created by `DMCreateGlobalVector()` will have `VecSetBindingPropagates()` called on them to
2353:   set their bindingpropagates flag to true.

2355: .seealso: [](ch_vectors), `Vec`, `MatSetBindingPropagates()`, `VecGetBindingPropagates()`
2356: @*/
2357: PetscErrorCode VecSetBindingPropagates(Vec v, PetscBool flg)
2358: {
2359:   PetscFunctionBegin;
2361: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2362:   v->bindingpropagates = flg;
2363: #endif
2364:   PetscFunctionReturn(PETSC_SUCCESS);
2365: }

2367: /*@
2368:   VecGetBindingPropagates - Gets whether the state of being bound to the CPU for a GPU vector type propagates to child and some other associated objects

2370:   Input Parameter:
2371: . v - the vector

2373:   Output Parameter:
2374: . flg - flag indicating whether the boundtocpu flag will be propagated

2376:   Level: developer

2378: .seealso: [](ch_vectors), `Vec`, `VecSetBindingPropagates()`
2379: @*/
2380: PetscErrorCode VecGetBindingPropagates(Vec v, PetscBool *flg)
2381: {
2382:   PetscFunctionBegin;
2384:   PetscAssertPointer(flg, 2);
2385: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2386:   *flg = v->bindingpropagates;
2387: #else
2388:   *flg = PETSC_FALSE;
2389: #endif
2390:   PetscFunctionReturn(PETSC_SUCCESS);
2391: }

2393: /*@C
2394:   VecSetPinnedMemoryMin - Set the minimum data size for which pinned memory will be used for host (CPU) allocations.

2396:   Logically Collective

2398:   Input Parameters:
2399: + v      - the vector
2400: - mbytes - minimum data size in bytes

2402:   Options Database Key:
2403: . -vec_pinned_memory_min size - minimum size (in bytes) for an allocation to use pinned memory on host.

2405:   Level: developer

2407:   Note:
2408:   Specifying -1 ensures that pinned memory will never be used.

2410: .seealso: [](ch_vectors), `Vec`, `VecGetPinnedMemoryMin()`
2411: @*/
2412: PetscErrorCode VecSetPinnedMemoryMin(Vec v, size_t mbytes)
2413: {
2414:   PetscFunctionBegin;
2416: #if PetscDefined(HAVE_DEVICE)
2417:   v->minimum_bytes_pinned_memory = mbytes;
2418: #endif
2419:   PetscFunctionReturn(PETSC_SUCCESS);
2420: }

2422: /*@C
2423:   VecGetPinnedMemoryMin - Get the minimum data size for which pinned memory will be used for host (CPU) allocations.

2425:   Logically Collective

2427:   Input Parameter:
2428: . v - the vector

2430:   Output Parameter:
2431: . mbytes - minimum data size in bytes

2433:   Level: developer

2435: .seealso: [](ch_vectors), `Vec`, `VecSetPinnedMemoryMin()`
2436: @*/
2437: PetscErrorCode VecGetPinnedMemoryMin(Vec v, size_t *mbytes)
2438: {
2439:   PetscFunctionBegin;
2441:   PetscAssertPointer(mbytes, 2);
2442: #if PetscDefined(HAVE_DEVICE)
2443:   *mbytes = v->minimum_bytes_pinned_memory;
2444: #endif
2445:   PetscFunctionReturn(PETSC_SUCCESS);
2446: }

2448: /*@
2449:   VecGetOffloadMask - Get the offload mask of a `Vec`

2451:   Not Collective

2453:   Input Parameter:
2454: . v - the vector

2456:   Output Parameter:
2457: . mask - corresponding `PetscOffloadMask` enum value.

2459:   Level: intermediate

2461: .seealso: [](ch_vectors), `Vec`, `VecCreateSeqCUDA()`, `VecCreateSeqViennaCL()`, `VecGetArray()`, `VecGetType()`
2462: @*/
2463: PetscErrorCode VecGetOffloadMask(Vec v, PetscOffloadMask *mask)
2464: {
2465:   PetscFunctionBegin;
2467:   PetscAssertPointer(mask, 2);
2468:   *mask = v->offloadmask;
2469:   PetscFunctionReturn(PETSC_SUCCESS);
2470: }

2472: #if !defined(PETSC_HAVE_VIENNACL)
2473: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLContext(Vec v, PETSC_UINTPTR_T *ctx)
2474: {
2475:   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_context");
2476: }

2478: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLQueue(Vec v, PETSC_UINTPTR_T *queue)
2479: {
2480:   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_command_queue");
2481: }

2483: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMem(Vec v, PETSC_UINTPTR_T *queue)
2484: {
2485:   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2486: }

2488: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMemRead(Vec v, PETSC_UINTPTR_T *queue)
2489: {
2490:   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2491: }

2493: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMemWrite(Vec v, PETSC_UINTPTR_T *queue)
2494: {
2495:   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2496: }

2498: PETSC_EXTERN PetscErrorCode VecViennaCLRestoreCLMemWrite(Vec v)
2499: {
2500:   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to restore a Vec's cl_mem");
2501: }
2502: #endif

2504: static PetscErrorCode VecErrorWeightedNorms_Basic(Vec U, Vec Y, Vec E, NormType wnormtype, PetscReal atol, Vec vatol, PetscReal rtol, Vec vrtol, PetscReal ignore_max, PetscReal *norm, PetscInt *norm_loc, PetscReal *norma, PetscInt *norma_loc, PetscReal *normr, PetscInt *normr_loc)
2505: {
2506:   const PetscScalar *u, *y;
2507:   const PetscScalar *atola = NULL, *rtola = NULL, *erra = NULL;
2508:   PetscInt           n, n_loc = 0, na_loc = 0, nr_loc = 0;
2509:   PetscReal          nrm = 0, nrma = 0, nrmr = 0, err_loc[6];

2511:   PetscFunctionBegin;
2512: #define SkipSmallValue(a, b, tol) \
2513:   if (PetscAbsScalar(a) < tol || PetscAbsScalar(b) < tol) continue

2515:   PetscCall(VecGetLocalSize(U, &n));
2516:   PetscCall(VecGetArrayRead(U, &u));
2517:   PetscCall(VecGetArrayRead(Y, &y));
2518:   if (E) PetscCall(VecGetArrayRead(E, &erra));
2519:   if (vatol) PetscCall(VecGetArrayRead(vatol, &atola));
2520:   if (vrtol) PetscCall(VecGetArrayRead(vrtol, &rtola));
2521:   for (PetscInt i = 0; i < n; i++) {
2522:     PetscReal err, tol, tola, tolr;

2524:     SkipSmallValue(y[i], u[i], ignore_max);
2525:     atol = atola ? PetscRealPart(atola[i]) : atol;
2526:     rtol = rtola ? PetscRealPart(rtola[i]) : rtol;
2527:     err  = erra ? PetscAbsScalar(erra[i]) : PetscAbsScalar(y[i] - u[i]);
2528:     tola = atol;
2529:     tolr = rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
2530:     tol  = tola + tolr;
2531:     if (tola > 0.) {
2532:       if (wnormtype == NORM_INFINITY) nrma = PetscMax(nrma, err / tola);
2533:       else nrma += PetscSqr(err / tola);
2534:       na_loc++;
2535:     }
2536:     if (tolr > 0.) {
2537:       if (wnormtype == NORM_INFINITY) nrmr = PetscMax(nrmr, err / tolr);
2538:       else nrmr += PetscSqr(err / tolr);
2539:       nr_loc++;
2540:     }
2541:     if (tol > 0.) {
2542:       if (wnormtype == NORM_INFINITY) nrm = PetscMax(nrm, err / tol);
2543:       else nrm += PetscSqr(err / tol);
2544:       n_loc++;
2545:     }
2546:   }
2547:   if (E) PetscCall(VecRestoreArrayRead(E, &erra));
2548:   if (vatol) PetscCall(VecRestoreArrayRead(vatol, &atola));
2549:   if (vrtol) PetscCall(VecRestoreArrayRead(vrtol, &rtola));
2550:   PetscCall(VecRestoreArrayRead(U, &u));
2551:   PetscCall(VecRestoreArrayRead(Y, &y));
2552: #undef SkipSmallValue

2554:   err_loc[0] = nrm;
2555:   err_loc[1] = nrma;
2556:   err_loc[2] = nrmr;
2557:   err_loc[3] = (PetscReal)n_loc;
2558:   err_loc[4] = (PetscReal)na_loc;
2559:   err_loc[5] = (PetscReal)nr_loc;
2560:   if (wnormtype == NORM_2) {
2561:     PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, err_loc, 6, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)U)));
2562:   } else {
2563:     PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, err_loc, 3, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)U)));
2564:     PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, err_loc + 3, 3, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)U)));
2565:   }
2566:   if (wnormtype == NORM_2) {
2567:     *norm  = PetscSqrtReal(err_loc[0]);
2568:     *norma = PetscSqrtReal(err_loc[1]);
2569:     *normr = PetscSqrtReal(err_loc[2]);
2570:   } else {
2571:     *norm  = err_loc[0];
2572:     *norma = err_loc[1];
2573:     *normr = err_loc[2];
2574:   }
2575:   *norm_loc  = (PetscInt)err_loc[3];
2576:   *norma_loc = (PetscInt)err_loc[4];
2577:   *normr_loc = (PetscInt)err_loc[5];
2578:   PetscFunctionReturn(PETSC_SUCCESS);
2579: }

2581: /*@
2582:   VecErrorWeightedNorms - compute a weighted norm of the difference between two vectors

2584:   Collective

2586:   Input Parameters:
2587: + U          - first vector to be compared
2588: . Y          - second vector to be compared
2589: . E          - optional third vector representing the error (if not provided, the error is ||U-Y||)
2590: . wnormtype  - norm type
2591: . atol       - scalar for absolute tolerance
2592: . vatol      - vector representing per-entry absolute tolerances (can be ``NULL``)
2593: . rtol       - scalar for relative tolerance
2594: . vrtol      - vector representing per-entry relative tolerances (can be ``NULL``)
2595: - ignore_max - ignore values smaller than this value in absolute terms.

2597:   Output Parameters:
2598: + norm      - weighted norm
2599: . norm_loc  - number of vector locations used for the weighted norm
2600: . norma     - weighted norm based on the absolute tolerance
2601: . norma_loc - number of vector locations used for the absolute weighted norm
2602: . normr     - weighted norm based on the relative tolerance
2603: - normr_loc - number of vector locations used for the relative weighted norm

2605:   Level: developer

2607:   Notes:
2608:   This is primarily used for computing weighted local truncation errors in ``TS``.

2610: .seealso: [](ch_vectors), `Vec`, `NormType`, `TSErrorWeightedNorm()`, `TSErrorWeightedENorm()`
2611: @*/
2612: PetscErrorCode VecErrorWeightedNorms(Vec U, Vec Y, Vec E, NormType wnormtype, PetscReal atol, Vec vatol, PetscReal rtol, Vec vrtol, PetscReal ignore_max, PetscReal *norm, PetscInt *norm_loc, PetscReal *norma, PetscInt *norma_loc, PetscReal *normr, PetscInt *normr_loc)
2613: {
2614:   PetscFunctionBegin;
2619:   if (E) {
2622:   }
2625:   if (vatol) {
2628:   }
2630:   if (vrtol) {
2633:   }
2635:   PetscAssertPointer(norm, 10);
2636:   PetscAssertPointer(norm_loc, 11);
2637:   PetscAssertPointer(norma, 12);
2638:   PetscAssertPointer(norma_loc, 13);
2639:   PetscAssertPointer(normr, 14);
2640:   PetscAssertPointer(normr_loc, 15);
2641:   PetscCheck(wnormtype == NORM_2 || wnormtype == NORM_INFINITY, PetscObjectComm((PetscObject)U), PETSC_ERR_SUP, "No support for norm type %s", NormTypes[wnormtype]);

2643:   /* There are potentially 5 vectors involved, some of them may happen to be of different type or bound to cpu.
2644:      Here we check that they all implement the same operation and call it if so.
2645:      Otherwise, we call the _Basic implementation that always works (provided VecGetArrayRead is implemented). */
2646:   PetscBool sameop = (PetscBool)(U->ops->errorwnorm && U->ops->errorwnorm == Y->ops->errorwnorm);
2647:   if (sameop && E) sameop = (PetscBool)(U->ops->errorwnorm == E->ops->errorwnorm);
2648:   if (sameop && vatol) sameop = (PetscBool)(U->ops->errorwnorm == vatol->ops->errorwnorm);
2649:   if (sameop && vrtol) sameop = (PetscBool)(U->ops->errorwnorm == vrtol->ops->errorwnorm);
2650:   if (sameop) PetscUseTypeMethod(U, errorwnorm, Y, E, wnormtype, atol, vatol, rtol, vrtol, ignore_max, norm, norm_loc, norma, norma_loc, normr, normr_loc);
2651:   else PetscCall(VecErrorWeightedNorms_Basic(U, Y, E, wnormtype, atol, vatol, rtol, vrtol, ignore_max, norm, norm_loc, norma, norma_loc, normr, normr_loc));
2652:   PetscFunctionReturn(PETSC_SUCCESS);
2653: }