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_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_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()`, `Vec`, `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;
 99:   *mapping = X->map->mapping;
100:   PetscFunctionReturn(PETSC_SUCCESS);
101: }

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

107:    Collective

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

112:    Level: beginner

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

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

132:    Collective

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

137:    Options Database Keys:
138: +  -vec_view - Prints vector in `PETSC_VIEWER_DEFAULT` format
139: .  -vec_view ::ascii_matlab - Prints vector in `PETSC_VIEWER_ASCII_MATLAB` format to stdout
140: .  -vec_view matlab:filename - Prints vector in MATLAB .mat file to filename (requires PETSc configured with --with-matlab)
141: .  -vec_view draw - Activates vector viewing using drawing tools
142: .  -display <name> - Sets display name (default is host)
143: .  -draw_pause <sec> - Sets number of seconds to pause after display
144: -  -vec_view socket - Activates vector viewing using a socket

146:    Level: beginner

148: .seealso: [](ch_vectors), `Vec`, `VecAssemblyBegin()`, `VecSetValues()`
149: @*/
150: PetscErrorCode VecAssemblyEnd(Vec vec)
151: {
152:   PetscFunctionBegin;
154:   PetscCall(PetscLogEventBegin(VEC_AssemblyEnd, vec, 0, 0, 0));
156:   PetscTryTypeMethod(vec, assemblyend);
157:   PetscCall(PetscLogEventEnd(VEC_AssemblyEnd, vec, 0, 0, 0));
158:   PetscCall(VecViewFromOptions(vec, NULL, "-vec_view"));
159:   PetscFunctionReturn(PETSC_SUCCESS);
160: }

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

165:    Collective

167:    Input Parameters:
168: +  x - vector being preallocated
169: .  ncoo - number of entries
170: -  coo_i - entry indices

172:    Level: beginner

174:    Notes:
175:    This and `VecSetValuesCOO()` provide an alernative API to using `VecSetValues()` to provide vector values.

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

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

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

185: .seealso: [](ch_vectors), `Vec`, `VecSetValuesCOO()`, `VecSetPreallocationCOOLocal()`
186: @*/
187: PetscErrorCode VecSetPreallocationCOO(Vec x, PetscCount ncoo, const PetscInt coo_i[])
188: {
189:   PetscFunctionBegin;
193:   PetscCall(PetscLogEventBegin(VEC_SetPreallocateCOO, x, 0, 0, 0));
194:   PetscCall(PetscLayoutSetUp(x->map));
195:   if (x->ops->setpreallocationcoo) {
196:     PetscUseTypeMethod(x, setpreallocationcoo, ncoo, coo_i);
197:   } else {
198:     IS is_coo_i;
199:     /* The default implementation only supports ncoo within limit of PetscInt */
200:     PetscCheck(ncoo <= PETSC_MAX_INT, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "ncoo %" PetscCount_FMT " overflowed PetscInt; configure --with-64-bit-indices or request support", ncoo);
201:     PetscCall(ISCreateGeneral(PETSC_COMM_SELF, ncoo, coo_i, PETSC_COPY_VALUES, &is_coo_i));
202:     PetscCall(PetscObjectCompose((PetscObject)x, "__PETSc_coo_i", (PetscObject)is_coo_i));
203:     PetscCall(ISDestroy(&is_coo_i));
204:   }
205:   PetscCall(PetscLogEventEnd(VEC_SetPreallocateCOO, x, 0, 0, 0));
206:   PetscFunctionReturn(PETSC_SUCCESS);
207: }

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

212:    Collective

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

219:    Level: beginner

221:    Notes:
222:    This and `VecSetValuesCOO()` provide an alernative API to using `VecSetValuesLocal()` to provide vector values.

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

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

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

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

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

241:   PetscFunctionBegin;
245:   PetscCheck(ncoo <= PETSC_MAX_INT, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "ncoo %" PetscCount_FMT " overflowed PetscInt; configure --with-64-bit-indices or request support", ncoo);
246:   PetscCall(PetscLayoutSetUp(x->map));
247:   PetscCall(VecGetLocalToGlobalMapping(x, &ltog));
248:   if (ltog) PetscCall(ISLocalToGlobalMappingApply(ltog, ncoo, coo_i, coo_i));
249:   PetscCall(VecSetPreallocationCOO(x, ncoo, coo_i));
250:   PetscFunctionReturn(PETSC_SUCCESS);
251: }

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

256:    Collective

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

263:    Level: beginner

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

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

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

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

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

309: static PetscErrorCode VecPointwiseApply_Private(Vec w, Vec x, Vec y, PetscLogEvent event, PetscErrorCode (*const pointwise_op)(Vec, Vec, Vec))
310: {
311:   PetscFunctionBegin;
318:   PetscCheckSameTypeAndComm(x, 2, y, 3);
319:   PetscCheckSameTypeAndComm(y, 3, w, 1);
320:   VecCheckSameSize(w, 1, x, 2);
321:   VecCheckSameSize(w, 1, y, 3);
322:   VecCheckAssembled(x);
323:   VecCheckAssembled(y);
324:   PetscCall(VecSetErrorIfLocked(w, 1));

327:   if (event) PetscCall(PetscLogEventBegin(event, x, y, w, 0));
328:   PetscCall((*pointwise_op)(w, x, y));
329:   if (event) PetscCall(PetscLogEventEnd(event, x, y, w, 0));
330:   PetscCall(PetscObjectStateIncrease((PetscObject)w));
331:   PetscFunctionReturn(PETSC_SUCCESS);
332: }

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

337:    Logically Collective

339:    Input Parameters:
340: +  x - the first input vector
341: -  y - the second input vector

343:    Output Parameter:
344: .  w - the result

346:    Level: advanced

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

351:    For complex numbers compares only the real part

353: .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
354: @*/
355: PetscErrorCode VecPointwiseMax(Vec w, Vec x, Vec y)
356: {
357:   PetscFunctionBegin;
359:   // REVIEW ME: no log event?
360:   PetscCall(VecPointwiseApply_Private(w, x, y, 0, w->ops->pointwisemax));
361:   PetscFunctionReturn(PETSC_SUCCESS);
362: }

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

367:    Logically Collective

369:    Input Parameters:
370: +  x - the first input vector
371: -  y - the second input vector

373:    Output Parameter:
374: .  w - the result

376:    Level: advanced

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

381:    For complex numbers compares only the real part

383: .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
384: @*/
385: PetscErrorCode VecPointwiseMin(Vec w, Vec x, Vec y)
386: {
387:   PetscFunctionBegin;
389:   VecCheckAssembled(x);
390:   // REVIEW ME: no log event?
391:   PetscCall(VecPointwiseApply_Private(w, x, y, 0, w->ops->pointwisemin));
392:   PetscFunctionReturn(PETSC_SUCCESS);
393: }

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

398:    Logically Collective

400:    Input Parameters:
401: +  x - the first input vector
402: -  y - the second input vector

404:    Output Parameter:
405: .  w - the result

407:    Level: advanced

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

412: .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMin()`, `VecPointwiseMax()`, `VecMaxPointwiseDivide()`
413: @*/
414: PetscErrorCode VecPointwiseMaxAbs(Vec w, Vec x, Vec y)
415: {
416:   PetscFunctionBegin;
418:   // REVIEW ME: no log event?
419:   PetscCall(VecPointwiseApply_Private(w, x, y, 0, w->ops->pointwisemaxabs));
420:   PetscFunctionReturn(PETSC_SUCCESS);
421: }

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

426:    Logically Collective

428:    Input Parameters:
429: +  x - the numerator vector
430: -  y - the denominator vector

432:    Output Parameter:
433: .  w - the result

435:    Level: advanced

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

440: .seealso: [](ch_vectors), `Vec`, `VecPointwiseMult()`, `VecPointwiseMax()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
441: @*/
442: PetscErrorCode VecPointwiseDivide(Vec w, Vec x, Vec y)
443: {
444:   PetscFunctionBegin;
446:   // REVIEW ME: no log event?
447:   PetscCall(VecPointwiseApply_Private(w, x, y, 0, w->ops->pointwisedivide));
448:   PetscFunctionReturn(PETSC_SUCCESS);
449: }

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

454:    Logically Collective

456:    Input Parameters:
457: +  x - the first vector
458: -  y - the second vector

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

463:    Level: advanced

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

468: .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMax()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
469: @*/
470: PetscErrorCode VecPointwiseMult(Vec w, Vec x, Vec y)
471: {
472:   PetscFunctionBegin;
474:   PetscCall(VecPointwiseApply_Private(w, x, y, VEC_PointwiseMult, w->ops->pointwisemult));
475:   PetscFunctionReturn(PETSC_SUCCESS);
476: }

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

481:    Collective

483:    Input Parameter:
484: .  v - a vector to mimic

486:    Output Parameter:
487: .  newv - location to put new vector

489:    Level: beginner

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

495:    Use `VecDestroy()` to free the space. Use `VecDuplicateVecs()` to get several
496:    vectors.

498: .seealso: [](ch_vectors), `Vec`, `VecDestroy()`, `VecDuplicateVecs()`, `VecCreate()`, `VecCopy()`
499: @*/
500: PetscErrorCode VecDuplicate(Vec v, Vec *newv)
501: {
502:   PetscFunctionBegin;
506:   PetscUseTypeMethod(v, duplicate, newv);
507: #if PetscDefined(HAVE_DEVICE)
508:   if (v->boundtocpu && v->bindingpropagates) {
509:     PetscCall(VecSetBindingPropagates(*newv, PETSC_TRUE));
510:     PetscCall(VecBindToCPU(*newv, PETSC_TRUE));
511:   }
512: #endif
513:   PetscCall(PetscObjectStateIncrease((PetscObject)(*newv)));
514:   PetscFunctionReturn(PETSC_SUCCESS);
515: }

517: /*@C
518:    VecDestroy - Destroys a vector.

520:    Collective

522:    Input Parameter:
523: .  v  - the vector

525:    Level: beginner

527: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecDuplicate()`, `VecDestroyVecs()`
528: @*/
529: PetscErrorCode VecDestroy(Vec *v)
530: {
531:   PetscFunctionBegin;
533:   if (!*v) PetscFunctionReturn(PETSC_SUCCESS);
535:   if (--((PetscObject)(*v))->refct > 0) {
536:     *v = NULL;
537:     PetscFunctionReturn(PETSC_SUCCESS);
538:   }

540:   PetscCall(PetscObjectSAWsViewOff((PetscObject)*v));
541:   /* destroy the internal part */
542:   PetscTryTypeMethod(*v, destroy);
543:   PetscCall(PetscFree((*v)->defaultrandtype));
544:   /* destroy the external/common part */
545:   PetscCall(PetscLayoutDestroy(&(*v)->map));
546:   PetscCall(PetscHeaderDestroy(v));
547:   PetscFunctionReturn(PETSC_SUCCESS);
548: }

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

553:    Collective

555:    Input Parameters:
556: +  m - the number of vectors to obtain
557: -  v - a vector to mimic

559:    Output Parameter:
560: .  V - location to put pointer to array of vectors

562:    Level: intermediate

564:    Note:
565:    Use `VecDestroyVecs()` to free the space. Use `VecDuplicate()` to form a single
566:    vector.

568:    Fortran Note:
569:    The Fortran interface is slightly different from that given below, it
570:    requires one to pass in `V` a `Vec` array of size at least `m`.
571:    See the [](ch_fortran) for details.

573: .seealso: [](ch_vectors), `Vec`, [](ch_fortran), `VecDestroyVecs()`, `VecDuplicate()`, `VecCreate()`, `VecDuplicateVecsF90()`
574: @*/
575: PetscErrorCode VecDuplicateVecs(Vec v, PetscInt m, Vec *V[])
576: {
577:   PetscFunctionBegin;
581:   PetscUseTypeMethod(v, duplicatevecs, m, V);
582: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
583:   if (v->boundtocpu && v->bindingpropagates) {
584:     PetscInt i;

586:     for (i = 0; i < m; i++) {
587:       /* Since ops->duplicatevecs might itself propagate the value of boundtocpu,
588:        * avoid unnecessary overhead by only calling VecBindToCPU() if the vector isn't already bound. */
589:       if (!(*V)[i]->boundtocpu) {
590:         PetscCall(VecSetBindingPropagates((*V)[i], PETSC_TRUE));
591:         PetscCall(VecBindToCPU((*V)[i], PETSC_TRUE));
592:       }
593:     }
594:   }
595: #endif
596:   PetscFunctionReturn(PETSC_SUCCESS);
597: }

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

602:    Collective

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

608:    Level: intermediate

610:    Fortran Note:
611:    The Fortran interface is slightly different from that given below.
612:    See the [](ch_fortran) for details.

614: .seealso: [](ch_vectors), `Vec`, [](ch_fortran), `VecDuplicateVecs()`, `VecDestroyVecsf90()`
615: @*/
616: PetscErrorCode VecDestroyVecs(PetscInt m, Vec *vv[])
617: {
618:   PetscFunctionBegin;
620:   PetscCheck(m >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Trying to destroy negative number of vectors %" PetscInt_FMT, m);
621:   if (!m || !*vv) {
622:     *vv = NULL;
623:     PetscFunctionReturn(PETSC_SUCCESS);
624:   }
627:   PetscCall((*(**vv)->ops->destroyvecs)(m, *vv));
628:   *vv = NULL;
629:   PetscFunctionReturn(PETSC_SUCCESS);
630: }

632: /*@C
633:    VecViewFromOptions - View a vector based on values in the options database

635:    Collective

637:    Input Parameters:
638: +  A - the vector
639: .  obj - Optional object that provides the options prefix for this viewing
640: -  name - command line option

642:    Level: intermediate

644:    Note:
645:    See `PetscObjectViewFromOptions()` to see the `PetscViewer` and PetscViewerFormat` available

647: .seealso: [](ch_vectors), `Vec`, `VecView`, `PetscObjectViewFromOptions()`, `VecCreate()`
648: @*/
649: PetscErrorCode VecViewFromOptions(Vec A, PetscObject obj, const char name[])
650: {
651:   PetscFunctionBegin;
653:   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
654:   PetscFunctionReturn(PETSC_SUCCESS);
655: }

657: /*@C
658:    VecView - Views a vector object.

660:    Collective

662:    Input Parameters:
663: +  vec - the vector
664: -  viewer - an optional `PetscViewer` visualization context

666:    Level: beginner

668:    Notes:
669:    The available visualization contexts include
670: +     `PETSC_VIEWER_STDOUT_SELF` - for sequential vectors
671: .     `PETSC_VIEWER_STDOUT_WORLD` - for parallel vectors created on `PETSC_COMM_WORLD`
672: -     `PETSC_VIEWER_STDOUT`_(comm) - for parallel vectors created on MPI communicator comm

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

677:    The user can open alternative viewers with
678: +    `PetscViewerASCIIOpen()` - Outputs vector to a specified file
679: .    `PetscViewerBinaryOpen()` - Outputs vector in binary to a
680:          specified file; corresponding input uses `VecLoad()`
681: .    `PetscViewerDrawOpen()` - Outputs vector to an X window display
682: .    `PetscViewerSocketOpen()` - Outputs vector to Socket viewer
683: -    `PetscViewerHDF5Open()` - Outputs vector to HDF5 file viewer

685:    The user can call `PetscViewerPushFormat()` to specify the output
686:    format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`,
687:    `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`).  Available formats include
688: +    `PETSC_VIEWER_DEFAULT` - default, prints vector contents
689: .    `PETSC_VIEWER_ASCII_MATLAB` - prints vector contents in MATLAB format
690: .    `PETSC_VIEWER_ASCII_INDEX` - prints vector contents, including indices of vector elements
691: -    `PETSC_VIEWER_ASCII_COMMON` - prints vector contents, using a
692:          format common among all vector types

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

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

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

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

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

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

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

724: .seealso: [](ch_vectors), `Vec`, `VecViewFromOptions()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscDrawLGCreate()`,
725:           `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `VecLoad()`, `PetscViewerCreate()`,
726:           `PetscRealView()`, `PetscScalarView()`, `PetscIntView()`, `PetscViewerHDF5SetTimestep()`
727: @*/
728: PetscErrorCode VecView(Vec vec, PetscViewer viewer)
729: {
730:   PetscBool         iascii;
731:   PetscViewerFormat format;
732:   PetscMPIInt       size;

734:   PetscFunctionBegin;
737:   VecCheckAssembled(vec);
738:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec), &viewer));
740:   PetscCall(PetscViewerGetFormat(viewer, &format));
741:   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size));
742:   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(PETSC_SUCCESS);

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

746:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
747:   if (iascii) {
748:     PetscInt rows, bs;

750:     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)vec, viewer));
751:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
752:       PetscCall(PetscViewerASCIIPushTab(viewer));
753:       PetscCall(VecGetSize(vec, &rows));
754:       PetscCall(VecGetBlockSize(vec, &bs));
755:       if (bs != 1) {
756:         PetscCall(PetscViewerASCIIPrintf(viewer, "length=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n", rows, bs));
757:       } else {
758:         PetscCall(PetscViewerASCIIPrintf(viewer, "length=%" PetscInt_FMT "\n", rows));
759:       }
760:       PetscCall(PetscViewerASCIIPopTab(viewer));
761:     }
762:   }
763:   PetscCall(VecLockReadPush(vec));
764:   PetscCall(PetscLogEventBegin(VEC_View, vec, viewer, 0, 0));
765:   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && vec->ops->viewnative) {
766:     PetscUseTypeMethod(vec, viewnative, viewer);
767:   } else {
768:     PetscUseTypeMethod(vec, view, viewer);
769:   }
770:   PetscCall(VecLockReadPop(vec));
771:   PetscCall(PetscLogEventEnd(VEC_View, vec, viewer, 0, 0));
772:   PetscFunctionReturn(PETSC_SUCCESS);
773: }

775: #if defined(PETSC_USE_DEBUG)
776: #include <../src/sys/totalview/tv_data_display.h>
777: PETSC_UNUSED static int TV_display_type(const struct _p_Vec *v)
778: {
779:   const PetscScalar *values;
780:   char               type[32];

782:   TV_add_row("Local rows", "int", &v->map->n);
783:   TV_add_row("Global rows", "int", &v->map->N);
784:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)v)->type_name);
785:   PetscCall(VecGetArrayRead((Vec)v, &values));
786:   PetscCall(PetscSNPrintf(type, 32, "double[%" PetscInt_FMT "]", v->map->n));
787:   TV_add_row("values", type, values);
788:   PetscCall(VecRestoreArrayRead((Vec)v, &values));
789:   return TV_format_OK;
790: }
791: #endif

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

796:    Collective

798:    Input Parameters:
799: +  vec - the vector
800: -  viewer - an optional `PetscViewer` visualization context

802:    Level: developer

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

809: .seealso: [](ch_vectors), `Vec`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscDrawLGCreate()`, `VecView()`
810:           `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `VecLoad()`, `PetscViewerCreate()`,
811:           `PetscRealView()`, `PetscScalarView()`, `PetscIntView()`, `PetscViewerHDF5SetTimestep()`
812: @*/
813: PetscErrorCode VecViewNative(Vec vec, PetscViewer viewer)
814: {
815:   PetscFunctionBegin;
818:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec), &viewer));
820:   PetscUseTypeMethod(vec, viewnative, viewer);
821:   PetscFunctionReturn(PETSC_SUCCESS);
822: }

824: /*@
825:    VecGetSize - Returns the global number of elements of the vector.

827:    Not Collective

829:    Input Parameter:
830: .  x - the vector

832:    Output Parameter:
833: .  size - the global length of the vector

835:    Level: beginner

837: .seealso: [](ch_vectors), `Vec`, `VecGetLocalSize()`
838: @*/
839: PetscErrorCode VecGetSize(Vec x, PetscInt *size)
840: {
841:   PetscFunctionBegin;
845:   PetscUseTypeMethod(x, getsize, size);
846:   PetscFunctionReturn(PETSC_SUCCESS);
847: }

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

853:    Not Collective

855:    Input Parameter:
856: .  x - the vector

858:    Output Parameter:
859: .  size - the length of the local piece of the vector

861:    Level: beginner

863: .seealso: [](ch_vectors), `Vec`, `VecGetSize()`
864: @*/
865: PetscErrorCode VecGetLocalSize(Vec x, PetscInt *size)
866: {
867:   PetscFunctionBegin;
871:   PetscUseTypeMethod(x, getlocalsize, size);
872:   PetscFunctionReturn(PETSC_SUCCESS);
873: }

875: /*@C
876:    VecGetOwnershipRange - Returns the range of indices owned by
877:    this process. The vector is laid out with the
878:    first n1 elements on the first processor, next n2 elements on the
879:    second, etc.  For certain parallel layouts this range may not be
880:    well defined.

882:    Not Collective

884:    Input Parameter:
885: .  x - the vector

887:    Output Parameters:
888: +  low - the first local element, pass in `NULL` if not interested
889: -  high - one more than the last local element, pass in `NULL` if not interested

891:    Level: beginner

893:    Note:
894:    The high argument is one more than the last element stored locally.

896:    Fortran Note:
897:    `PETSC_NULL_INTEGER` should be used instead of NULL

899: .seealso: [](ch_vectors), `Vec`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `VecGetOwnershipRanges()`
900: @*/
901: PetscErrorCode VecGetOwnershipRange(Vec x, PetscInt *low, PetscInt *high)
902: {
903:   PetscFunctionBegin;
908:   if (low) *low = x->map->rstart;
909:   if (high) *high = x->map->rend;
910:   PetscFunctionReturn(PETSC_SUCCESS);
911: }

913: /*@C
914:    VecGetOwnershipRanges - Returns the range of indices owned by EACH processor,
915:    The vector is laid out with the
916:    first n1 elements on the first processor, next n2 elements on the
917:    second, etc.  For certain parallel layouts this range may not be
918:    well defined.

920:    Not Collective

922:    Input Parameter:
923: .  x - the vector

925:    Output Parameter:
926: .  range - array of length size+1 with the start and end+1 for each process

928:    Level: beginner

930:    Notes:
931:    The high argument is one more than the last element stored locally.

933:    If the ranges are used after all vectors that share the ranges has been destroyed then the program will crash accessing ranges[].

935:    Fortran Note:
936:    You must PASS in an array of length size+1

938: .seealso: [](ch_vectors), `Vec`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `VecGetOwnershipRange()`
939: @*/
940: PetscErrorCode VecGetOwnershipRanges(Vec x, const PetscInt *ranges[])
941: {
942:   PetscFunctionBegin;
945:   PetscCall(PetscLayoutGetRanges(x->map, ranges));
946:   PetscFunctionReturn(PETSC_SUCCESS);
947: }

949: /*@
950:    VecSetOption - Sets an option for controlling a vector's behavior.

952:    Collective

954:    Input Parameters:
955: +  x - the vector
956: .  op - the option
957: -  flag - turn the option on or off

959:    Supported Options:
960: +     `VEC_IGNORE_OFF_PROC_ENTRIES`, which causes `VecSetValues()` to ignore
961:           entries destined to be stored on a separate processor. This can be used
962:           to eliminate the global reduction in the `VecAssemblyBegin()` if you know
963:           that you have only used `VecSetValues()` to set local elements
964: .     `VEC_IGNORE_NEGATIVE_INDICES`, which means you can pass negative indices
965:           in ix in calls to `VecSetValues()` or `VecGetValues()`. These rows are simply
966:           ignored.
967: -     `VEC_SUBSET_OFF_PROC_ENTRIES`, which causes `VecAssemblyBegin()` to assume that the off-process
968:           entries will always be a subset (possibly equal) of the off-process entries set on the
969:           first assembly which had a true `VEC_SUBSET_OFF_PROC_ENTRIES` and the vector has not
970:           changed this flag afterwards. If this assembly is not such first assembly, then this
971:           assembly can reuse the communication pattern setup in that first assembly, thus avoiding
972:           a global reduction. Subsequent assemblies setting off-process values should use the same
973:           InsertMode as the first assembly.

975:    Level: intermediate

977:    Developer Note:
978:    The `InsertMode` restriction could be removed by packing the stash messages out of place.

980: .seealso: [](ch_vectors), `Vec`, `VecSetValues()`
981: @*/
982: PetscErrorCode VecSetOption(Vec x, VecOption op, PetscBool flag)
983: {
984:   PetscFunctionBegin;
987:   PetscTryTypeMethod(x, setoption, op, flag);
988:   PetscFunctionReturn(PETSC_SUCCESS);
989: }

991: /* Default routines for obtaining and releasing; */
992: /* may be used by any implementation */
993: PetscErrorCode VecDuplicateVecs_Default(Vec w, PetscInt m, Vec *V[])
994: {
995:   PetscFunctionBegin;
998:   PetscCheck(m > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "m must be > 0: m = %" PetscInt_FMT, m);
999:   PetscCall(PetscMalloc1(m, V));
1000:   for (PetscInt i = 0; i < m; i++) PetscCall(VecDuplicate(w, *V + i));
1001:   PetscFunctionReturn(PETSC_SUCCESS);
1002: }

1004: PetscErrorCode VecDestroyVecs_Default(PetscInt m, Vec v[])
1005: {
1006:   PetscInt i;

1008:   PetscFunctionBegin;
1010:   for (i = 0; i < m; i++) PetscCall(VecDestroy(&v[i]));
1011:   PetscCall(PetscFree(v));
1012:   PetscFunctionReturn(PETSC_SUCCESS);
1013: }

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

1019:    Not Collective

1021:    Input Parameter:
1022: .  vec - the vector

1024:    Level: developer

1026: .seealso: [](ch_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecPlaceArray()`
1027: @*/
1028: PetscErrorCode VecResetArray(Vec vec)
1029: {
1030:   PetscFunctionBegin;
1033:   PetscUseTypeMethod(vec, resetarray);
1034:   PetscCall(PetscObjectStateIncrease((PetscObject)vec));
1035:   PetscFunctionReturn(PETSC_SUCCESS);
1036: }

1038: /*@C
1039:   VecLoad - Loads a vector that has been stored in binary or HDF5 format
1040:   with `VecView()`.

1042:   Collective

1044:   Input Parameters:
1045: + vec - the newly loaded vector, this needs to have been created with `VecCreate()` or
1046:            some related function before the call to `VecLoad()`.
1047: - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` or
1048:            HDF5 file viewer, obtained from `PetscViewerHDF5Open()`

1050:    Level: intermediate

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

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

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

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

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

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

1078:   Notes for advanced users when using the binary viewer:
1079:   Most users should not need to know the details of the binary storage
1080:   format, since `VecLoad()` and `VecView()` completely hide these details.
1081:   But for anyone who's interested, the standard binary vector storage
1082:   format is
1083: .vb
1084:      PetscInt    VEC_FILE_CLASSID
1085:      PetscInt    number of rows
1086:      PetscScalar *values of all entries
1087: .ve

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

1094: .seealso: [](ch_vectors), `Vec`, `PetscViewerBinaryOpen()`, `VecView()`, `MatLoad()`, `VecLoad()`
1095: @*/
1096: PetscErrorCode VecLoad(Vec vec, PetscViewer viewer)
1097: {
1098:   PetscBool         isbinary, ishdf5, isadios, isexodusii;
1099:   PetscViewerFormat format;

1101:   PetscFunctionBegin;
1104:   PetscCheckSameComm(vec, 1, viewer, 2);
1105:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
1106:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
1107:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERADIOS, &isadios));
1108:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWEREXODUSII, &isexodusii));
1109:   PetscCheck(isbinary || ishdf5 || isadios || isexodusii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen()");

1111:   PetscCall(VecSetErrorIfLocked(vec, 1));
1112:   if (!((PetscObject)vec)->type_name && !vec->ops->create) PetscCall(VecSetType(vec, VECSTANDARD));
1113:   PetscCall(PetscLogEventBegin(VEC_Load, viewer, 0, 0, 0));
1114:   PetscCall(PetscViewerGetFormat(viewer, &format));
1115:   if (format == PETSC_VIEWER_NATIVE && vec->ops->loadnative) {
1116:     PetscUseTypeMethod(vec, loadnative, viewer);
1117:   } else {
1118:     PetscUseTypeMethod(vec, load, viewer);
1119:   }
1120:   PetscCall(PetscLogEventEnd(VEC_Load, viewer, 0, 0, 0));
1121:   PetscFunctionReturn(PETSC_SUCCESS);
1122: }

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

1127:    Logically Collective

1129:    Input Parameter:
1130: .  vec - the vector

1132:    Output Parameter:
1133: .  vec - the vector reciprocal

1135:    Level: intermediate

1137:    Note:
1138:    Vector entries with value 0.0 are not changed

1140: .seealso: [](ch_vectors), `Vec`, `VecLog()`, `VecExp()`, `VecSqrtAbs()`
1141: @*/
1142: PetscErrorCode VecReciprocal(Vec vec)
1143: {
1144:   PetscFunctionBegin;
1147:   VecCheckAssembled(vec);
1148:   PetscCall(VecSetErrorIfLocked(vec, 1));
1149:   PetscUseTypeMethod(vec, reciprocal);
1150:   PetscCall(PetscObjectStateIncrease((PetscObject)vec));
1151:   PetscFunctionReturn(PETSC_SUCCESS);
1152: }

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

1157:    Logically Collective; No Fortran Support

1159:   Input Parameters:
1160: + vec - The vector to modify
1161: . op  - The name of the operation
1162: - f   - The function that provides the operation.

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

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

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

1177:   Level: advanced

1179:   Example Usage:
1180: .vb
1181:   // some new VecView() implementation, must have the same signature as the function it seeks
1182:   // to replace
1183:   PetscErrorCode UserVecView(Vec x, PetscViewer viewer)
1184:   {
1185:     PetscFunctionBeginUser;
1186:     // ...
1187:     PetscFunctionReturn(PETSC_SUCCESS);
1188:   }

1190:   // Create a VECMPI which has a pre-defined VecView() implementation
1191:   VecCreateMPI(comm, n, N, &x);
1192:   // Calls the VECMPI implementation for VecView()
1193:   VecView(x, viewer);

1195:   VecSetOperation(x, VECOP_VIEW, (void (*)(void))UserVecView);
1196:   // Now calls UserVecView()
1197:   VecView(x, viewer);
1198: .ve

1200: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `MatShellSetOperation()`
1201: @*/
1202: PetscErrorCode VecSetOperation(Vec vec, VecOperation op, void (*f)(void))
1203: {
1204:   PetscFunctionBegin;
1206:   if (op == VECOP_VIEW && !vec->ops->viewnative) {
1207:     vec->ops->viewnative = vec->ops->view;
1208:   } else if (op == VECOP_LOAD && !vec->ops->loadnative) {
1209:     vec->ops->loadnative = vec->ops->load;
1210:   }
1211:   ((void (**)(void))vec->ops)[(int)op] = f;
1212:   PetscFunctionReturn(PETSC_SUCCESS);
1213: }

1215: /*@
1216:    VecStashSetInitialSize - sets the sizes of the vec-stash, that is
1217:    used during the assembly process to store values that belong to
1218:    other processors.

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

1222:    Input Parameters:
1223: +  vec   - the vector
1224: .  size  - the initial size of the stash.
1225: -  bsize - the initial size of the block-stash(if used).

1227:    Options Database Keys:
1228: +   -vecstash_initial_size <size> or <size0,size1,...sizep-1>
1229: -   -vecstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>

1231:    Level: intermediate

1233:    Notes:
1234:      The block-stash is used for values set with `VecSetValuesBlocked()` while
1235:      the stash is used for values set with `VecSetValues()`

1237:      Run with the option -info and look for output of the form
1238:      VecAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
1239:      to determine the appropriate value, MM, to use for size and
1240:      VecAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
1241:      to determine the value, BMM to use for bsize

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

1246: .seealso: [](ch_vectors), `Vec`, `VecSetBlockSize()`, `VecSetValues()`, `VecSetValuesBlocked()`, `VecStashView()`
1247: @*/
1248: PetscErrorCode VecStashSetInitialSize(Vec vec, PetscInt size, PetscInt bsize)
1249: {
1250:   PetscFunctionBegin;
1252:   PetscCall(VecStashSetInitialSize_Private(&vec->stash, size));
1253:   PetscCall(VecStashSetInitialSize_Private(&vec->bstash, bsize));
1254:   PetscFunctionReturn(PETSC_SUCCESS);
1255: }

1257: /*@
1258:    VecConjugate - Conjugates a vector. That is, replace every entry in a vector with its complex conjugate

1260:    Logically Collective

1262:    Input Parameter:
1263: .  x - the vector

1265:    Level: intermediate

1267: .seealso: [](ch_vectors), `Vec`, `VecSet()`
1268: @*/
1269: PetscErrorCode VecConjugate(Vec x)
1270: {
1271:   PetscFunctionBegin;
1274:   VecCheckAssembled(x);
1275:   PetscCall(VecSetErrorIfLocked(x, 1));
1276:   if (PetscDefined(USE_COMPLEX)) {
1277:     PetscUseTypeMethod(x, conjugate);
1278:     /* we need to copy norms here */
1279:     PetscCall(PetscObjectStateIncrease((PetscObject)x));
1280:   }
1281:   PetscFunctionReturn(PETSC_SUCCESS);
1282: }

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

1287:    Logically Collective

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

1293:    Output Parameter:
1294: .  x  - the vector

1296:    Example of Usage:
1297: .vb
1298:      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
1299:      VecSetRandom(x,rctx);
1300:      PetscRandomDestroy(&rctx);
1301: .ve

1303:    Level: intermediate

1305: .seealso: [](ch_vectors), `Vec`, `VecSet()`, `VecSetValues()`, `PetscRandomCreate()`, `PetscRandomDestroy()`
1306: @*/
1307: PetscErrorCode VecSetRandom(Vec x, PetscRandom rctx)
1308: {
1309:   PetscRandom randObj = NULL;

1311:   PetscFunctionBegin;
1315:   VecCheckAssembled(x);
1316:   PetscCall(VecSetErrorIfLocked(x, 1));

1318:   if (!rctx) {
1319:     PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject)x), &randObj));
1320:     PetscCall(PetscRandomSetType(randObj, x->defaultrandtype));
1321:     PetscCall(PetscRandomSetFromOptions(randObj));
1322:     rctx = randObj;
1323:   }

1325:   PetscCall(PetscLogEventBegin(VEC_SetRandom, x, rctx, 0, 0));
1326:   PetscUseTypeMethod(x, setrandom, rctx);
1327:   PetscCall(PetscLogEventEnd(VEC_SetRandom, x, rctx, 0, 0));

1329:   PetscCall(PetscRandomDestroy(&randObj));
1330:   PetscCall(PetscObjectStateIncrease((PetscObject)x));
1331:   PetscFunctionReturn(PETSC_SUCCESS);
1332: }

1334: /*@
1335:   VecZeroEntries - puts a `0.0` in each element of a vector

1337:   Logically Collective

1339:   Input Parameter:
1340: . vec - The vector

1342:   Level: beginner

1344: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecSetOptionsPrefix()`, `VecSet()`, `VecSetValues()`
1345: @*/
1346: PetscErrorCode VecZeroEntries(Vec vec)
1347: {
1348:   PetscFunctionBegin;
1349:   PetscCall(VecSet(vec, 0));
1350:   PetscFunctionReturn(PETSC_SUCCESS);
1351: }

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

1357:   Collective

1359:   Input Parameter:
1360: . vec - The vector

1362:   Level: intermediate

1364: .seealso: [](ch_vectors), `Vec`, `VecSetFromOptions()`, `VecSetType()`
1365: */
1366: static PetscErrorCode VecSetTypeFromOptions_Private(Vec vec, PetscOptionItems *PetscOptionsObject)
1367: {
1368:   PetscBool   opt;
1369:   VecType     defaultType;
1370:   char        typeName[256];
1371:   PetscMPIInt size;

1373:   PetscFunctionBegin;
1374:   if (((PetscObject)vec)->type_name) defaultType = ((PetscObject)vec)->type_name;
1375:   else {
1376:     PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size));
1377:     if (size > 1) defaultType = VECMPI;
1378:     else defaultType = VECSEQ;
1379:   }

1381:   PetscCall(VecRegisterAll());
1382:   PetscCall(PetscOptionsFList("-vec_type", "Vector type", "VecSetType", VecList, defaultType, typeName, 256, &opt));
1383:   if (opt) {
1384:     PetscCall(VecSetType(vec, typeName));
1385:   } else {
1386:     PetscCall(VecSetType(vec, defaultType));
1387:   }
1388:   PetscFunctionReturn(PETSC_SUCCESS);
1389: }

1391: /*@
1392:   VecSetFromOptions - Configures the vector from the options database.

1394:   Collective

1396:   Input Parameter:
1397: . vec - The vector

1399:   Level: beginner

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

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

1406: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecSetOptionsPrefix()`
1407: @*/
1408: PetscErrorCode VecSetFromOptions(Vec vec)
1409: {
1410:   PetscBool flg;
1411:   PetscInt  bind_below = 0;

1413:   PetscFunctionBegin;

1416:   PetscObjectOptionsBegin((PetscObject)vec);
1417:   /* Handle vector type options */
1418:   PetscCall(VecSetTypeFromOptions_Private(vec, PetscOptionsObject));

1420:   /* Handle specific vector options */
1421:   PetscTryTypeMethod(vec, setfromoptions, PetscOptionsObject);

1423:   /* Bind to CPU if below a user-specified size threshold.
1424:    * This perhaps belongs in the options for the GPU Vec types, but VecBindToCPU() does nothing when called on non-GPU types,
1425:    * and putting it here makes is more maintainable than duplicating this for all. */
1426:   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));
1427:   if (flg && vec->map->n < bind_below) PetscCall(VecBindToCPU(vec, PETSC_TRUE));

1429:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
1430:   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)vec, PetscOptionsObject));
1431:   PetscOptionsEnd();
1432:   PetscFunctionReturn(PETSC_SUCCESS);
1433: }

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

1438:   Collective

1440:   Input Parameters:
1441: + v - the vector
1442: . n - the local size (or `PETSC_DECIDE` to have it set)
1443: - N - the global size (or `PETSC_DETERMINE` to have it set)

1445:   Level: intermediate

1447:   Notes:
1448:   `N` cannot be `PETSC_DETERMINE` if `n` is `PETSC_DECIDE`

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

1452: .seealso: [](ch_vectors), `Vec`, `VecGetSize()`, `PetscSplitOwnership()`
1453: @*/
1454: PetscErrorCode VecSetSizes(Vec v, PetscInt n, PetscInt N)
1455: {
1456:   PetscFunctionBegin;
1458:   if (N >= 0) {
1460:     PetscCheck(n <= N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " cannot be larger than global size %" PetscInt_FMT, n, N);
1461:   }
1462:   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,
1463:              v->map->n, v->map->N);
1464:   v->map->n = n;
1465:   v->map->N = N;
1466:   PetscTryTypeMethod(v, create);
1467:   v->ops->create = NULL;
1468:   PetscFunctionReturn(PETSC_SUCCESS);
1469: }

1471: /*@
1472:    VecSetBlockSize - Sets the block size for future calls to `VecSetValuesBlocked()`
1473:    and `VecSetValuesBlockedLocal()`.

1475:    Logically Collective

1477:    Input Parameters:
1478: +  v - the vector
1479: -  bs - the blocksize

1481:    Level: advanced

1483:    Note:
1484:    All vectors obtained by `VecDuplicate()` inherit the same blocksize.

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

1488: .seealso: [](ch_vectors), `Vec`, `VecSetValuesBlocked()`, `VecSetLocalToGlobalMapping()`, `VecGetBlockSize()`
1489: @*/
1490: PetscErrorCode VecSetBlockSize(Vec v, PetscInt bs)
1491: {
1492:   PetscFunctionBegin;
1495:   PetscCall(PetscLayoutSetBlockSize(v->map, bs));
1496:   v->bstash.bs = bs; /* use the same blocksize for the vec's block-stash */
1497:   PetscFunctionReturn(PETSC_SUCCESS);
1498: }

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

1504:    Not Collective

1506:    Input Parameter:
1507: .  v - the vector

1509:    Output Parameter:
1510: .  bs - the blocksize

1512:    Level: advanced

1514:    Note:
1515:    All vectors obtained by `VecDuplicate()` inherit the same blocksize.

1517: .seealso: [](ch_vectors), `Vec`, `VecSetValuesBlocked()`, `VecSetLocalToGlobalMapping()`, `VecSetBlockSize()`
1518: @*/
1519: PetscErrorCode VecGetBlockSize(Vec v, PetscInt *bs)
1520: {
1521:   PetscFunctionBegin;
1524:   PetscCall(PetscLayoutGetBlockSize(v->map, bs));
1525:   PetscFunctionReturn(PETSC_SUCCESS);
1526: }

1528: /*@C
1529:    VecSetOptionsPrefix - Sets the prefix used for searching for all
1530:    `Vec` options in the database.

1532:    Logically Collective

1534:    Input Parameters:
1535: +  v - the `Vec` context
1536: -  prefix - the prefix to prepend to all option names

1538:    Level: advanced

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

1544: .seealso: [](ch_vectors), `Vec`, `VecSetFromOptions()`
1545: @*/
1546: PetscErrorCode VecSetOptionsPrefix(Vec v, const char prefix[])
1547: {
1548:   PetscFunctionBegin;
1550:   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)v, prefix));
1551:   PetscFunctionReturn(PETSC_SUCCESS);
1552: }

1554: /*@C
1555:    VecAppendOptionsPrefix - Appends to the prefix used for searching for all
1556:    `Vec` options in the database.

1558:    Logically Collective

1560:    Input Parameters:
1561: +  v - the `Vec` context
1562: -  prefix - the prefix to prepend to all option names

1564:    Level: advanced

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

1570: .seealso: [](ch_vectors), `Vec`, `VecGetOptionsPrefix()`
1571: @*/
1572: PetscErrorCode VecAppendOptionsPrefix(Vec v, const char prefix[])
1573: {
1574:   PetscFunctionBegin;
1576:   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)v, prefix));
1577:   PetscFunctionReturn(PETSC_SUCCESS);
1578: }

1580: /*@C
1581:    VecGetOptionsPrefix - Sets the prefix used for searching for all
1582:    Vec options in the database.

1584:    Not Collective

1586:    Input Parameter:
1587: .  v - the `Vec` context

1589:    Output Parameter:
1590: .  prefix - pointer to the prefix string used

1592:    Level: advanced

1594:    Fortran Note:
1595:    The user must pass in a string `prefix` of
1596:    sufficient length to hold the prefix.

1598: .seealso: [](ch_vectors), `Vec`, `VecAppendOptionsPrefix()`
1599: @*/
1600: PetscErrorCode VecGetOptionsPrefix(Vec v, const char *prefix[])
1601: {
1602:   PetscFunctionBegin;
1604:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)v, prefix));
1605:   PetscFunctionReturn(PETSC_SUCCESS);
1606: }

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

1611:    Collective

1613:    Input Parameter:
1614: .  v - the `Vec` context

1616:    Level: advanced

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

1622: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecDestroy()`
1623: @*/
1624: PetscErrorCode VecSetUp(Vec v)
1625: {
1626:   PetscMPIInt size;

1628:   PetscFunctionBegin;
1630:   PetscCheck(v->map->n >= 0 || v->map->N >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Sizes not set");
1631:   if (!((PetscObject)v)->type_name) {
1632:     PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)v), &size));
1633:     if (size == 1) {
1634:       PetscCall(VecSetType(v, VECSEQ));
1635:     } else {
1636:       PetscCall(VecSetType(v, VECMPI));
1637:     }
1638:   }
1639:   PetscFunctionReturn(PETSC_SUCCESS);
1640: }

1642: /*
1643:     These currently expose the PetscScalar/PetscReal in updating the
1644:     cached norm. If we push those down into the implementation these
1645:     will become independent of PetscScalar/PetscReal
1646: */

1648: /*@
1649:    VecCopy - Copies a vector `y = x`

1651:    Logically Collective

1653:    Input Parameter:
1654: .  x - the vector

1656:    Output Parameter:
1657: .  y - the copy

1659:    Level: beginner

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

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

1670: .seealso: [](ch_vectors), `Vec`, `VecDuplicate()`
1671: @*/
1672: PetscErrorCode VecCopy(Vec x, Vec y)
1673: {
1674:   PetscBool flgs[4];
1675:   PetscReal norms[4] = {0.0, 0.0, 0.0, 0.0};

1677:   PetscFunctionBegin;
1682:   if (x == y) PetscFunctionReturn(PETSC_SUCCESS);
1683:   VecCheckSameLocalSize(x, 1, y, 2);
1684:   VecCheckAssembled(x);
1685:   PetscCall(VecSetErrorIfLocked(y, 2));

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

1691:   PetscCall(PetscLogEventBegin(VEC_Copy, x, y, 0, 0));
1692: #if defined(PETSC_USE_MIXED_PRECISION)
1693:   extern PetscErrorCode VecGetArray(Vec, double **);
1694:   extern PetscErrorCode VecRestoreArray(Vec, double **);
1695:   extern PetscErrorCode VecGetArray(Vec, float **);
1696:   extern PetscErrorCode VecRestoreArray(Vec, float **);
1697:   extern PetscErrorCode VecGetArrayRead(Vec, const double **);
1698:   extern PetscErrorCode VecRestoreArrayRead(Vec, const double **);
1699:   extern PetscErrorCode VecGetArrayRead(Vec, const float **);
1700:   extern PetscErrorCode VecRestoreArrayRead(Vec, const float **);
1701:   if ((((PetscObject)x)->precision == PETSC_PRECISION_SINGLE) && (((PetscObject)y)->precision == PETSC_PRECISION_DOUBLE)) {
1702:     PetscInt     i, n;
1703:     const float *xx;
1704:     double      *yy;
1705:     PetscCall(VecGetArrayRead(x, &xx));
1706:     PetscCall(VecGetArray(y, &yy));
1707:     PetscCall(VecGetLocalSize(x, &n));
1708:     for (i = 0; i < n; i++) yy[i] = xx[i];
1709:     PetscCall(VecRestoreArrayRead(x, &xx));
1710:     PetscCall(VecRestoreArray(y, &yy));
1711:   } else if ((((PetscObject)x)->precision == PETSC_PRECISION_DOUBLE) && (((PetscObject)y)->precision == PETSC_PRECISION_SINGLE)) {
1712:     PetscInt      i, n;
1713:     float        *yy;
1714:     const double *xx;
1715:     PetscCall(VecGetArrayRead(x, &xx));
1716:     PetscCall(VecGetArray(y, &yy));
1717:     PetscCall(VecGetLocalSize(x, &n));
1718:     for (i = 0; i < n; i++) yy[i] = (float)xx[i];
1719:     PetscCall(VecRestoreArrayRead(x, &xx));
1720:     PetscCall(VecRestoreArray(y, &yy));
1721:   } else PetscUseTypeMethod(x, copy, y);
1722: #else
1723:   PetscUseTypeMethod(x, copy, y);
1724: #endif

1726:   PetscCall(PetscObjectStateIncrease((PetscObject)y));
1727: #if !defined(PETSC_USE_MIXED_PRECISION)
1728:   for (PetscInt i = 0; i < 4; i++) {
1729:     if (flgs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)y, NormIds[i], norms[i]));
1730:   }
1731: #endif

1733:   PetscCall(PetscLogEventEnd(VEC_Copy, x, y, 0, 0));
1734:   PetscFunctionReturn(PETSC_SUCCESS);
1735: }

1737: /*@
1738:    VecSwap - Swaps the values between two vectors, `x` and `y`.

1740:    Logically Collective

1742:    Input Parameters:
1743: +  x  - the first vector
1744: -  y  - the second vector

1746:    Level: advanced

1748: .seealso: [](ch_vectors), `Vec`, `VecSet()`
1749: @*/
1750: PetscErrorCode VecSwap(Vec x, Vec y)
1751: {
1752:   PetscReal normxs[4], normys[4];
1753:   PetscBool flgxs[4], flgys[4];

1755:   PetscFunctionBegin;
1760:   PetscCheckSameTypeAndComm(x, 1, y, 2);
1761:   VecCheckSameSize(x, 1, y, 2);
1762:   VecCheckAssembled(x);
1763:   VecCheckAssembled(y);
1764:   PetscCall(VecSetErrorIfLocked(x, 1));
1765:   PetscCall(VecSetErrorIfLocked(y, 2));

1767:   for (PetscInt i = 0; i < 4; i++) {
1768:     PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], normxs[i], flgxs[i]));
1769:     PetscCall(PetscObjectComposedDataGetReal((PetscObject)y, NormIds[i], normys[i], flgys[i]));
1770:   }

1772:   PetscCall(PetscLogEventBegin(VEC_Swap, x, y, 0, 0));
1773:   PetscUseTypeMethod(x, swap, y);
1774:   PetscCall(PetscLogEventEnd(VEC_Swap, x, y, 0, 0));

1776:   PetscCall(PetscObjectStateIncrease((PetscObject)x));
1777:   PetscCall(PetscObjectStateIncrease((PetscObject)y));
1778:   for (PetscInt i = 0; i < 4; i++) {
1779:     if (flgxs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)y, NormIds[i], normxs[i]));
1780:     if (flgys[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[i], normys[i]));
1781:   }
1782:   PetscFunctionReturn(PETSC_SUCCESS);
1783: }

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

1788:   Collective

1790:   Input Parameters:
1791: + obj   - the `Vec` containing a stash
1792: . bobj - optional other object that provides the prefix
1793: - optionname - option to activate viewing

1795:   Level: intermediate

1797:   Developer Note:
1798:   This cannot use `PetscObjectViewFromOptions()` because it takes a `Vec` as an argument but does not use `VecView()`

1800: .seealso: [](ch_vectors), `Vec`, `VecStashSetInitialSize()`
1801: @*/
1802: PetscErrorCode VecStashViewFromOptions(Vec obj, PetscObject bobj, const char optionname[])
1803: {
1804:   PetscViewer       viewer;
1805:   PetscBool         flg;
1806:   PetscViewerFormat format;
1807:   char             *prefix;

1809:   PetscFunctionBegin;
1810:   prefix = bobj ? bobj->prefix : ((PetscObject)obj)->prefix;
1811:   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj), ((PetscObject)obj)->options, prefix, optionname, &viewer, &format, &flg));
1812:   if (flg) {
1813:     PetscCall(PetscViewerPushFormat(viewer, format));
1814:     PetscCall(VecStashView(obj, viewer));
1815:     PetscCall(PetscViewerPopFormat(viewer));
1816:     PetscCall(PetscViewerDestroy(&viewer));
1817:   }
1818:   PetscFunctionReturn(PETSC_SUCCESS);
1819: }

1821: /*@
1822:    VecStashView - Prints the entries in the vector stash and block stash.

1824:    Collective

1826:    Input Parameters:
1827: +  v - the vector
1828: -  viewer - the viewer

1830:    Level: advanced

1832: .seealso: [](ch_vectors), `Vec`, `VecSetBlockSize()`, `VecSetValues()`, `VecSetValuesBlocked()`
1833: @*/
1834: PetscErrorCode VecStashView(Vec v, PetscViewer viewer)
1835: {
1836:   PetscMPIInt rank;
1837:   PetscInt    i, j;
1838:   PetscBool   match;
1839:   VecStash   *s;
1840:   PetscScalar val;

1842:   PetscFunctionBegin;
1845:   PetscCheckSameComm(v, 1, viewer, 2);

1847:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &match));
1848:   PetscCheck(match, PETSC_COMM_SELF, PETSC_ERR_SUP, "Stash viewer only works with ASCII viewer not %s", ((PetscObject)v)->type_name);
1849:   PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1850:   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)v), &rank));
1851:   s = &v->bstash;

1853:   /* print block stash */
1854:   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
1855:   PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Vector Block stash size %" PetscInt_FMT " block size %" PetscInt_FMT "\n", rank, s->n, s->bs));
1856:   for (i = 0; i < s->n; i++) {
1857:     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " ", rank, s->idx[i]));
1858:     for (j = 0; j < s->bs; j++) {
1859:       val = s->array[i * s->bs + j];
1860: #if defined(PETSC_USE_COMPLEX)
1861:       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "(%18.16e %18.16e) ", (double)PetscRealPart(val), (double)PetscImaginaryPart(val)));
1862: #else
1863:       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%18.16e ", (double)val));
1864: #endif
1865:     }
1866:     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
1867:   }
1868:   PetscCall(PetscViewerFlush(viewer));

1870:   s = &v->stash;

1872:   /* print basic stash */
1873:   PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Vector stash size %" PetscInt_FMT "\n", rank, s->n));
1874:   for (i = 0; i < s->n; i++) {
1875:     val = s->array[i];
1876: #if defined(PETSC_USE_COMPLEX)
1877:     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " (%18.16e %18.16e) ", rank, s->idx[i], (double)PetscRealPart(val), (double)PetscImaginaryPart(val)));
1878: #else
1879:     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " %18.16e\n", rank, s->idx[i], (double)val));
1880: #endif
1881:   }
1882:   PetscCall(PetscViewerFlush(viewer));
1883:   PetscCall(PetscViewerASCIIPopSynchronized(viewer));
1884:   PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1885:   PetscFunctionReturn(PETSC_SUCCESS);
1886: }

1888: PetscErrorCode PetscOptionsGetVec(PetscOptions options, const char prefix[], const char key[], Vec v, PetscBool *set)
1889: {
1890:   PetscInt     i, N, rstart, rend;
1891:   PetscScalar *xx;
1892:   PetscReal   *xreal;
1893:   PetscBool    iset;

1895:   PetscFunctionBegin;
1896:   PetscCall(VecGetOwnershipRange(v, &rstart, &rend));
1897:   PetscCall(VecGetSize(v, &N));
1898:   PetscCall(PetscCalloc1(N, &xreal));
1899:   PetscCall(PetscOptionsGetRealArray(options, prefix, key, xreal, &N, &iset));
1900:   if (iset) {
1901:     PetscCall(VecGetArray(v, &xx));
1902:     for (i = rstart; i < rend; i++) xx[i - rstart] = xreal[i];
1903:     PetscCall(VecRestoreArray(v, &xx));
1904:   }
1905:   PetscCall(PetscFree(xreal));
1906:   if (set) *set = iset;
1907:   PetscFunctionReturn(PETSC_SUCCESS);
1908: }

1910: /*@
1911:    VecGetLayout - get `PetscLayout` describing a vector layout

1913:    Not Collective

1915:    Input Parameter:
1916: .  x - the vector

1918:    Output Parameter:
1919: .  map - the layout

1921:    Level: developer

1923:    Note:
1924:    The layout determines what vector elements are contained on each MPI process

1926: .seealso: [](ch_vectors), `PetscLayout`, `Vec`, `VecGetSizes()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
1927: @*/
1928: PetscErrorCode VecGetLayout(Vec x, PetscLayout *map)
1929: {
1930:   PetscFunctionBegin;
1933:   *map = x->map;
1934:   PetscFunctionReturn(PETSC_SUCCESS);
1935: }

1937: /*@
1938:    VecSetLayout - set `PetscLayout` describing vector layout

1940:    Not Collective

1942:    Input Parameters:
1943: +  x - the vector
1944: -  map - the layout

1946:    Level: developer

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

1951: .seealso: [](ch_vectors), `Vec`, `PetscLayout`, `VecGetLayout()`, `VecGetSizes()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
1952: @*/
1953: PetscErrorCode VecSetLayout(Vec x, PetscLayout map)
1954: {
1955:   PetscFunctionBegin;
1957:   PetscCall(PetscLayoutReference(map, &x->map));
1958:   PetscFunctionReturn(PETSC_SUCCESS);
1959: }

1961: PetscErrorCode VecSetInf(Vec xin)
1962: {
1963:   // use of variables one and zero over just doing 1.0/0.0 is deliberate. MSVC complains that
1964:   // we are dividing by zero in the latter case (ostensibly because dividing by 0 is UB, but
1965:   // only for *integers* not floats).
1966:   const PetscScalar one = 1.0, zero = 0.0;
1967:   PetscScalar       inf;

1969:   PetscFunctionBegin;
1970:   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
1971:   inf = one / zero;
1972:   PetscCall(PetscFPTrapPop());
1973:   if (xin->ops->set) {
1974:     PetscUseTypeMethod(xin, set, inf);
1975:   } else {
1976:     PetscInt     n;
1977:     PetscScalar *xx;

1979:     PetscCall(VecGetLocalSize(xin, &n));
1980:     PetscCall(VecGetArrayWrite(xin, &xx));
1981:     for (PetscInt i = 0; i < n; ++i) xx[i] = inf;
1982:     PetscCall(VecRestoreArrayWrite(xin, &xx));
1983:   }
1984:   PetscFunctionReturn(PETSC_SUCCESS);
1985: }

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

1990:   Logically collective

1992:    Input Parameters:
1993: +   v - the vector
1994: -   flg - bind to the CPU if value of `PETSC_TRUE`

1996:    Level: intermediate

1998: .seelaso: [](ch_vectors), `Vec`, `VecBoundToCPU()`
1999: @*/
2000: PetscErrorCode VecBindToCPU(Vec v, PetscBool flg)
2001: {
2002:   PetscFunctionBegin;
2005: #if defined(PETSC_HAVE_DEVICE)
2006:   if (v->boundtocpu == flg) PetscFunctionReturn(PETSC_SUCCESS);
2007:   v->boundtocpu = flg;
2008:   PetscTryTypeMethod(v, bindtocpu, flg);
2009: #endif
2010:   PetscFunctionReturn(PETSC_SUCCESS);
2011: }

2013: /*@
2014:      VecBoundToCPU - query if a vector is bound to the CPU

2016:   Not collective

2018:    Input Parameter:
2019: .   v - the vector

2021:    Output Parameter:
2022: .   flg - the logical flag

2024:    Level: intermediate

2026: .seealso: [](ch_vectors), `Vec`, `VecBindToCPU()`
2027: @*/
2028: PetscErrorCode VecBoundToCPU(Vec v, PetscBool *flg)
2029: {
2030:   PetscFunctionBegin;
2033: #if defined(PETSC_HAVE_DEVICE)
2034:   *flg = v->boundtocpu;
2035: #else
2036:   *flg = PETSC_TRUE;
2037: #endif
2038:   PetscFunctionReturn(PETSC_SUCCESS);
2039: }

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

2044:    Input Parameters:
2045: +  v - the vector
2046: -  flg - flag indicating whether the boundtocpu flag should be propagated

2048:    Level: developer

2050:    Notes:
2051:    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.
2052:    The created vectors will also have their bindingpropagates flag set to true.

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

2058: .seealso: [](ch_vectors), `Vec`, `MatSetBindingPropagates()`, `VecGetBindingPropagates()`
2059: @*/
2060: PetscErrorCode VecSetBindingPropagates(Vec v, PetscBool flg)
2061: {
2062:   PetscFunctionBegin;
2064: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2065:   v->bindingpropagates = flg;
2066: #endif
2067:   PetscFunctionReturn(PETSC_SUCCESS);
2068: }

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

2073:    Input Parameter:
2074: .  v - the vector

2076:    Output Parameter:
2077: .  flg - flag indicating whether the boundtocpu flag will be propagated

2079:    Level: developer

2081: .seealso: [](ch_vectors), `Vec`, `VecSetBindingPropagates()`
2082: @*/
2083: PetscErrorCode VecGetBindingPropagates(Vec v, PetscBool *flg)
2084: {
2085:   PetscFunctionBegin;
2088: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2089:   *flg = v->bindingpropagates;
2090: #else
2091:   *flg = PETSC_FALSE;
2092: #endif
2093:   PetscFunctionReturn(PETSC_SUCCESS);
2094: }

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

2099:   Logically Collective

2101:   Input Parameters:
2102: +  v    - the vector
2103: -  mbytes - minimum data size in bytes

2105:   Options Database Key:
2106: . -vec_pinned_memory_min <size> - minimum size (in bytes) for an allocation to use pinned memory on host.

2108:   Level: developer

2110:   Note:
2111:   Specifying -1 ensures that pinned memory will never be used.

2113: .seealso: [](ch_vectors), `Vec`, `VecGetPinnedMemoryMin()`
2114: @*/
2115: PetscErrorCode VecSetPinnedMemoryMin(Vec v, size_t mbytes)
2116: {
2117:   PetscFunctionBegin;
2119: #if PetscDefined(HAVE_DEVICE)
2120:   v->minimum_bytes_pinned_memory = mbytes;
2121: #endif
2122:   PetscFunctionReturn(PETSC_SUCCESS);
2123: }

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

2128:   Logically Collective

2130:   Input Parameter:
2131: .  v    - the vector

2133:   Output Parameter:
2134: .  mbytes - minimum data size in bytes

2136:   Level: developer

2138: .seealso: [](ch_vectors), `Vec`, `VecSetPinnedMemoryMin()`
2139: @*/
2140: PetscErrorCode VecGetPinnedMemoryMin(Vec v, size_t *mbytes)
2141: {
2142:   PetscFunctionBegin;
2145: #if PetscDefined(HAVE_DEVICE)
2146:   *mbytes = v->minimum_bytes_pinned_memory;
2147: #endif
2148:   PetscFunctionReturn(PETSC_SUCCESS);
2149: }

2151: /*@
2152:   VecGetOffloadMask - Get the offload mask of a `Vec`

2154:   Not Collective

2156:   Input Parameter:
2157: .   v - the vector

2159:   Output Parameter:
2160: .   mask - corresponding `PetscOffloadMask` enum value.

2162:    Level: intermediate

2164: .seealso: [](ch_vectors), `Vec`, `VecCreateSeqCUDA()`, `VecCreateSeqViennaCL()`, `VecGetArray()`, `VecGetType()`
2165: @*/
2166: PetscErrorCode VecGetOffloadMask(Vec v, PetscOffloadMask *mask)
2167: {
2168:   PetscFunctionBegin;
2171:   *mask = v->offloadmask;
2172:   PetscFunctionReturn(PETSC_SUCCESS);
2173: }

2175: #if !defined(PETSC_HAVE_VIENNACL)
2176: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLContext(Vec v, PETSC_UINTPTR_T *ctx)
2177: {
2178:   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_context");
2179: }

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

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

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

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

2201: PETSC_EXTERN PetscErrorCode VecViennaCLRestoreCLMemWrite(Vec v)
2202: {
2203:   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to restore a Vec's cl_mem");
2204: }
2205: #endif