xref: /petsc/src/vec/vec/interface/vector.c (revision a20f46d599fba65f6a90b21923b18d4339af9fb1)
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> /*I  "petscvec.h"   I*/
6 #include <petsc/private/deviceimpl.h>
7 
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;
19 
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
23 
24   Not Collective
25 
26   Input Parameter:
27 . vec - the vector
28 
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()`)
34 
35   Level: advanced
36 
37 .seealso: [](ch_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecStashSetInitialSize()`, `VecStashView()`
38 @*/
VecStashGetInfo(Vec vec,PetscInt * nstash,PetscInt * reallocs,PetscInt * bnstash,PetscInt * breallocs)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 }
46 
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.
51 
52   Logically Collective
53 
54   Input Parameters:
55 + x       - vector
56 - mapping - mapping created with `ISLocalToGlobalMappingCreate()` or `ISLocalToGlobalMappingCreateIS()`
57 
58   Level: intermediate
59 
60   Notes:
61   All vectors obtained with `VecDuplicate()` from this vector inherit the same mapping.
62 
63   Vectors obtained with `DMCreateGlobaVector()` will often have this attribute attached to the vector so this call is not needed
64 
65 .seealso: [](ch_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`, `VecSetValuesLocal()`,
66            `VecGetLocalToGlobalMapping()`, `VecSetValuesBlockedLocal()`
67 @*/
VecSetLocalToGlobalMapping(Vec x,ISLocalToGlobalMapping mapping)68 PetscErrorCode VecSetLocalToGlobalMapping(Vec x, ISLocalToGlobalMapping mapping)
69 {
70   PetscFunctionBegin;
71   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
72   if (mapping) PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 2);
73   if (x->ops->setlocaltoglobalmapping) PetscUseTypeMethod(x, setlocaltoglobalmapping, mapping);
74   else PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->map, mapping));
75   PetscFunctionReturn(PETSC_SUCCESS);
76 }
77 
78 /*@
79   VecGetLocalToGlobalMapping - Gets the local-to-global numbering set by `VecSetLocalToGlobalMapping()`
80 
81   Not Collective
82 
83   Input Parameter:
84 . X - the vector
85 
86   Output Parameter:
87 . mapping - the mapping
88 
89   Level: advanced
90 
91 .seealso: [](ch_vectors), `Vec`, `VecSetValuesLocal()`, `VecSetLocalToGlobalMapping()`
92 @*/
VecGetLocalToGlobalMapping(Vec X,ISLocalToGlobalMapping * mapping)93 PetscErrorCode VecGetLocalToGlobalMapping(Vec X, ISLocalToGlobalMapping *mapping)
94 {
95   PetscFunctionBegin;
96   PetscValidHeaderSpecific(X, VEC_CLASSID, 1);
97   PetscValidType(X, 1);
98   PetscAssertPointer(mapping, 2);
99   if (X->ops->getlocaltoglobalmapping) PetscUseTypeMethod(X, getlocaltoglobalmapping, mapping);
100   else *mapping = X->map->mapping;
101   PetscFunctionReturn(PETSC_SUCCESS);
102 }
103 
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()`.
107 
108   Collective
109 
110   Input Parameter:
111 . vec - the vector
112 
113   Level: beginner
114 
115 .seealso: [](ch_vectors), `Vec`, `VecAssemblyEnd()`, `VecSetValues()`
116 @*/
VecAssemblyBegin(Vec vec)117 PetscErrorCode VecAssemblyBegin(Vec vec)
118 {
119   PetscFunctionBegin;
120   PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
121   PetscValidType(vec, 1);
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 }
129 
130 /*@
131   VecAssemblyEnd - Completes assembling the vector.  This routine should be called after `VecAssemblyBegin()`.
132 
133   Collective
134 
135   Input Parameter:
136 . vec - the vector
137 
138   Options Database Keys:
139 + -vec_view                 - Prints vector in `PETSC_VIEWER_DEFAULT` format
140 . -vec_view ::ascii_matlab  - Prints vector in `PETSC_VIEWER_ASCII_MATLAB` format to stdout
141 . -vec_view matlab:filename - Prints vector in MATLAB .mat file to filename (requires PETSc configured with --with-matlab)
142 . -vec_view draw            - Activates vector viewing using drawing tools
143 . -display <name>           - Sets display name (default is host)
144 . -draw_pause <sec>         - Sets number of seconds to pause after display
145 - -vec_view socket          - Activates vector viewing using a socket
146 
147   Level: beginner
148 
149 .seealso: [](ch_vectors), `Vec`, `VecAssemblyBegin()`, `VecSetValues()`
150 @*/
VecAssemblyEnd(Vec vec)151 PetscErrorCode VecAssemblyEnd(Vec vec)
152 {
153   PetscFunctionBegin;
154   PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
155   PetscCall(PetscLogEventBegin(VEC_AssemblyEnd, vec, 0, 0, 0));
156   PetscValidType(vec, 1);
157   PetscTryTypeMethod(vec, assemblyend);
158   PetscCall(PetscLogEventEnd(VEC_AssemblyEnd, vec, 0, 0, 0));
159   PetscCall(VecViewFromOptions(vec, NULL, "-vec_view"));
160   PetscFunctionReturn(PETSC_SUCCESS);
161 }
162 
163 /*@
164   VecSetPreallocationCOO - set preallocation for a vector using a coordinate format of the entries with global indices
165 
166   Collective
167 
168   Input Parameters:
169 + x     - vector being preallocated
170 . ncoo  - number of entries
171 - coo_i - entry indices
172 
173   Level: beginner
174 
175   Notes:
176   This and `VecSetValuesCOO()` provide an alternative API to using `VecSetValues()` to provide vector values.
177 
178   This API is particularly efficient for use on GPUs.
179 
180   Entries can be repeated, see `VecSetValuesCOO()`. Negative indices are not allowed unless vector option `VEC_IGNORE_NEGATIVE_INDICES` is set,
181   in which case they, along with the corresponding entries in `VecSetValuesCOO()`, are ignored. If vector option `VEC_NO_OFF_PROC_ENTRIES` is set,
182   remote entries are ignored, otherwise, they will be properly added or inserted to the vector.
183 
184   The array coo_i[] may be freed immediately after calling this function.
185 
186 .seealso: [](ch_vectors), `Vec`, `VecSetValuesCOO()`, `VecSetPreallocationCOOLocal()`
187 @*/
VecSetPreallocationCOO(Vec x,PetscCount ncoo,const PetscInt coo_i[])188 PetscErrorCode VecSetPreallocationCOO(Vec x, PetscCount ncoo, const PetscInt coo_i[])
189 {
190   PetscFunctionBegin;
191   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
192   PetscValidType(x, 1);
193   if (ncoo) PetscAssertPointer(coo_i, 3);
194   PetscCall(PetscLogEventBegin(VEC_SetPreallocateCOO, x, 0, 0, 0));
195   PetscCall(PetscLayoutSetUp(x->map));
196   if (x->ops->setpreallocationcoo) {
197     PetscUseTypeMethod(x, setpreallocationcoo, ncoo, coo_i);
198   } else {
199     PetscInt ncoo_i;
200     IS       is_coo_i;
201 
202     PetscCall(PetscIntCast(ncoo, &ncoo_i));
203     PetscCall(ISCreateGeneral(PETSC_COMM_SELF, ncoo_i, coo_i, PETSC_COPY_VALUES, &is_coo_i));
204     PetscCall(PetscObjectCompose((PetscObject)x, "__PETSc_coo_i", (PetscObject)is_coo_i));
205     PetscCall(ISDestroy(&is_coo_i));
206   }
207   PetscCall(PetscLogEventEnd(VEC_SetPreallocateCOO, x, 0, 0, 0));
208   PetscFunctionReturn(PETSC_SUCCESS);
209 }
210 
211 /*@
212   VecSetPreallocationCOOLocal - set preallocation for vectors using a coordinate format of the entries with local indices
213 
214   Collective
215 
216   Input Parameters:
217 + x     - vector being preallocated
218 . ncoo  - number of entries
219 - coo_i - row indices (local numbering; may be modified)
220 
221   Level: beginner
222 
223   Notes:
224   This and `VecSetValuesCOO()` provide an alternative API to using `VecSetValuesLocal()` to provide vector values.
225 
226   This API is particularly efficient for use on GPUs.
227 
228   The local indices are translated using the local to global mapping, thus `VecSetLocalToGlobalMapping()` must have been
229   called prior to this function.
230 
231   The indices coo_i may be modified within this function. They might be translated to corresponding global
232   indices, but the caller should not rely on them having any specific value after this function returns. The arrays
233   can be freed or reused immediately after this function returns.
234 
235   Entries can be repeated. Negative indices and remote indices might be allowed. see `VecSetPreallocationCOO()`.
236 
237 .seealso: [](ch_vectors), `Vec`, `VecSetPreallocationCOO()`, `VecSetValuesCOO()`
238 @*/
VecSetPreallocationCOOLocal(Vec x,PetscCount ncoo,PetscInt coo_i[])239 PetscErrorCode VecSetPreallocationCOOLocal(Vec x, PetscCount ncoo, PetscInt coo_i[])
240 {
241   PetscInt               ncoo_i;
242   ISLocalToGlobalMapping ltog;
243 
244   PetscFunctionBegin;
245   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
246   PetscValidType(x, 1);
247   if (ncoo) PetscAssertPointer(coo_i, 3);
248   PetscCall(PetscIntCast(ncoo, &ncoo_i));
249   PetscCall(PetscLayoutSetUp(x->map));
250   PetscCall(VecGetLocalToGlobalMapping(x, &ltog));
251   if (ltog) PetscCall(ISLocalToGlobalMappingApply(ltog, ncoo_i, coo_i, coo_i));
252   PetscCall(VecSetPreallocationCOO(x, ncoo, coo_i));
253   PetscFunctionReturn(PETSC_SUCCESS);
254 }
255 
256 /*@
257   VecSetValuesCOO - set values at once in a vector preallocated using `VecSetPreallocationCOO()`
258 
259   Collective
260 
261   Input Parameters:
262 + x     - vector being set
263 . coo_v - the value array
264 - imode - the insert mode
265 
266   Level: beginner
267 
268   Note:
269   This and `VecSetPreallocationCOO() or ``VecSetPreallocationCOOLocal()` provide an alternative API to using `VecSetValues()` to provide vector values.
270 
271   This API is particularly efficient for use on GPUs.
272 
273   The values must follow the order of the indices prescribed with `VecSetPreallocationCOO()` or `VecSetPreallocationCOOLocal()`.
274   When repeated entries are specified in the COO indices the `coo_v` values are first properly summed, regardless of the value of `imode`.
275   The imode flag indicates if `coo_v` must be added to the current values of the vector (`ADD_VALUES`) or overwritten (`INSERT_VALUES`).
276   `VecAssemblyBegin()` and `VecAssemblyEnd()` do not need to be called after this routine. It automatically handles the assembly process.
277 
278 .seealso: [](ch_vectors), `Vec`, `VecSetPreallocationCOO()`, `VecSetPreallocationCOOLocal()`, `VecSetValues()`
279 @*/
VecSetValuesCOO(Vec x,const PetscScalar coo_v[],InsertMode imode)280 PetscErrorCode VecSetValuesCOO(Vec x, const PetscScalar coo_v[], InsertMode imode)
281 {
282   PetscFunctionBegin;
283   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
284   PetscValidType(x, 1);
285   PetscValidLogicalCollectiveEnum(x, imode, 3);
286   PetscCall(PetscLogEventBegin(VEC_SetValuesCOO, x, 0, 0, 0));
287   if (x->ops->setvaluescoo) {
288     PetscUseTypeMethod(x, setvaluescoo, coo_v, imode);
289     PetscCall(PetscObjectStateIncrease((PetscObject)x));
290   } else {
291     IS              is_coo_i;
292     const PetscInt *coo_i;
293     PetscInt        ncoo;
294     PetscMemType    mtype;
295 
296     PetscCall(PetscGetMemType(coo_v, &mtype));
297     PetscCheck(mtype == PETSC_MEMTYPE_HOST, PetscObjectComm((PetscObject)x), PETSC_ERR_ARG_WRONG, "The basic VecSetValuesCOO() only supports v[] on host");
298     PetscCall(PetscObjectQuery((PetscObject)x, "__PETSc_coo_i", (PetscObject *)&is_coo_i));
299     PetscCheck(is_coo_i, PetscObjectComm((PetscObject)x), PETSC_ERR_COR, "Missing coo_i IS");
300     PetscCall(ISGetLocalSize(is_coo_i, &ncoo));
301     PetscCall(ISGetIndices(is_coo_i, &coo_i));
302     if (imode != ADD_VALUES) PetscCall(VecZeroEntries(x));
303     PetscCall(VecSetValues(x, ncoo, coo_i, coo_v, ADD_VALUES));
304     PetscCall(ISRestoreIndices(is_coo_i, &coo_i));
305     PetscCall(VecAssemblyBegin(x));
306     PetscCall(VecAssemblyEnd(x));
307   }
308   PetscCall(PetscLogEventEnd(VEC_SetValuesCOO, x, 0, 0, 0));
309   PetscFunctionReturn(PETSC_SUCCESS);
310 }
311 
VecPointwiseApply_Private(Vec w,Vec x,Vec y,PetscDeviceContext dctx,PetscLogEvent event,const char async_name[],PetscErrorCode (* const pointwise_op)(Vec,Vec,Vec))312 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))
313 {
314   PetscErrorCode (*async_fn)(Vec, Vec, Vec, PetscDeviceContext) = NULL;
315 
316   PetscFunctionBegin;
317   PetscValidHeaderSpecific(w, VEC_CLASSID, 1);
318   PetscValidHeaderSpecific(x, VEC_CLASSID, 2);
319   PetscValidHeaderSpecific(y, VEC_CLASSID, 3);
320   PetscValidType(w, 1);
321   PetscValidType(x, 2);
322   PetscValidType(y, 3);
323   PetscCheckSameTypeAndComm(x, 2, y, 3);
324   PetscCheckSameTypeAndComm(y, 3, w, 1);
325   VecCheckSameSize(w, 1, x, 2);
326   VecCheckSameSize(w, 1, y, 3);
327   VecCheckAssembled(x);
328   VecCheckAssembled(y);
329   PetscCall(VecSetErrorIfLocked(w, 1));
330   PetscValidFunction(pointwise_op, 5);
331 
332   if (dctx) PetscCall(PetscObjectQueryFunction((PetscObject)w, async_name, &async_fn));
333   if (event) PetscCall(PetscLogEventBegin(event, x, y, w, 0));
334   if (async_fn) {
335     PetscCall((*async_fn)(w, x, y, dctx));
336   } else {
337     PetscCall((*pointwise_op)(w, x, y));
338   }
339   if (event) PetscCall(PetscLogEventEnd(event, x, y, w, 0));
340   PetscCall(PetscObjectStateIncrease((PetscObject)w));
341   PetscFunctionReturn(PETSC_SUCCESS);
342 }
343 
VecPointwiseMaxAsync_Private(Vec w,Vec x,Vec y,PetscDeviceContext dctx)344 PetscErrorCode VecPointwiseMaxAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
345 {
346   PetscFunctionBegin;
347   // REVIEW ME: no log event?
348   PetscCall(VecPointwiseApply_Private(w, x, y, dctx, 0, VecAsyncFnName(PointwiseMax), w->ops->pointwisemax));
349   PetscFunctionReturn(PETSC_SUCCESS);
350 }
351 
352 /*@
353   VecPointwiseMax - Computes the component-wise maximum `w[i] = max(x[i], y[i])`.
354 
355   Logically Collective
356 
357   Input Parameters:
358 + x - the first input vector
359 - y - the second input vector
360 
361   Output Parameter:
362 . w - the result
363 
364   Level: advanced
365 
366   Notes:
367   Any subset of the `x`, `y`, and `w` may be the same vector.
368 
369   For complex numbers compares only the real part
370 
371 .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
372 @*/
VecPointwiseMax(Vec w,Vec x,Vec y)373 PetscErrorCode VecPointwiseMax(Vec w, Vec x, Vec y)
374 {
375   PetscFunctionBegin;
376   PetscCall(VecPointwiseMaxAsync_Private(w, x, y, NULL));
377   PetscFunctionReturn(PETSC_SUCCESS);
378 }
379 
VecPointwiseMinAsync_Private(Vec w,Vec x,Vec y,PetscDeviceContext dctx)380 PetscErrorCode VecPointwiseMinAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
381 {
382   PetscFunctionBegin;
383   // REVIEW ME: no log event?
384   PetscCall(VecPointwiseApply_Private(w, x, y, dctx, 0, VecAsyncFnName(PointwiseMin), w->ops->pointwisemin));
385   PetscFunctionReturn(PETSC_SUCCESS);
386 }
387 
388 /*@
389   VecPointwiseMin - Computes the component-wise minimum `w[i] = min(x[i], y[i])`.
390 
391   Logically Collective
392 
393   Input Parameters:
394 + x - the first input vector
395 - y - the second input vector
396 
397   Output Parameter:
398 . w - the result
399 
400   Level: advanced
401 
402   Notes:
403   Any subset of the `x`, `y`, and `w` may be the same vector.
404 
405   For complex numbers compares only the real part
406 
407 .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
408 @*/
VecPointwiseMin(Vec w,Vec x,Vec y)409 PetscErrorCode VecPointwiseMin(Vec w, Vec x, Vec y)
410 {
411   PetscFunctionBegin;
412   PetscCall(VecPointwiseMinAsync_Private(w, x, y, NULL));
413   PetscFunctionReturn(PETSC_SUCCESS);
414 }
415 
VecPointwiseMaxAbsAsync_Private(Vec w,Vec x,Vec y,PetscDeviceContext dctx)416 PetscErrorCode VecPointwiseMaxAbsAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
417 {
418   PetscFunctionBegin;
419   // REVIEW ME: no log event?
420   PetscCall(VecPointwiseApply_Private(w, x, y, dctx, 0, VecAsyncFnName(PointwiseMaxAbs), w->ops->pointwisemaxabs));
421   PetscFunctionReturn(PETSC_SUCCESS);
422 }
423 
424 /*@
425   VecPointwiseMaxAbs - Computes the component-wise maximum of the absolute values `w[i] = max(abs(x[i]), abs(y[i]))`.
426 
427   Logically Collective
428 
429   Input Parameters:
430 + x - the first input vector
431 - y - the second input vector
432 
433   Output Parameter:
434 . w - the result
435 
436   Level: advanced
437 
438   Notes:
439   Any subset of the `x`, `y`, and `w` may be the same vector.
440 
441 .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMin()`, `VecPointwiseMax()`, `VecMaxPointwiseDivide()`
442 @*/
VecPointwiseMaxAbs(Vec w,Vec x,Vec y)443 PetscErrorCode VecPointwiseMaxAbs(Vec w, Vec x, Vec y)
444 {
445   PetscFunctionBegin;
446   PetscCall(VecPointwiseMaxAbsAsync_Private(w, x, y, NULL));
447   PetscFunctionReturn(PETSC_SUCCESS);
448 }
449 
VecPointwiseDivideAsync_Private(Vec w,Vec x,Vec y,PetscDeviceContext dctx)450 PetscErrorCode VecPointwiseDivideAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
451 {
452   PetscFunctionBegin;
453   PetscCall(VecPointwiseApply_Private(w, x, y, dctx, VEC_PointwiseDivide, VecAsyncFnName(PointwiseDivide), w->ops->pointwisedivide));
454   PetscFunctionReturn(PETSC_SUCCESS);
455 }
456 
457 /*@
458   VecPointwiseDivide - Computes the component-wise division `w[i] = x[i] / y[i]`.
459 
460   Logically Collective
461 
462   Input Parameters:
463 + x - the numerator vector
464 - y - the denominator vector
465 
466   Output Parameter:
467 . w - the result
468 
469   Level: advanced
470 
471   Note:
472   Any subset of the `x`, `y`, and `w` may be the same vector.
473 
474 .seealso: [](ch_vectors), `Vec`, `VecPointwiseMult()`, `VecPointwiseMax()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
475 @*/
VecPointwiseDivide(Vec w,Vec x,Vec y)476 PetscErrorCode VecPointwiseDivide(Vec w, Vec x, Vec y)
477 {
478   PetscFunctionBegin;
479   PetscCall(VecPointwiseDivideAsync_Private(w, x, y, NULL));
480   PetscFunctionReturn(PETSC_SUCCESS);
481 }
482 
VecPointwiseMultAsync_Private(Vec w,Vec x,Vec y,PetscDeviceContext dctx)483 PetscErrorCode VecPointwiseMultAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
484 {
485   PetscFunctionBegin;
486   PetscValidHeaderSpecific(w, VEC_CLASSID, 1);
487   PetscCall(VecPointwiseApply_Private(w, x, y, dctx, VEC_PointwiseMult, VecAsyncFnName(PointwiseMult), w->ops->pointwisemult));
488   PetscFunctionReturn(PETSC_SUCCESS);
489 }
490 
491 /*@
492   VecPointwiseMult - Computes the component-wise multiplication `w[i] = x[i] * y[i]`.
493 
494   Logically Collective
495 
496   Input Parameters:
497 + x - the first vector
498 - y - the second vector
499 
500   Output Parameter:
501 . w - the result
502 
503   Level: advanced
504 
505   Note:
506   Any subset of the `x`, `y`, and `w` may be the same vector.
507 
508 .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMax()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
509 @*/
VecPointwiseMult(Vec w,Vec x,Vec y)510 PetscErrorCode VecPointwiseMult(Vec w, Vec x, Vec y)
511 {
512   PetscFunctionBegin;
513   PetscCall(VecPointwiseMultAsync_Private(w, x, y, NULL));
514   PetscFunctionReturn(PETSC_SUCCESS);
515 }
516 
517 /*@
518   VecDuplicate - Creates a new vector of the same type as an existing vector.
519 
520   Collective
521 
522   Input Parameter:
523 . v - a vector to mimic
524 
525   Output Parameter:
526 . newv - location to put new vector
527 
528   Level: beginner
529 
530   Notes:
531   `VecDuplicate()` DOES NOT COPY the vector entries, but rather allocates storage
532   for the new vector.  Use `VecCopy()` to copy a vector.
533 
534   Use `VecDestroy()` to free the space. Use `VecDuplicateVecs()` to get several
535   vectors.
536 
537 .seealso: [](ch_vectors), `Vec`, `VecDestroy()`, `VecDuplicateVecs()`, `VecCreate()`, `VecCopy()`
538 @*/
VecDuplicate(Vec v,Vec * newv)539 PetscErrorCode VecDuplicate(Vec v, Vec *newv)
540 {
541   PetscFunctionBegin;
542   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
543   PetscAssertPointer(newv, 2);
544   PetscValidType(v, 1);
545   PetscUseTypeMethod(v, duplicate, newv);
546 #if PetscDefined(HAVE_DEVICE)
547   if (v->boundtocpu && v->bindingpropagates) {
548     PetscCall(VecSetBindingPropagates(*newv, PETSC_TRUE));
549     PetscCall(VecBindToCPU(*newv, PETSC_TRUE));
550   }
551 #endif
552   PetscCall(PetscObjectStateIncrease((PetscObject)*newv));
553   PetscFunctionReturn(PETSC_SUCCESS);
554 }
555 
556 /*@
557   VecDestroy - Destroys a vector.
558 
559   Collective
560 
561   Input Parameter:
562 . v - the vector
563 
564   Level: beginner
565 
566 .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecDuplicate()`, `VecDestroyVecs()`
567 @*/
VecDestroy(Vec * v)568 PetscErrorCode VecDestroy(Vec *v)
569 {
570   PetscFunctionBegin;
571   PetscAssertPointer(v, 1);
572   if (!*v) PetscFunctionReturn(PETSC_SUCCESS);
573   PetscValidHeaderSpecific(*v, VEC_CLASSID, 1);
574   if (--((PetscObject)*v)->refct > 0) {
575     *v = NULL;
576     PetscFunctionReturn(PETSC_SUCCESS);
577   }
578 
579   PetscCall(PetscObjectSAWsViewOff((PetscObject)*v));
580   /* destroy the internal part */
581   PetscTryTypeMethod(*v, destroy);
582   PetscCall(PetscFree((*v)->defaultrandtype));
583   /* destroy the external/common part */
584   PetscCall(PetscLayoutDestroy(&(*v)->map));
585   PetscCall(PetscHeaderDestroy(v));
586   PetscFunctionReturn(PETSC_SUCCESS);
587 }
588 
589 /*@C
590   VecDuplicateVecs - Creates several vectors of the same type as an existing vector.
591 
592   Collective
593 
594   Input Parameters:
595 + m - the number of vectors to obtain
596 - v - a vector to mimic
597 
598   Output Parameter:
599 . V - location to put pointer to array of vectors
600 
601   Level: intermediate
602 
603   Notes:
604   Use `VecDestroyVecs()` to free the space. Use `VecDuplicate()` to form a single
605   vector.
606 
607   Some implementations ensure that the arrays accessed by each vector are contiguous in memory. Certain `VecMDot()` and `VecMAXPY()`
608   implementations utilize this property to use BLAS 2 operations for higher efficiency. This is especially useful in `KSPGMRES`, see
609   `KSPGMRESSetPreAllocateVectors()`.
610 
611   Fortran Note:
612 .vb
613   Vec, pointer :: V(:)
614 .ve
615 
616 .seealso: [](ch_vectors), `Vec`, [](ch_fortran), `VecDestroyVecs()`, `VecDuplicate()`, `VecCreate()`, `VecMDot()`, `VecMAXPY()`, `KSPGMRES`,
617           `KSPGMRESSetPreAllocateVectors()`
618 @*/
VecDuplicateVecs(Vec v,PetscInt m,Vec * V[])619 PetscErrorCode VecDuplicateVecs(Vec v, PetscInt m, Vec *V[])
620 {
621   PetscFunctionBegin;
622   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
623   PetscAssertPointer(V, 3);
624   PetscValidType(v, 1);
625   PetscUseTypeMethod(v, duplicatevecs, m, V);
626 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
627   if (v->boundtocpu && v->bindingpropagates) {
628     PetscInt i;
629 
630     for (i = 0; i < m; i++) {
631       /* Since ops->duplicatevecs might itself propagate the value of boundtocpu,
632        * avoid unnecessary overhead by only calling VecBindToCPU() if the vector isn't already bound. */
633       if (!(*V)[i]->boundtocpu) {
634         PetscCall(VecSetBindingPropagates((*V)[i], PETSC_TRUE));
635         PetscCall(VecBindToCPU((*V)[i], PETSC_TRUE));
636       }
637     }
638   }
639 #endif
640   PetscFunctionReturn(PETSC_SUCCESS);
641 }
642 
643 /*@C
644   VecDestroyVecs - Frees a block of vectors obtained with `VecDuplicateVecs()`.
645 
646   Collective
647 
648   Input Parameters:
649 + m  - the number of vectors previously obtained, if zero no vectors are destroyed
650 - vv - pointer to pointer to array of vector pointers, if `NULL` no vectors are destroyed
651 
652   Level: intermediate
653 
654 .seealso: [](ch_vectors), `Vec`, [](ch_fortran), `VecDuplicateVecs()`, `VecDestroyVecsf90()`
655 @*/
VecDestroyVecs(PetscInt m,Vec * vv[])656 PetscErrorCode VecDestroyVecs(PetscInt m, Vec *vv[])
657 {
658   PetscFunctionBegin;
659   PetscAssertPointer(vv, 2);
660   PetscCheck(m >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Trying to destroy negative number of vectors %" PetscInt_FMT, m);
661   if (!m || !*vv) {
662     *vv = NULL;
663     PetscFunctionReturn(PETSC_SUCCESS);
664   }
665   PetscValidHeaderSpecific(**vv, VEC_CLASSID, 2);
666   PetscValidType(**vv, 2);
667   PetscCall((*(**vv)->ops->destroyvecs)(m, *vv));
668   *vv = NULL;
669   PetscFunctionReturn(PETSC_SUCCESS);
670 }
671 
672 /*@
673   VecViewFromOptions - View a vector based on values in the options database
674 
675   Collective
676 
677   Input Parameters:
678 + A    - the vector
679 . obj  - optional object that provides the options prefix for this viewing, use 'NULL' to use the prefix of `A`
680 - name - command line option
681 
682   Level: intermediate
683 
684   Note:
685   See `PetscObjectViewFromOptions()` to see the `PetscViewer` and PetscViewerFormat` available
686 
687 .seealso: [](ch_vectors), `Vec`, `VecView`, `PetscObjectViewFromOptions()`, `VecCreate()`
688 @*/
VecViewFromOptions(Vec A,PeOp PetscObject obj,const char name[])689 PetscErrorCode VecViewFromOptions(Vec A, PeOp PetscObject obj, const char name[])
690 {
691   PetscFunctionBegin;
692   PetscValidHeaderSpecific(A, VEC_CLASSID, 1);
693   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
694   PetscFunctionReturn(PETSC_SUCCESS);
695 }
696 
697 /*@
698   VecView - Views a vector object.
699 
700   Collective
701 
702   Input Parameters:
703 + vec    - the vector
704 - viewer - an optional `PetscViewer` visualization context
705 
706   Level: beginner
707 
708   Notes:
709   The available visualization contexts include
710 +     `PETSC_VIEWER_STDOUT_SELF` - for sequential vectors
711 .     `PETSC_VIEWER_STDOUT_WORLD` - for parallel vectors created on `PETSC_COMM_WORLD`
712 -     `PETSC_VIEWER_STDOUT`_(comm) - for parallel vectors created on MPI communicator comm
713 
714   You can change the format the vector is printed using the
715   option `PetscViewerPushFormat()`.
716 
717   The user can open alternative viewers with
718 +    `PetscViewerASCIIOpen()` - Outputs vector to a specified file
719 .    `PetscViewerBinaryOpen()` - Outputs vector in binary to a
720   specified file; corresponding input uses `VecLoad()`
721 .    `PetscViewerDrawOpen()` - Outputs vector to an X window display
722 .    `PetscViewerSocketOpen()` - Outputs vector to Socket viewer
723 -    `PetscViewerHDF5Open()` - Outputs vector to HDF5 file viewer
724 
725   The user can call `PetscViewerPushFormat()` to specify the output
726   format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`,
727   `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`).  Available formats include
728 +    `PETSC_VIEWER_DEFAULT` - default, prints vector contents
729 .    `PETSC_VIEWER_ASCII_MATLAB` - prints vector contents in MATLAB format
730 .    `PETSC_VIEWER_ASCII_INDEX` - prints vector contents, including indices of vector elements
731 -    `PETSC_VIEWER_ASCII_COMMON` - prints vector contents, using a
732   format common among all vector types
733 
734   You can pass any number of vector objects, or other PETSc objects to the same viewer.
735 
736   In the debugger you can do call `VecView`(v,0) to display the vector. (The same holds for any PETSc object viewer).
737 
738   Notes for binary viewer:
739   If you pass multiple vectors to a binary viewer you can read them back in the same order
740   with `VecLoad()`.
741 
742   If the blocksize of the vector is greater than one then you must provide a unique prefix to
743   the vector with `PetscObjectSetOptionsPrefix`((`PetscObject`)vec,"uniqueprefix"); BEFORE calling `VecView()` on the
744   vector to be stored and then set that same unique prefix on the vector that you pass to `VecLoad()`. The blocksize
745   information is stored in an ASCII file with the same name as the binary file plus a ".info" appended to the
746   filename. If you copy the binary file, make sure you copy the associated .info file with it.
747 
748   See the manual page for `VecLoad()` on the exact format the binary viewer stores
749   the values in the file.
750 
751   Notes for HDF5 Viewer:
752   The name of the `Vec` (given with `PetscObjectSetName()` is the name that is used
753   for the object in the HDF5 file. If you wish to store the same Vec into multiple
754   datasets in the same file (typically with different values), you must change its
755   name each time before calling the `VecView()`. To load the same vector,
756   the name of the Vec object passed to `VecLoad()` must be the same.
757 
758   If the block size of the vector is greater than 1 then it is used as the first dimension in the HDF5 array.
759   If the function `PetscViewerHDF5SetBaseDimension2()`is called then even if the block size is one it will
760   be used as the first dimension in the HDF5 array (that is the HDF5 array will always be two dimensional)
761   See also `PetscViewerHDF5SetTimestep()` which adds an additional complication to reading and writing `Vec`
762   with the HDF5 viewer.
763 
764 .seealso: [](ch_vectors), `Vec`, `VecViewFromOptions()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscDrawLGCreate()`,
765           `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `VecLoad()`, `PetscViewerCreate()`,
766           `PetscRealView()`, `PetscScalarView()`, `PetscIntView()`, `PetscViewerHDF5SetTimestep()`
767 @*/
VecView(Vec vec,PetscViewer viewer)768 PetscErrorCode VecView(Vec vec, PetscViewer viewer)
769 {
770   PetscBool         isascii;
771   PetscViewerFormat format;
772   PetscMPIInt       size;
773 
774   PetscFunctionBegin;
775   PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
776   PetscValidType(vec, 1);
777   VecCheckAssembled(vec);
778   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec), &viewer));
779   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
780   PetscCall(PetscViewerGetFormat(viewer, &format));
781   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size));
782   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(PETSC_SUCCESS);
783 
784   PetscCheck(!vec->stash.n && !vec->bstash.n, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call VecAssemblyBegin/End() before viewing this vector");
785 
786   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
787   if (isascii) {
788     PetscInt rows, bs;
789 
790     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)vec, viewer));
791     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
792       PetscCall(PetscViewerASCIIPushTab(viewer));
793       PetscCall(VecGetSize(vec, &rows));
794       PetscCall(VecGetBlockSize(vec, &bs));
795       if (bs != 1) {
796         PetscCall(PetscViewerASCIIPrintf(viewer, "length=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n", rows, bs));
797       } else {
798         PetscCall(PetscViewerASCIIPrintf(viewer, "length=%" PetscInt_FMT "\n", rows));
799       }
800       PetscCall(PetscViewerASCIIPopTab(viewer));
801     }
802   }
803   PetscCall(VecLockReadPush(vec));
804   PetscCall(PetscLogEventBegin(VEC_View, vec, viewer, 0, 0));
805   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && vec->ops->viewnative) {
806     PetscUseTypeMethod(vec, viewnative, viewer);
807   } else {
808     PetscUseTypeMethod(vec, view, viewer);
809   }
810   PetscCall(VecLockReadPop(vec));
811   PetscCall(PetscLogEventEnd(VEC_View, vec, viewer, 0, 0));
812   PetscFunctionReturn(PETSC_SUCCESS);
813 }
814 
815 #if defined(PETSC_USE_DEBUG)
816   #include <../src/sys/totalview/tv_data_display.h>
TV_display_type(const struct _p_Vec * v)817 PETSC_UNUSED static int TV_display_type(const struct _p_Vec *v)
818 {
819   const PetscScalar *values;
820   char               type[32];
821 
822   TV_add_row("Local rows", "int", &v->map->n);
823   TV_add_row("Global rows", "int", &v->map->N);
824   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)v)->type_name);
825   PetscCall(VecGetArrayRead((Vec)v, &values));
826   PetscCall(PetscSNPrintf(type, 32, "double[%" PetscInt_FMT "]", v->map->n));
827   TV_add_row("values", type, values);
828   PetscCall(VecRestoreArrayRead((Vec)v, &values));
829   return TV_format_OK;
830 }
831 #endif
832 
833 /*@C
834   VecViewNative - Views a vector object with the original type specific viewer
835 
836   Collective
837 
838   Input Parameters:
839 + vec    - the vector
840 - viewer - an optional `PetscViewer` visualization context
841 
842   Level: developer
843 
844   Note:
845   This can be used with, for example, vectors obtained with `DMCreateGlobalVector()` for a `DMDA` to display the vector
846   in the PETSc storage format (each MPI process values follow the previous MPI processes) instead of the "natural" grid
847   ordering.
848 
849 .seealso: [](ch_vectors), `Vec`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscDrawLGCreate()`, `VecView()`
850           `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `VecLoad()`, `PetscViewerCreate()`,
851           `PetscRealView()`, `PetscScalarView()`, `PetscIntView()`, `PetscViewerHDF5SetTimestep()`
852 @*/
VecViewNative(Vec vec,PetscViewer viewer)853 PetscErrorCode VecViewNative(Vec vec, PetscViewer viewer)
854 {
855   PetscFunctionBegin;
856   PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
857   PetscValidType(vec, 1);
858   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec), &viewer));
859   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
860   PetscUseTypeMethod(vec, viewnative, viewer);
861   PetscFunctionReturn(PETSC_SUCCESS);
862 }
863 
864 /*@
865   VecGetSize - Returns the global number of elements of the vector.
866 
867   Not Collective
868 
869   Input Parameter:
870 . x - the vector
871 
872   Output Parameter:
873 . size - the global length of the vector
874 
875   Level: beginner
876 
877 .seealso: [](ch_vectors), `Vec`, `VecGetLocalSize()`
878 @*/
VecGetSize(Vec x,PetscInt * size)879 PetscErrorCode VecGetSize(Vec x, PetscInt *size)
880 {
881   PetscFunctionBegin;
882   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
883   PetscAssertPointer(size, 2);
884   PetscValidType(x, 1);
885   PetscUseTypeMethod(x, getsize, size);
886   PetscFunctionReturn(PETSC_SUCCESS);
887 }
888 
889 /*@
890   VecGetLocalSize - Returns the number of elements of the vector stored
891   in local memory (that is on this MPI process)
892 
893   Not Collective
894 
895   Input Parameter:
896 . x - the vector
897 
898   Output Parameter:
899 . size - the length of the local piece of the vector
900 
901   Level: beginner
902 
903 .seealso: [](ch_vectors), `Vec`, `VecGetSize()`
904 @*/
VecGetLocalSize(Vec x,PetscInt * size)905 PetscErrorCode VecGetLocalSize(Vec x, PetscInt *size)
906 {
907   PetscFunctionBegin;
908   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
909   PetscAssertPointer(size, 2);
910   PetscValidType(x, 1);
911   PetscUseTypeMethod(x, getlocalsize, size);
912   PetscFunctionReturn(PETSC_SUCCESS);
913 }
914 
915 /*@
916   VecGetOwnershipRange - Returns the range of indices owned by
917   this process. The vector is laid out with the
918   first `n1` elements on the first processor, next `n2` elements on the
919   second, etc.  For certain parallel layouts this range may not be
920   well defined.
921 
922   Not Collective
923 
924   Input Parameter:
925 . x - the vector
926 
927   Output Parameters:
928 + low  - the first local element, pass in `NULL` if not interested
929 - high - one more than the last local element, pass in `NULL` if not interested
930 
931   Level: beginner
932 
933   Notes:
934   If the `Vec` was obtained from a `DM` with `DMCreateGlobalVector()`, then the range values are determined by the specific `DM`.
935 
936   If the `Vec` was created directly the range values are determined by the local size passed to `VecSetSizes()` or `VecCreateMPI()`.
937   If `PETSC_DECIDE` was passed as the local size, then the vector uses default values for the range using `PetscSplitOwnership()`.
938 
939   The high argument is one more than the last element stored locally.
940 
941   For certain `DM`, such as `DMDA`, it is better to use `DM` specific routines, such as `DMDAGetGhostCorners()`, to determine
942   the local values in the vector.
943 
944 .seealso: [](ch_vectors), `Vec`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `VecGetOwnershipRanges()`, `PetscSplitOwnership()`,
945           `VecSetSizes()`, `VecCreateMPI()`, `PetscLayout`, `DMDAGetGhostCorners()`, `DM`
946 @*/
VecGetOwnershipRange(Vec x,PetscInt * low,PetscInt * high)947 PetscErrorCode VecGetOwnershipRange(Vec x, PetscInt *low, PetscInt *high)
948 {
949   PetscFunctionBegin;
950   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
951   PetscValidType(x, 1);
952   if (low) PetscAssertPointer(low, 2);
953   if (high) PetscAssertPointer(high, 3);
954   if (low) *low = x->map->rstart;
955   if (high) *high = x->map->rend;
956   PetscFunctionReturn(PETSC_SUCCESS);
957 }
958 
959 /*@C
960   VecGetOwnershipRanges - Returns the range of indices owned by EACH processor,
961   The vector is laid out with the
962   first `n1` elements on the first processor, next `n2` elements on the
963   second, etc.  For certain parallel layouts this range may not be
964   well defined.
965 
966   Not Collective
967 
968   Input Parameter:
969 . x - the vector
970 
971   Output Parameter:
972 . ranges - array of length `size` + 1 with the start and end+1 for each process
973 
974   Level: beginner
975 
976   Notes:
977   If the `Vec` was obtained from a `DM` with `DMCreateGlobalVector()`, then the range values are determined by the specific `DM`.
978 
979   If the `Vec` was created directly the range values are determined by the local size passed to `VecSetSizes()` or `VecCreateMPI()`.
980   If `PETSC_DECIDE` was passed as the local size, then the vector uses default values for the range using `PetscSplitOwnership()`.
981 
982   The high argument is one more than the last element stored locally.
983 
984   For certain `DM`, such as `DMDA`, it is better to use `DM` specific routines, such as `DMDAGetGhostCorners()`, to determine
985   the local values in the vector.
986 
987   The high argument is one more than the last element stored locally.
988 
989   If `ranges` are used after all vectors that share the ranges has been destroyed, then the program will crash accessing `ranges`.
990 
991   Fortran Note:
992   The argument `ranges` must be declared as
993 .vb
994   PetscInt, pointer :: ranges(:)
995 .ve
996   and you have to return it with a call to `VecRestoreOwnershipRanges()` when no longer needed
997 
998 .seealso: [](ch_vectors), `Vec`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `VecGetOwnershipRange()`, `PetscSplitOwnership()`,
999           `VecSetSizes()`, `VecCreateMPI()`, `PetscLayout`, `DMDAGetGhostCorners()`, `DM`
1000 @*/
VecGetOwnershipRanges(Vec x,const PetscInt * ranges[])1001 PetscErrorCode VecGetOwnershipRanges(Vec x, const PetscInt *ranges[])
1002 {
1003   PetscFunctionBegin;
1004   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
1005   PetscValidType(x, 1);
1006   PetscCall(PetscLayoutGetRanges(x->map, ranges));
1007   PetscFunctionReturn(PETSC_SUCCESS);
1008 }
1009 
1010 // PetscClangLinter pragma disable: -fdoc-section-header-unknown
1011 /*@
1012   VecSetOption - Sets an option for controlling a vector's behavior.
1013 
1014   Collective
1015 
1016   Input Parameters:
1017 + x    - the vector
1018 . op   - the option
1019 - flag - turn the option on or off
1020 
1021   Supported Options:
1022 + `VEC_IGNORE_OFF_PROC_ENTRIES` - which causes `VecSetValues()` to ignore
1023           entries destined to be stored on a separate processor. This can be used
1024           to eliminate the global reduction in the `VecAssemblyBegin()` if you know
1025           that you have only used `VecSetValues()` to set local elements
1026 . `VEC_IGNORE_NEGATIVE_INDICES` - which means you can pass negative indices
1027           in ix in calls to `VecSetValues()` or `VecGetValues()`. These rows are simply
1028           ignored.
1029 - `VEC_SUBSET_OFF_PROC_ENTRIES` - which causes `VecAssemblyBegin()` to assume that the off-process
1030           entries will always be a subset (possibly equal) of the off-process entries set on the
1031           first assembly which had a true `VEC_SUBSET_OFF_PROC_ENTRIES` and the vector has not
1032           changed this flag afterwards. If this assembly is not such first assembly, then this
1033           assembly can reuse the communication pattern setup in that first assembly, thus avoiding
1034           a global reduction. Subsequent assemblies setting off-process values should use the same
1035           InsertMode as the first assembly.
1036 
1037   Level: intermediate
1038 
1039   Developer Notes:
1040   The `InsertMode` restriction could be removed by packing the stash messages out of place.
1041 
1042 .seealso: [](ch_vectors), `Vec`, `VecSetValues()`
1043 @*/
VecSetOption(Vec x,VecOption op,PetscBool flag)1044 PetscErrorCode VecSetOption(Vec x, VecOption op, PetscBool flag)
1045 {
1046   PetscFunctionBegin;
1047   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
1048   PetscValidType(x, 1);
1049   PetscTryTypeMethod(x, setoption, op, flag);
1050   PetscFunctionReturn(PETSC_SUCCESS);
1051 }
1052 
1053 /* Default routines for obtaining and releasing; */
1054 /* may be used by any implementation */
VecDuplicateVecs_Default(Vec w,PetscInt m,Vec * V[])1055 PetscErrorCode VecDuplicateVecs_Default(Vec w, PetscInt m, Vec *V[])
1056 {
1057   PetscFunctionBegin;
1058   PetscCheck(m > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "m must be > 0: m = %" PetscInt_FMT, m);
1059   PetscCall(PetscMalloc1(m, V));
1060   for (PetscInt i = 0; i < m; i++) PetscCall(VecDuplicate(w, *V + i));
1061   PetscFunctionReturn(PETSC_SUCCESS);
1062 }
1063 
VecDestroyVecs_Default(PetscInt m,Vec v[])1064 PetscErrorCode VecDestroyVecs_Default(PetscInt m, Vec v[])
1065 {
1066   PetscInt i;
1067 
1068   PetscFunctionBegin;
1069   PetscAssertPointer(v, 2);
1070   for (i = 0; i < m; i++) PetscCall(VecDestroy(&v[i]));
1071   PetscCall(PetscFree(v));
1072   PetscFunctionReturn(PETSC_SUCCESS);
1073 }
1074 
1075 /*@
1076   VecResetArray - Resets a vector to use its default memory. Call this
1077   after the use of `VecPlaceArray()`.
1078 
1079   Not Collective
1080 
1081   Input Parameter:
1082 . vec - the vector
1083 
1084   Level: developer
1085 
1086 .seealso: [](ch_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecPlaceArray()`
1087 @*/
VecResetArray(Vec vec)1088 PetscErrorCode VecResetArray(Vec vec)
1089 {
1090   PetscFunctionBegin;
1091   PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
1092   PetscValidType(vec, 1);
1093   PetscUseTypeMethod(vec, resetarray);
1094   PetscCall(PetscObjectStateIncrease((PetscObject)vec));
1095   PetscFunctionReturn(PETSC_SUCCESS);
1096 }
1097 
1098 /*@
1099   VecLoad - Loads a vector that has been stored in binary or HDF5 format
1100   with `VecView()`.
1101 
1102   Collective
1103 
1104   Input Parameters:
1105 + vec    - the newly loaded vector, this needs to have been created with `VecCreate()` or
1106            some related function before the call to `VecLoad()`.
1107 - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` or
1108            HDF5 file viewer, obtained from `PetscViewerHDF5Open()`
1109 
1110   Level: intermediate
1111 
1112   Notes:
1113   Defaults to the standard `VECSEQ` or `VECMPI`, if you want some other type of `Vec` call `VecSetFromOptions()`
1114   before calling this.
1115 
1116   The input file must contain the full global vector, as
1117   written by the routine `VecView()`.
1118 
1119   If the type or size of `vec` is not set before a call to `VecLoad()`, PETSc
1120   sets the type and the local and global sizes based on the vector it is reading in. If type and/or
1121   sizes are already set, then the same are used.
1122 
1123   If using the binary viewer and the blocksize of the vector is greater than one then you must provide a unique prefix to
1124   the vector with `PetscObjectSetOptionsPrefix`((`PetscObject`)vec,"uniqueprefix"); BEFORE calling `VecView()` on the
1125   vector to be stored and then set that same unique prefix on the vector that you pass to VecLoad(). The blocksize
1126   information is stored in an ASCII file with the same name as the binary file plus a ".info" appended to the
1127   filename. If you copy the binary file, make sure you copy the associated .info file with it.
1128 
1129   If using HDF5, you must assign the `Vec` the same name as was used in the Vec
1130   that was stored in the file using `PetscObjectSetName()`. Otherwise you will
1131   get the error message: "Cannot H5DOpen2() with `Vec` name NAMEOFOBJECT".
1132 
1133   If the HDF5 file contains a two dimensional array the first dimension is treated as the block size
1134   in loading the vector. Hence, for example, using MATLAB notation h5create('vector.dat','/Test_Vec',[27 1]);
1135   will load a vector of size 27 and block size 27 thus resulting in all 27 entries being on the first process of
1136   vectors communicator and the rest of the processes having zero entries
1137 
1138   Notes for advanced users when using the binary viewer:
1139   Most users should not need to know the details of the binary storage
1140   format, since `VecLoad()` and `VecView()` completely hide these details.
1141   But for anyone who's interested, the standard binary vector storage
1142   format is
1143 .vb
1144      PetscInt    VEC_FILE_CLASSID
1145      PetscInt    number of rows
1146      PetscScalar *values of all entries
1147 .ve
1148 
1149   In addition, PETSc automatically uses byte swapping to work on all machines; the files
1150   are written ALWAYS using big-endian ordering. On small-endian machines the numbers
1151   are converted to the small-endian format when they are read in from the file.
1152   See PetscBinaryRead() and PetscBinaryWrite() to see how this may be done.
1153 
1154 .seealso: [](ch_vectors), `Vec`, `PetscViewerBinaryOpen()`, `VecView()`, `MatLoad()`
1155 @*/
VecLoad(Vec vec,PetscViewer viewer)1156 PetscErrorCode VecLoad(Vec vec, PetscViewer viewer)
1157 {
1158   PetscViewerFormat format;
1159 
1160   PetscFunctionBegin;
1161   PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
1162   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1163   PetscCheckSameComm(vec, 1, viewer, 2);
1164 
1165   PetscCall(VecSetErrorIfLocked(vec, 1));
1166   if (!((PetscObject)vec)->type_name && !vec->ops->create) PetscCall(VecSetType(vec, VECSTANDARD));
1167   PetscCall(PetscLogEventBegin(VEC_Load, viewer, 0, 0, 0));
1168   PetscCall(PetscViewerGetFormat(viewer, &format));
1169   if (format == PETSC_VIEWER_NATIVE && vec->ops->loadnative) {
1170     PetscUseTypeMethod(vec, loadnative, viewer);
1171   } else {
1172     PetscUseTypeMethod(vec, load, viewer);
1173   }
1174   PetscCall(PetscLogEventEnd(VEC_Load, viewer, 0, 0, 0));
1175   PetscFunctionReturn(PETSC_SUCCESS);
1176 }
1177 
1178 /*@
1179   VecReciprocal - Replaces each component of a vector by its reciprocal.
1180 
1181   Logically Collective
1182 
1183   Input Parameter:
1184 . vec - the vector
1185 
1186   Output Parameter:
1187 . vec - the vector reciprocal
1188 
1189   Level: intermediate
1190 
1191   Note:
1192   Vector entries with value 0.0 are not changed
1193 
1194 .seealso: [](ch_vectors), `Vec`, `VecLog()`, `VecExp()`, `VecSqrtAbs()`
1195 @*/
VecReciprocal(Vec vec)1196 PetscErrorCode VecReciprocal(Vec vec)
1197 {
1198   PetscFunctionBegin;
1199   PetscCall(VecReciprocalAsync_Private(vec, NULL));
1200   PetscFunctionReturn(PETSC_SUCCESS);
1201 }
1202 
1203 /*@C
1204   VecSetOperation - Allows the user to override a particular vector operation.
1205 
1206   Logically Collective; No Fortran Support
1207 
1208   Input Parameters:
1209 + vec - The vector to modify
1210 . op  - The name of the operation
1211 - f   - The function that provides the operation.
1212 
1213   Level: advanced
1214 
1215   Example Usage:
1216 .vb
1217   // some new VecView() implementation, must have the same signature as the function it seeks
1218   // to replace
1219   PetscErrorCode UserVecView(Vec x, PetscViewer viewer)
1220   {
1221     PetscFunctionBeginUser;
1222     // ...
1223     PetscFunctionReturn(PETSC_SUCCESS);
1224   }
1225 
1226   // Create a VECMPI which has a pre-defined VecView() implementation
1227   VecCreateMPI(comm, n, N, &x);
1228   // Calls the VECMPI implementation for VecView()
1229   VecView(x, viewer);
1230 
1231   VecSetOperation(x, VECOP_VIEW, (PetscErrorCodeFn *)UserVecView);
1232   // Now calls UserVecView()
1233   VecView(x, viewer);
1234 .ve
1235 
1236   Notes:
1237   `f` may be `NULL` to remove the operation from `vec`. Depending on the operation this may be
1238   allowed, however some always expect a valid function. In these cases an error will be raised
1239   when calling the interface routine in question.
1240 
1241   See `VecOperation` for an up-to-date list of override-able operations. The operations listed
1242   there have the form `VECOP_<OPERATION>`, where `<OPERATION>` is the suffix (in all capital
1243   letters) of the public interface routine (e.g., `VecView()` -> `VECOP_VIEW`).
1244 
1245   Overriding a particular `Vec`'s operation has no affect on any other `Vec`s past, present,
1246   or future. The user should also note that overriding a method is "destructive"; the previous
1247   method is not retained in any way.
1248 
1249   Each function MUST return `PETSC_SUCCESS` on success and
1250   nonzero on failure.
1251 
1252 .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecGetOperation()`, `MatSetOperation()`, `MatShellSetOperation()`
1253 @*/
VecSetOperation(Vec vec,VecOperation op,PetscErrorCodeFn * f)1254 PetscErrorCode VecSetOperation(Vec vec, VecOperation op, PetscErrorCodeFn *f)
1255 {
1256   PetscFunctionBegin;
1257   PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
1258   if (op == VECOP_VIEW && !vec->ops->viewnative) {
1259     vec->ops->viewnative = vec->ops->view;
1260   } else if (op == VECOP_LOAD && !vec->ops->loadnative) {
1261     vec->ops->loadnative = vec->ops->load;
1262   }
1263   ((PetscErrorCodeFn **)vec->ops)[(int)op] = f;
1264   PetscFunctionReturn(PETSC_SUCCESS);
1265 }
1266 
1267 /*@
1268   VecStashSetInitialSize - sets the sizes of the vec-stash, that is
1269   used during the assembly process to store values that belong to
1270   other processors.
1271 
1272   Not Collective, different processes can have different size stashes
1273 
1274   Input Parameters:
1275 + vec   - the vector
1276 . size  - the initial size of the stash.
1277 - bsize - the initial size of the block-stash(if used).
1278 
1279   Options Database Keys:
1280 + -vecstash_initial_size <size> or <size0,size1,...sizep-1>           - set initial size
1281 - -vecstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> - set initial block size
1282 
1283   Level: intermediate
1284 
1285   Notes:
1286   The block-stash is used for values set with `VecSetValuesBlocked()` while
1287   the stash is used for values set with `VecSetValues()`
1288 
1289   Run with the option -info and look for output of the form
1290   VecAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
1291   to determine the appropriate value, MM, to use for size and
1292   VecAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
1293   to determine the value, BMM to use for bsize
1294 
1295   PETSc attempts to smartly manage the stash size so there is little likelihood setting a
1296   a specific value here will affect performance
1297 
1298 .seealso: [](ch_vectors), `Vec`, `VecSetBlockSize()`, `VecSetValues()`, `VecSetValuesBlocked()`, `VecStashView()`
1299 @*/
VecStashSetInitialSize(Vec vec,PetscInt size,PetscInt bsize)1300 PetscErrorCode VecStashSetInitialSize(Vec vec, PetscInt size, PetscInt bsize)
1301 {
1302   PetscFunctionBegin;
1303   PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
1304   PetscCall(VecStashSetInitialSize_Private(&vec->stash, size));
1305   PetscCall(VecStashSetInitialSize_Private(&vec->bstash, bsize));
1306   PetscFunctionReturn(PETSC_SUCCESS);
1307 }
1308 
1309 /*@
1310   VecSetRandom - Sets all components of a vector to random numbers.
1311 
1312   Logically Collective
1313 
1314   Input Parameters:
1315 + x    - the vector
1316 - rctx - the random number context, formed by `PetscRandomCreate()`, or use `NULL` and it will create one internally.
1317 
1318   Output Parameter:
1319 . x - the vector
1320 
1321   Example of Usage:
1322 .vb
1323      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
1324      VecSetRandom(x,rctx);
1325      PetscRandomDestroy(&rctx);
1326 .ve
1327 
1328   Level: intermediate
1329 
1330 .seealso: [](ch_vectors), `Vec`, `VecSet()`, `VecSetValues()`, `PetscRandomCreate()`, `PetscRandomDestroy()`
1331 @*/
VecSetRandom(Vec x,PetscRandom rctx)1332 PetscErrorCode VecSetRandom(Vec x, PetscRandom rctx)
1333 {
1334   PetscRandom randObj = NULL;
1335 
1336   PetscFunctionBegin;
1337   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
1338   if (rctx) PetscValidHeaderSpecific(rctx, PETSC_RANDOM_CLASSID, 2);
1339   PetscValidType(x, 1);
1340   VecCheckAssembled(x);
1341   PetscCall(VecSetErrorIfLocked(x, 1));
1342 
1343   if (!rctx) {
1344     PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject)x), &randObj));
1345     PetscCall(PetscRandomSetType(randObj, x->defaultrandtype));
1346     PetscCall(PetscRandomSetFromOptions(randObj));
1347     rctx = randObj;
1348   }
1349 
1350   PetscCall(PetscLogEventBegin(VEC_SetRandom, x, rctx, 0, 0));
1351   PetscUseTypeMethod(x, setrandom, rctx);
1352   PetscCall(PetscLogEventEnd(VEC_SetRandom, x, rctx, 0, 0));
1353 
1354   PetscCall(PetscRandomDestroy(&randObj));
1355   PetscCall(PetscObjectStateIncrease((PetscObject)x));
1356   PetscFunctionReturn(PETSC_SUCCESS);
1357 }
1358 
1359 /*@
1360   VecZeroEntries - puts a `0.0` in each element of a vector
1361 
1362   Logically Collective
1363 
1364   Input Parameter:
1365 . vec - The vector
1366 
1367   Level: beginner
1368 
1369   Note:
1370   If the norm of the vector is known to be zero then this skips the unneeded zeroing process
1371 
1372 .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecSetOptionsPrefix()`, `VecSet()`, `VecSetValues()`
1373 @*/
VecZeroEntries(Vec vec)1374 PetscErrorCode VecZeroEntries(Vec vec)
1375 {
1376   PetscFunctionBegin;
1377   PetscCall(VecSet(vec, 0));
1378   PetscFunctionReturn(PETSC_SUCCESS);
1379 }
1380 
1381 /*
1382   VecSetTypeFromOptions_Private - Sets the type of vector from user options. Defaults to a PETSc sequential vector on one
1383   processor and a PETSc MPI vector on more than one processor.
1384 
1385   Collective
1386 
1387   Input Parameter:
1388 . vec - The vector
1389 
1390   Level: intermediate
1391 
1392 .seealso: [](ch_vectors), `Vec`, `VecSetFromOptions()`, `VecSetType()`
1393 */
VecSetTypeFromOptions_Private(Vec vec,PetscOptionItems PetscOptionsObject)1394 static PetscErrorCode VecSetTypeFromOptions_Private(Vec vec, PetscOptionItems PetscOptionsObject)
1395 {
1396   PetscBool   opt;
1397   VecType     defaultType;
1398   char        typeName[256];
1399   PetscMPIInt size;
1400 
1401   PetscFunctionBegin;
1402   if (((PetscObject)vec)->type_name) defaultType = ((PetscObject)vec)->type_name;
1403   else {
1404     PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size));
1405     if (size > 1) defaultType = VECMPI;
1406     else defaultType = VECSEQ;
1407   }
1408 
1409   PetscCall(VecRegisterAll());
1410   PetscCall(PetscOptionsFList("-vec_type", "Vector type", "VecSetType", VecList, defaultType, typeName, 256, &opt));
1411   if (opt) {
1412     PetscCall(VecSetType(vec, typeName));
1413   } else {
1414     PetscCall(VecSetType(vec, defaultType));
1415   }
1416   PetscFunctionReturn(PETSC_SUCCESS);
1417 }
1418 
1419 /*@
1420   VecSetFromOptions - Configures the vector from the options database.
1421 
1422   Collective
1423 
1424   Input Parameter:
1425 . vec - The vector
1426 
1427   Level: beginner
1428 
1429   Notes:
1430   To see all options, run your program with the -help option.
1431 
1432   Must be called after `VecCreate()` but before the vector is used.
1433 
1434 .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecSetOptionsPrefix()`
1435 @*/
VecSetFromOptions(Vec vec)1436 PetscErrorCode VecSetFromOptions(Vec vec)
1437 {
1438   PetscBool flg;
1439   PetscInt  bind_below = 0;
1440 
1441   PetscFunctionBegin;
1442   PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
1443 
1444   PetscObjectOptionsBegin((PetscObject)vec);
1445   /* Handle vector type options */
1446   PetscCall(VecSetTypeFromOptions_Private(vec, PetscOptionsObject));
1447 
1448   /* Handle specific vector options */
1449   PetscTryTypeMethod(vec, setfromoptions, PetscOptionsObject);
1450 
1451   /* Bind to CPU if below a user-specified size threshold.
1452    * This perhaps belongs in the options for the GPU Vec types, but VecBindToCPU() does nothing when called on non-GPU types,
1453    * and putting it here makes is more maintainable than duplicating this for all. */
1454   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));
1455   if (flg && vec->map->n < bind_below) PetscCall(VecBindToCPU(vec, PETSC_TRUE));
1456 
1457   /* process any options handlers added with PetscObjectAddOptionsHandler() */
1458   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)vec, PetscOptionsObject));
1459   PetscOptionsEnd();
1460   PetscFunctionReturn(PETSC_SUCCESS);
1461 }
1462 
1463 /*@
1464   VecSetSizes - Sets the local and global sizes, and checks to determine compatibility of the sizes
1465 
1466   Collective
1467 
1468   Input Parameters:
1469 + v - the vector
1470 . n - the local size (or `PETSC_DECIDE` to have it set)
1471 - N - the global size (or `PETSC_DETERMINE` to have it set)
1472 
1473   Level: intermediate
1474 
1475   Notes:
1476   `N` cannot be `PETSC_DETERMINE` if `n` is `PETSC_DECIDE`
1477 
1478   If one processor calls this with `N` of `PETSC_DETERMINE` then all processors must, otherwise the program will hang.
1479 
1480   If `n` is not `PETSC_DECIDE`, then the value determines the `PetscLayout` of the vector and the ranges returned by
1481   `VecGetOwnershipRange()` and `VecGetOwnershipRanges()`
1482 
1483 .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecCreateSeq()`, `VecCreateMPI()`, `VecGetSize()`, `PetscSplitOwnership()`, `PetscLayout`,
1484           `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`, `MatSetSizes()`
1485 @*/
VecSetSizes(Vec v,PetscInt n,PetscInt N)1486 PetscErrorCode VecSetSizes(Vec v, PetscInt n, PetscInt N)
1487 {
1488   PetscFunctionBegin;
1489   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1490   if (N >= 0) {
1491     PetscValidLogicalCollectiveInt(v, N, 3);
1492     PetscCheck(n <= N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " cannot be larger than global size %" PetscInt_FMT, n, N);
1493   }
1494   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,
1495              v->map->n, v->map->N);
1496   v->map->n = n;
1497   v->map->N = N;
1498   PetscTryTypeMethod(v, create);
1499   v->ops->create = NULL;
1500   PetscFunctionReturn(PETSC_SUCCESS);
1501 }
1502 
1503 /*@
1504   VecSetBlockSize - Sets the block size for future calls to `VecSetValuesBlocked()`
1505   and `VecSetValuesBlockedLocal()`.
1506 
1507   Logically Collective
1508 
1509   Input Parameters:
1510 + v  - the vector
1511 - bs - the blocksize
1512 
1513   Level: advanced
1514 
1515   Note:
1516   All vectors obtained by `VecDuplicate()` inherit the same blocksize.
1517 
1518   Vectors obtained with `DMCreateGlobalVector()` and `DMCreateLocalVector()` generally already have a blocksize set based on the state of the `DM`
1519 
1520 .seealso: [](ch_vectors), `Vec`, `VecSetValuesBlocked()`, `VecSetLocalToGlobalMapping()`, `VecGetBlockSize()`
1521 @*/
VecSetBlockSize(Vec v,PetscInt bs)1522 PetscErrorCode VecSetBlockSize(Vec v, PetscInt bs)
1523 {
1524   PetscFunctionBegin;
1525   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1526   PetscValidLogicalCollectiveInt(v, bs, 2);
1527   PetscCall(PetscLayoutSetBlockSize(v->map, bs));
1528   v->bstash.bs = bs; /* use the same blocksize for the vec's block-stash */
1529   PetscFunctionReturn(PETSC_SUCCESS);
1530 }
1531 
1532 /*@
1533   VecGetBlockSize - Gets the blocksize for the vector, i.e. what is used for `VecSetValuesBlocked()`
1534   and `VecSetValuesBlockedLocal()`.
1535 
1536   Not Collective
1537 
1538   Input Parameter:
1539 . v - the vector
1540 
1541   Output Parameter:
1542 . bs - the blocksize
1543 
1544   Level: advanced
1545 
1546   Note:
1547   All vectors obtained by `VecDuplicate()` inherit the same blocksize.
1548 
1549 .seealso: [](ch_vectors), `Vec`, `VecSetValuesBlocked()`, `VecSetLocalToGlobalMapping()`, `VecSetBlockSize()`
1550 @*/
VecGetBlockSize(Vec v,PetscInt * bs)1551 PetscErrorCode VecGetBlockSize(Vec v, PetscInt *bs)
1552 {
1553   PetscFunctionBegin;
1554   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1555   PetscAssertPointer(bs, 2);
1556   PetscCall(PetscLayoutGetBlockSize(v->map, bs));
1557   PetscFunctionReturn(PETSC_SUCCESS);
1558 }
1559 
1560 /*@
1561   VecSetOptionsPrefix - Sets the prefix used for searching for all
1562   `Vec` options in the database.
1563 
1564   Logically Collective
1565 
1566   Input Parameters:
1567 + v      - the `Vec` context
1568 - prefix - the prefix to prepend to all option names
1569 
1570   Level: advanced
1571 
1572   Note:
1573   A hyphen (-) must NOT be given at the beginning of the prefix name.
1574   The first character of all runtime options is AUTOMATICALLY the hyphen.
1575 
1576 .seealso: [](ch_vectors), `Vec`, `VecSetFromOptions()`
1577 @*/
VecSetOptionsPrefix(Vec v,const char prefix[])1578 PetscErrorCode VecSetOptionsPrefix(Vec v, const char prefix[])
1579 {
1580   PetscFunctionBegin;
1581   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1582   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)v, prefix));
1583   PetscFunctionReturn(PETSC_SUCCESS);
1584 }
1585 
1586 /*@
1587   VecAppendOptionsPrefix - Appends to the prefix used for searching for all
1588   `Vec` options in the database.
1589 
1590   Logically Collective
1591 
1592   Input Parameters:
1593 + v      - the `Vec` context
1594 - prefix - the prefix to prepend to all option names
1595 
1596   Level: advanced
1597 
1598   Note:
1599   A hyphen (-) must NOT be given at the beginning of the prefix name.
1600   The first character of all runtime options is AUTOMATICALLY the hyphen.
1601 
1602 .seealso: [](ch_vectors), `Vec`, `VecGetOptionsPrefix()`
1603 @*/
VecAppendOptionsPrefix(Vec v,const char prefix[])1604 PetscErrorCode VecAppendOptionsPrefix(Vec v, const char prefix[])
1605 {
1606   PetscFunctionBegin;
1607   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1608   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)v, prefix));
1609   PetscFunctionReturn(PETSC_SUCCESS);
1610 }
1611 
1612 /*@
1613   VecGetOptionsPrefix - Sets the prefix used for searching for all
1614   Vec options in the database.
1615 
1616   Not Collective
1617 
1618   Input Parameter:
1619 . v - the `Vec` context
1620 
1621   Output Parameter:
1622 . prefix - pointer to the prefix string used
1623 
1624   Level: advanced
1625 
1626 .seealso: [](ch_vectors), `Vec`, `VecAppendOptionsPrefix()`
1627 @*/
VecGetOptionsPrefix(Vec v,const char * prefix[])1628 PetscErrorCode VecGetOptionsPrefix(Vec v, const char *prefix[])
1629 {
1630   PetscFunctionBegin;
1631   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1632   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)v, prefix));
1633   PetscFunctionReturn(PETSC_SUCCESS);
1634 }
1635 
1636 /*@C
1637   VecGetState - Gets the state of a `Vec`.
1638 
1639   Not Collective
1640 
1641   Input Parameter:
1642 . v - the `Vec` context
1643 
1644   Output Parameter:
1645 . state - the object state
1646 
1647   Level: advanced
1648 
1649   Note:
1650   Object state is an integer which gets increased every time
1651   the object is changed. By saving and later querying the object state
1652   one can determine whether information about the object is still current.
1653 
1654 .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `PetscObjectStateGet()`
1655 @*/
VecGetState(Vec v,PetscObjectState * state)1656 PetscErrorCode VecGetState(Vec v, PetscObjectState *state)
1657 {
1658   PetscFunctionBegin;
1659   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1660   PetscAssertPointer(state, 2);
1661   PetscCall(PetscObjectStateGet((PetscObject)v, state));
1662   PetscFunctionReturn(PETSC_SUCCESS);
1663 }
1664 
1665 /*@
1666   VecSetUp - Sets up the internal vector data structures for the later use.
1667 
1668   Collective
1669 
1670   Input Parameter:
1671 . v - the `Vec` context
1672 
1673   Level: advanced
1674 
1675   Notes:
1676   For basic use of the `Vec` classes the user need not explicitly call
1677   `VecSetUp()`, since these actions will happen automatically.
1678 
1679 .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecDestroy()`
1680 @*/
VecSetUp(Vec v)1681 PetscErrorCode VecSetUp(Vec v)
1682 {
1683   PetscMPIInt size;
1684 
1685   PetscFunctionBegin;
1686   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1687   PetscCheck(v->map->n >= 0 || v->map->N >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Sizes not set");
1688   if (!((PetscObject)v)->type_name) {
1689     PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)v), &size));
1690     if (size == 1) {
1691       PetscCall(VecSetType(v, VECSEQ));
1692     } else {
1693       PetscCall(VecSetType(v, VECMPI));
1694     }
1695   }
1696   PetscFunctionReturn(PETSC_SUCCESS);
1697 }
1698 
1699 /*
1700     These currently expose the PetscScalar/PetscReal in updating the
1701     cached norm. If we push those down into the implementation these
1702     will become independent of PetscScalar/PetscReal
1703 */
1704 
VecCopyAsync_Private(Vec x,Vec y,PetscDeviceContext dctx)1705 PetscErrorCode VecCopyAsync_Private(Vec x, Vec y, PetscDeviceContext dctx)
1706 {
1707   PetscBool flgs[4];
1708   PetscReal norms[4] = {0.0, 0.0, 0.0, 0.0};
1709 
1710   PetscFunctionBegin;
1711   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
1712   PetscValidHeaderSpecific(y, VEC_CLASSID, 2);
1713   PetscValidType(x, 1);
1714   PetscValidType(y, 2);
1715   if (x == y) PetscFunctionReturn(PETSC_SUCCESS);
1716   VecCheckSameLocalSize(x, 1, y, 2);
1717   VecCheckAssembled(x);
1718   PetscCall(VecSetErrorIfLocked(y, 2));
1719 
1720 #if !defined(PETSC_USE_MIXED_PRECISION)
1721   for (PetscInt i = 0; i < 4; i++) PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], norms[i], flgs[i]));
1722 #endif
1723 
1724   PetscCall(PetscLogEventBegin(VEC_Copy, x, y, 0, 0));
1725 #if defined(PETSC_USE_MIXED_PRECISION)
1726   extern PetscErrorCode VecGetArray(Vec, double **);
1727   extern PetscErrorCode VecRestoreArray(Vec, double **);
1728   extern PetscErrorCode VecGetArray(Vec, float **);
1729   extern PetscErrorCode VecRestoreArray(Vec, float **);
1730   extern PetscErrorCode VecGetArrayRead(Vec, const double **);
1731   extern PetscErrorCode VecRestoreArrayRead(Vec, const double **);
1732   extern PetscErrorCode VecGetArrayRead(Vec, const float **);
1733   extern PetscErrorCode VecRestoreArrayRead(Vec, const float **);
1734   if ((((PetscObject)x)->precision == PETSC_PRECISION_SINGLE) && (((PetscObject)y)->precision == PETSC_PRECISION_DOUBLE)) {
1735     PetscInt     i, n;
1736     const float *xx;
1737     double      *yy;
1738     PetscCall(VecGetArrayRead(x, &xx));
1739     PetscCall(VecGetArray(y, &yy));
1740     PetscCall(VecGetLocalSize(x, &n));
1741     for (i = 0; i < n; i++) yy[i] = xx[i];
1742     PetscCall(VecRestoreArrayRead(x, &xx));
1743     PetscCall(VecRestoreArray(y, &yy));
1744   } else if ((((PetscObject)x)->precision == PETSC_PRECISION_DOUBLE) && (((PetscObject)y)->precision == PETSC_PRECISION_SINGLE)) {
1745     PetscInt      i, n;
1746     float        *yy;
1747     const double *xx;
1748     PetscCall(VecGetArrayRead(x, &xx));
1749     PetscCall(VecGetArray(y, &yy));
1750     PetscCall(VecGetLocalSize(x, &n));
1751     for (i = 0; i < n; i++) yy[i] = (float)xx[i];
1752     PetscCall(VecRestoreArrayRead(x, &xx));
1753     PetscCall(VecRestoreArray(y, &yy));
1754   } else PetscUseTypeMethod(x, copy, y);
1755 #else
1756   VecMethodDispatch(x, dctx, VecAsyncFnName(Copy), copy, (Vec, Vec, PetscDeviceContext), y);
1757 #endif
1758 
1759   PetscCall(PetscObjectStateIncrease((PetscObject)y));
1760 #if !defined(PETSC_USE_MIXED_PRECISION)
1761   for (PetscInt i = 0; i < 4; i++) {
1762     if (flgs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)y, NormIds[i], norms[i]));
1763   }
1764 #endif
1765 
1766   PetscCall(PetscLogEventEnd(VEC_Copy, x, y, 0, 0));
1767   PetscFunctionReturn(PETSC_SUCCESS);
1768 }
1769 
1770 /*@
1771   VecCopy - Copies a vector `y = x`
1772 
1773   Logically Collective
1774 
1775   Input Parameter:
1776 . x - the vector
1777 
1778   Output Parameter:
1779 . y - the copy
1780 
1781   Level: beginner
1782 
1783   Note:
1784   For default parallel PETSc vectors, both `x` and `y` must be distributed in
1785   the same manner; local copies are done.
1786 
1787   Developer Notes:
1788   `PetscCheckSameTypeAndComm`(x,1,y,2) is not used on these vectors because we allow one
1789   of the vectors to be sequential and one to be parallel so long as both have the same
1790   local sizes. This is used in some internal functions in PETSc.
1791 
1792 .seealso: [](ch_vectors), `Vec`, `VecDuplicate()`
1793 @*/
VecCopy(Vec x,Vec y)1794 PetscErrorCode VecCopy(Vec x, Vec y)
1795 {
1796   PetscFunctionBegin;
1797   PetscCall(VecCopyAsync_Private(x, y, NULL));
1798   PetscFunctionReturn(PETSC_SUCCESS);
1799 }
1800 
VecSwapAsync_Private(Vec x,Vec y,PetscDeviceContext dctx)1801 PetscErrorCode VecSwapAsync_Private(Vec x, Vec y, PetscDeviceContext dctx)
1802 {
1803   PetscReal normxs[4], normys[4];
1804   PetscBool flgxs[4], flgys[4];
1805 
1806   PetscFunctionBegin;
1807   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
1808   PetscValidHeaderSpecific(y, VEC_CLASSID, 2);
1809   PetscValidType(x, 1);
1810   PetscValidType(y, 2);
1811   PetscCheckSameTypeAndComm(x, 1, y, 2);
1812   VecCheckSameSize(x, 1, y, 2);
1813   VecCheckAssembled(x);
1814   VecCheckAssembled(y);
1815   PetscCall(VecSetErrorIfLocked(x, 1));
1816   PetscCall(VecSetErrorIfLocked(y, 2));
1817 
1818   for (PetscInt i = 0; i < 4; i++) {
1819     PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], normxs[i], flgxs[i]));
1820     PetscCall(PetscObjectComposedDataGetReal((PetscObject)y, NormIds[i], normys[i], flgys[i]));
1821   }
1822 
1823   PetscCall(PetscLogEventBegin(VEC_Swap, x, y, 0, 0));
1824   VecMethodDispatch(x, dctx, VecAsyncFnName(Swap), swap, (Vec, Vec, PetscDeviceContext), y);
1825   PetscCall(PetscLogEventEnd(VEC_Swap, x, y, 0, 0));
1826 
1827   PetscCall(PetscObjectStateIncrease((PetscObject)x));
1828   PetscCall(PetscObjectStateIncrease((PetscObject)y));
1829   for (PetscInt i = 0; i < 4; i++) {
1830     if (flgxs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)y, NormIds[i], normxs[i]));
1831     if (flgys[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[i], normys[i]));
1832   }
1833   PetscFunctionReturn(PETSC_SUCCESS);
1834 }
1835 /*@
1836   VecSwap - Swaps the values between two vectors, `x` and `y`.
1837 
1838   Logically Collective
1839 
1840   Input Parameters:
1841 + x - the first vector
1842 - y - the second vector
1843 
1844   Level: advanced
1845 
1846 .seealso: [](ch_vectors), `Vec`, `VecSet()`
1847 @*/
VecSwap(Vec x,Vec y)1848 PetscErrorCode VecSwap(Vec x, Vec y)
1849 {
1850   PetscFunctionBegin;
1851   PetscCall(VecSwapAsync_Private(x, y, NULL));
1852   PetscFunctionReturn(PETSC_SUCCESS);
1853 }
1854 
1855 /*@
1856   VecStashViewFromOptions - Processes command line options to determine if/how a `VecStash` object is to be viewed.
1857 
1858   Collective
1859 
1860   Input Parameters:
1861 + obj        - the `Vec` containing a stash
1862 . bobj       - optional other object that provides the prefix
1863 - optionname - option to activate viewing
1864 
1865   Level: intermediate
1866 
1867   Developer Notes:
1868   This cannot use `PetscObjectViewFromOptions()` because it takes a `Vec` as an argument but does not use `VecView()`
1869 
1870 .seealso: [](ch_vectors), `Vec`, `VecStashSetInitialSize()`
1871 @*/
VecStashViewFromOptions(Vec obj,PetscObject bobj,const char optionname[])1872 PetscErrorCode VecStashViewFromOptions(Vec obj, PetscObject bobj, const char optionname[])
1873 {
1874   PetscViewer       viewer;
1875   PetscBool         flg;
1876   PetscViewerFormat format;
1877   char             *prefix;
1878 
1879   PetscFunctionBegin;
1880   prefix = bobj ? bobj->prefix : ((PetscObject)obj)->prefix;
1881   PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)obj), ((PetscObject)obj)->options, prefix, optionname, &viewer, &format, &flg));
1882   if (flg) {
1883     PetscCall(PetscViewerPushFormat(viewer, format));
1884     PetscCall(VecStashView(obj, viewer));
1885     PetscCall(PetscViewerPopFormat(viewer));
1886     PetscCall(PetscViewerDestroy(&viewer));
1887   }
1888   PetscFunctionReturn(PETSC_SUCCESS);
1889 }
1890 
1891 /*@
1892   VecStashView - Prints the entries in the vector stash and block stash.
1893 
1894   Collective
1895 
1896   Input Parameters:
1897 + v      - the vector
1898 - viewer - the viewer
1899 
1900   Level: advanced
1901 
1902 .seealso: [](ch_vectors), `Vec`, `VecSetBlockSize()`, `VecSetValues()`, `VecSetValuesBlocked()`
1903 @*/
VecStashView(Vec v,PetscViewer viewer)1904 PetscErrorCode VecStashView(Vec v, PetscViewer viewer)
1905 {
1906   PetscMPIInt rank;
1907   PetscInt    i, j;
1908   PetscBool   match;
1909   VecStash   *s;
1910   PetscScalar val;
1911 
1912   PetscFunctionBegin;
1913   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1914   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1915   PetscCheckSameComm(v, 1, viewer, 2);
1916 
1917   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &match));
1918   PetscCheck(match, PETSC_COMM_SELF, PETSC_ERR_SUP, "Stash viewer only works with ASCII viewer not %s", ((PetscObject)v)->type_name);
1919   PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1920   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)v), &rank));
1921   s = &v->bstash;
1922 
1923   /* print block stash */
1924   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
1925   PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Vector Block stash size %" PetscInt_FMT " block size %" PetscInt_FMT "\n", rank, s->n, s->bs));
1926   for (i = 0; i < s->n; i++) {
1927     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " ", rank, s->idx[i]));
1928     for (j = 0; j < s->bs; j++) {
1929       val = s->array[i * s->bs + j];
1930 #if defined(PETSC_USE_COMPLEX)
1931       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "(%18.16e %18.16e) ", (double)PetscRealPart(val), (double)PetscImaginaryPart(val)));
1932 #else
1933       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%18.16e ", (double)val));
1934 #endif
1935     }
1936     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
1937   }
1938   PetscCall(PetscViewerFlush(viewer));
1939 
1940   s = &v->stash;
1941 
1942   /* print basic stash */
1943   PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Vector stash size %" PetscInt_FMT "\n", rank, s->n));
1944   for (i = 0; i < s->n; i++) {
1945     val = s->array[i];
1946 #if defined(PETSC_USE_COMPLEX)
1947     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " (%18.16e %18.16e) ", rank, s->idx[i], (double)PetscRealPart(val), (double)PetscImaginaryPart(val)));
1948 #else
1949     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " %18.16e\n", rank, s->idx[i], (double)val));
1950 #endif
1951   }
1952   PetscCall(PetscViewerFlush(viewer));
1953   PetscCall(PetscViewerASCIIPopSynchronized(viewer));
1954   PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1955   PetscFunctionReturn(PETSC_SUCCESS);
1956 }
1957 
PetscOptionsGetVec(PetscOptions options,const char prefix[],const char key[],Vec v,PetscBool * set)1958 PetscErrorCode PetscOptionsGetVec(PetscOptions options, const char prefix[], const char key[], Vec v, PetscBool *set)
1959 {
1960   PetscInt     i, N, rstart, rend;
1961   PetscScalar *xx;
1962   PetscReal   *xreal;
1963   PetscBool    iset;
1964 
1965   PetscFunctionBegin;
1966   PetscCall(VecGetOwnershipRange(v, &rstart, &rend));
1967   PetscCall(VecGetSize(v, &N));
1968   PetscCall(PetscCalloc1(N, &xreal));
1969   PetscCall(PetscOptionsGetRealArray(options, prefix, key, xreal, &N, &iset));
1970   if (iset) {
1971     PetscCall(VecGetArray(v, &xx));
1972     for (i = rstart; i < rend; i++) xx[i - rstart] = xreal[i];
1973     PetscCall(VecRestoreArray(v, &xx));
1974   }
1975   PetscCall(PetscFree(xreal));
1976   if (set) *set = iset;
1977   PetscFunctionReturn(PETSC_SUCCESS);
1978 }
1979 
1980 /*@
1981   VecGetLayout - get `PetscLayout` describing a vector layout
1982 
1983   Not Collective
1984 
1985   Input Parameter:
1986 . x - the vector
1987 
1988   Output Parameter:
1989 . map - the layout
1990 
1991   Level: developer
1992 
1993   Note:
1994   The layout determines what vector elements are contained on each MPI process
1995 
1996 .seealso: [](ch_vectors), `PetscLayout`, `Vec`, `VecGetSize()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
1997 @*/
VecGetLayout(Vec x,PetscLayout * map)1998 PetscErrorCode VecGetLayout(Vec x, PetscLayout *map)
1999 {
2000   PetscFunctionBegin;
2001   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
2002   PetscAssertPointer(map, 2);
2003   *map = x->map;
2004   PetscFunctionReturn(PETSC_SUCCESS);
2005 }
2006 
2007 /*@
2008   VecSetLayout - set `PetscLayout` describing vector layout
2009 
2010   Not Collective
2011 
2012   Input Parameters:
2013 + x   - the vector
2014 - map - the layout
2015 
2016   Level: developer
2017 
2018   Note:
2019   It is normally only valid to replace the layout with a layout known to be equivalent.
2020 
2021 .seealso: [](ch_vectors), `Vec`, `PetscLayout`, `VecGetLayout()`, `VecGetSize()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
2022 @*/
VecSetLayout(Vec x,PetscLayout map)2023 PetscErrorCode VecSetLayout(Vec x, PetscLayout map)
2024 {
2025   PetscFunctionBegin;
2026   PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
2027   PetscCall(PetscLayoutReference(map, &x->map));
2028   PetscFunctionReturn(PETSC_SUCCESS);
2029 }
2030 
2031 /*@
2032   VecFlag - set infinity into the local part of the vector on any subset of MPI processes
2033 
2034   Logically Collective
2035 
2036   Input Parameters:
2037 + xin - the vector, can be `NULL` but only if on all processes
2038 - flg - indicates if this processes portion of the vector should be set to infinity
2039 
2040   Level: developer
2041 
2042   Note:
2043   This removes the values from the vector norm cache for all processes by calling `PetscObjectIncrease()`.
2044 
2045   This is used for any subset of MPI processes to indicate an failure in a solver, after the next use of `VecNorm()` if
2046   `KSPCheckNorm()` detects an infinity and at least one of the MPI processes has a not converged reason then the `KSP`
2047   object collectively is labeled as not converged.
2048 
2049 .seealso: [](ch_vectors), `Vec`, `PetscLayout`, `VecGetLayout()`, `VecGetSize()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
2050 @*/
VecFlag(Vec xin,PetscInt flg)2051 PetscErrorCode VecFlag(Vec xin, PetscInt flg)
2052 {
2053   // MSVC gives "divide by zero" error at compile time - so declare as volatile to skip this check.
2054   volatile PetscReal one = 1.0, zero = 0.0;
2055   PetscScalar        inf;
2056 
2057   PetscFunctionBegin;
2058   if (!xin) PetscFunctionReturn(PETSC_SUCCESS);
2059   PetscValidHeaderSpecific(xin, VEC_CLASSID, 1);
2060   PetscCall(PetscObjectStateIncrease((PetscObject)xin));
2061   if (flg) {
2062     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
2063     inf = one / zero;
2064     PetscCall(PetscFPTrapPop());
2065     if (xin->ops->set) {
2066       PetscUseTypeMethod(xin, set, inf);
2067     } else {
2068       PetscInt     n;
2069       PetscScalar *xx;
2070 
2071       PetscCall(VecGetLocalSize(xin, &n));
2072       PetscCall(VecGetArrayWrite(xin, &xx));
2073       for (PetscInt i = 0; i < n; ++i) xx[i] = inf;
2074       PetscCall(VecRestoreArrayWrite(xin, &xx));
2075     }
2076   }
2077   PetscFunctionReturn(PETSC_SUCCESS);
2078 }
2079 
2080 /*@
2081   VecSetInf - set infinity into the local part of the vector
2082 
2083   Not Collective
2084 
2085   Input Parameters:
2086 . xin - the vector
2087 
2088   Level: developer
2089 
2090   Note:
2091   Deprecated, see  `VecFlag()`
2092   This is used for any subset of MPI processes to indicate an failure in a solver, after the next use of `VecNorm()` if
2093   `KSPCheckNorm()` detects an infinity and at least one of the MPI processes has a not converged reason then the `KSP`
2094   object collectively is labeled as not converged.
2095 
2096   This cannot be called if `xin` has a cached norm available
2097 
2098 .seealso: [](ch_vectors), `VecFlag()`, `Vec`, `PetscLayout`, `VecGetLayout()`, `VecGetSize()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
2099 @*/
VecSetInf(Vec xin)2100 PetscErrorCode VecSetInf(Vec xin)
2101 {
2102   // MSVC gives "divide by zero" error at compile time - so declare as volatile to skip this check.
2103   volatile PetscReal one = 1.0, zero = 0.0;
2104   PetscScalar        inf;
2105   PetscBool          flg;
2106 
2107   PetscFunctionBegin;
2108   PetscCall(VecNormAvailable(xin, NORM_2, &flg, NULL));
2109   PetscCheck(!flg, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot call VecSetInf() if the vector has a cached norm");
2110   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
2111   inf = one / zero;
2112   PetscCall(PetscFPTrapPop());
2113   if (xin->ops->set) {
2114     PetscUseTypeMethod(xin, set, inf);
2115   } else {
2116     PetscInt     n;
2117     PetscScalar *xx;
2118 
2119     PetscCall(VecGetLocalSize(xin, &n));
2120     PetscCall(VecGetArrayWrite(xin, &xx));
2121     for (PetscInt i = 0; i < n; ++i) xx[i] = inf;
2122     PetscCall(VecRestoreArrayWrite(xin, &xx));
2123   }
2124   PetscFunctionReturn(PETSC_SUCCESS);
2125 }
2126 
2127 /*@
2128   VecBindToCPU - marks a vector to temporarily stay on the CPU and perform computations on the CPU
2129 
2130   Logically collective
2131 
2132   Input Parameters:
2133 + v   - the vector
2134 - flg - bind to the CPU if value of `PETSC_TRUE`
2135 
2136   Level: intermediate
2137 
2138 .seealso: [](ch_vectors), `Vec`, `VecBoundToCPU()`
2139 @*/
VecBindToCPU(Vec v,PetscBool flg)2140 PetscErrorCode VecBindToCPU(Vec v, PetscBool flg)
2141 {
2142   PetscFunctionBegin;
2143   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
2144   PetscValidLogicalCollectiveBool(v, flg, 2);
2145 #if defined(PETSC_HAVE_DEVICE)
2146   if (v->boundtocpu == flg) PetscFunctionReturn(PETSC_SUCCESS);
2147   v->boundtocpu = flg;
2148   PetscTryTypeMethod(v, bindtocpu, flg);
2149 #endif
2150   PetscFunctionReturn(PETSC_SUCCESS);
2151 }
2152 
2153 /*@
2154   VecBoundToCPU - query if a vector is bound to the CPU
2155 
2156   Not collective
2157 
2158   Input Parameter:
2159 . v - the vector
2160 
2161   Output Parameter:
2162 . flg - the logical flag
2163 
2164   Level: intermediate
2165 
2166 .seealso: [](ch_vectors), `Vec`, `VecBindToCPU()`
2167 @*/
VecBoundToCPU(Vec v,PetscBool * flg)2168 PetscErrorCode VecBoundToCPU(Vec v, PetscBool *flg)
2169 {
2170   PetscFunctionBegin;
2171   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
2172   PetscAssertPointer(flg, 2);
2173 #if defined(PETSC_HAVE_DEVICE)
2174   *flg = v->boundtocpu;
2175 #else
2176   *flg = PETSC_TRUE;
2177 #endif
2178   PetscFunctionReturn(PETSC_SUCCESS);
2179 }
2180 
2181 /*@
2182   VecSetBindingPropagates - Sets whether the state of being bound to the CPU for a GPU vector type propagates to child and some other associated objects
2183 
2184   Input Parameters:
2185 + v   - the vector
2186 - flg - flag indicating whether the boundtocpu flag should be propagated
2187 
2188   Level: developer
2189 
2190   Notes:
2191   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.
2192   The created vectors will also have their bindingpropagates flag set to true.
2193 
2194   Developer Notes:
2195   If a `DMDA` has the `-dm_bind_below option` set to true, then vectors created by `DMCreateGlobalVector()` will have `VecSetBindingPropagates()` called on them to
2196   set their bindingpropagates flag to true.
2197 
2198 .seealso: [](ch_vectors), `Vec`, `MatSetBindingPropagates()`, `VecGetBindingPropagates()`
2199 @*/
VecSetBindingPropagates(Vec v,PetscBool flg)2200 PetscErrorCode VecSetBindingPropagates(Vec v, PetscBool flg)
2201 {
2202   PetscFunctionBegin;
2203   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
2204 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2205   v->bindingpropagates = flg;
2206 #endif
2207   PetscFunctionReturn(PETSC_SUCCESS);
2208 }
2209 
2210 /*@
2211   VecGetBindingPropagates - Gets whether the state of being bound to the CPU for a GPU vector type propagates to child and some other associated objects
2212 
2213   Input Parameter:
2214 . v - the vector
2215 
2216   Output Parameter:
2217 . flg - flag indicating whether the boundtocpu flag will be propagated
2218 
2219   Level: developer
2220 
2221 .seealso: [](ch_vectors), `Vec`, `VecSetBindingPropagates()`
2222 @*/
VecGetBindingPropagates(Vec v,PetscBool * flg)2223 PetscErrorCode VecGetBindingPropagates(Vec v, PetscBool *flg)
2224 {
2225   PetscFunctionBegin;
2226   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
2227   PetscAssertPointer(flg, 2);
2228 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2229   *flg = v->bindingpropagates;
2230 #else
2231   *flg = PETSC_FALSE;
2232 #endif
2233   PetscFunctionReturn(PETSC_SUCCESS);
2234 }
2235 
2236 /*@C
2237   VecSetPinnedMemoryMin - Set the minimum data size for which pinned memory will be used for host (CPU) allocations.
2238 
2239   Logically Collective
2240 
2241   Input Parameters:
2242 + v      - the vector
2243 - mbytes - minimum data size in bytes
2244 
2245   Options Database Key:
2246 . -vec_pinned_memory_min <size> - minimum size (in bytes) for an allocation to use pinned memory on host.
2247 
2248   Level: developer
2249 
2250   Note:
2251   Specifying -1 ensures that pinned memory will never be used.
2252 
2253 .seealso: [](ch_vectors), `Vec`, `VecGetPinnedMemoryMin()`
2254 @*/
VecSetPinnedMemoryMin(Vec v,size_t mbytes)2255 PetscErrorCode VecSetPinnedMemoryMin(Vec v, size_t mbytes)
2256 {
2257   PetscFunctionBegin;
2258   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
2259 #if PetscDefined(HAVE_DEVICE)
2260   v->minimum_bytes_pinned_memory = mbytes;
2261 #endif
2262   PetscFunctionReturn(PETSC_SUCCESS);
2263 }
2264 
2265 /*@C
2266   VecGetPinnedMemoryMin - Get the minimum data size for which pinned memory will be used for host (CPU) allocations.
2267 
2268   Logically Collective
2269 
2270   Input Parameter:
2271 . v - the vector
2272 
2273   Output Parameter:
2274 . mbytes - minimum data size in bytes
2275 
2276   Level: developer
2277 
2278 .seealso: [](ch_vectors), `Vec`, `VecSetPinnedMemoryMin()`
2279 @*/
VecGetPinnedMemoryMin(Vec v,size_t * mbytes)2280 PetscErrorCode VecGetPinnedMemoryMin(Vec v, size_t *mbytes)
2281 {
2282   PetscFunctionBegin;
2283   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
2284   PetscAssertPointer(mbytes, 2);
2285 #if PetscDefined(HAVE_DEVICE)
2286   *mbytes = v->minimum_bytes_pinned_memory;
2287 #endif
2288   PetscFunctionReturn(PETSC_SUCCESS);
2289 }
2290 
2291 /*@
2292   VecGetOffloadMask - Get the offload mask of a `Vec`
2293 
2294   Not Collective
2295 
2296   Input Parameter:
2297 . v - the vector
2298 
2299   Output Parameter:
2300 . mask - corresponding `PetscOffloadMask` enum value.
2301 
2302   Level: intermediate
2303 
2304 .seealso: [](ch_vectors), `Vec`, `VecCreateSeqCUDA()`, `VecCreateSeqViennaCL()`, `VecGetArray()`, `VecGetType()`
2305 @*/
VecGetOffloadMask(Vec v,PetscOffloadMask * mask)2306 PetscErrorCode VecGetOffloadMask(Vec v, PetscOffloadMask *mask)
2307 {
2308   PetscFunctionBegin;
2309   PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
2310   PetscAssertPointer(mask, 2);
2311   *mask = v->offloadmask;
2312   PetscFunctionReturn(PETSC_SUCCESS);
2313 }
2314 
2315 #if !defined(PETSC_HAVE_VIENNACL)
VecViennaCLGetCLContext(Vec v,PETSC_UINTPTR_T * ctx)2316 PETSC_EXTERN PetscErrorCode VecViennaCLGetCLContext(Vec v, PETSC_UINTPTR_T *ctx)
2317 {
2318   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_context");
2319 }
2320 
VecViennaCLGetCLQueue(Vec v,PETSC_UINTPTR_T * queue)2321 PETSC_EXTERN PetscErrorCode VecViennaCLGetCLQueue(Vec v, PETSC_UINTPTR_T *queue)
2322 {
2323   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_command_queue");
2324 }
2325 
VecViennaCLGetCLMem(Vec v,PETSC_UINTPTR_T * queue)2326 PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMem(Vec v, PETSC_UINTPTR_T *queue)
2327 {
2328   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2329 }
2330 
VecViennaCLGetCLMemRead(Vec v,PETSC_UINTPTR_T * queue)2331 PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMemRead(Vec v, PETSC_UINTPTR_T *queue)
2332 {
2333   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2334 }
2335 
VecViennaCLGetCLMemWrite(Vec v,PETSC_UINTPTR_T * queue)2336 PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMemWrite(Vec v, PETSC_UINTPTR_T *queue)
2337 {
2338   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2339 }
2340 
VecViennaCLRestoreCLMemWrite(Vec v)2341 PETSC_EXTERN PetscErrorCode VecViennaCLRestoreCLMemWrite(Vec v)
2342 {
2343   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to restore a Vec's cl_mem");
2344 }
2345 #endif
2346 
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)2347 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)
2348 {
2349   const PetscScalar *u, *y;
2350   const PetscScalar *atola = NULL, *rtola = NULL, *erra = NULL;
2351   PetscInt           n, n_loc = 0, na_loc = 0, nr_loc = 0;
2352   PetscReal          nrm = 0, nrma = 0, nrmr = 0, err_loc[6];
2353 
2354   PetscFunctionBegin;
2355 #define SkipSmallValue(a, b, tol) \
2356   if (PetscAbsScalar(a) < tol || PetscAbsScalar(b) < tol) continue
2357 
2358   PetscCall(VecGetLocalSize(U, &n));
2359   PetscCall(VecGetArrayRead(U, &u));
2360   PetscCall(VecGetArrayRead(Y, &y));
2361   if (E) PetscCall(VecGetArrayRead(E, &erra));
2362   if (vatol) PetscCall(VecGetArrayRead(vatol, &atola));
2363   if (vrtol) PetscCall(VecGetArrayRead(vrtol, &rtola));
2364   for (PetscInt i = 0; i < n; i++) {
2365     PetscReal err, tol, tola, tolr;
2366 
2367     SkipSmallValue(y[i], u[i], ignore_max);
2368     atol = atola ? PetscRealPart(atola[i]) : atol;
2369     rtol = rtola ? PetscRealPart(rtola[i]) : rtol;
2370     err  = erra ? PetscAbsScalar(erra[i]) : PetscAbsScalar(y[i] - u[i]);
2371     tola = atol;
2372     tolr = rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
2373     tol  = tola + tolr;
2374     if (tola > 0.) {
2375       if (wnormtype == NORM_INFINITY) nrma = PetscMax(nrma, err / tola);
2376       else nrma += PetscSqr(err / tola);
2377       na_loc++;
2378     }
2379     if (tolr > 0.) {
2380       if (wnormtype == NORM_INFINITY) nrmr = PetscMax(nrmr, err / tolr);
2381       else nrmr += PetscSqr(err / tolr);
2382       nr_loc++;
2383     }
2384     if (tol > 0.) {
2385       if (wnormtype == NORM_INFINITY) nrm = PetscMax(nrm, err / tol);
2386       else nrm += PetscSqr(err / tol);
2387       n_loc++;
2388     }
2389   }
2390   if (E) PetscCall(VecRestoreArrayRead(E, &erra));
2391   if (vatol) PetscCall(VecRestoreArrayRead(vatol, &atola));
2392   if (vrtol) PetscCall(VecRestoreArrayRead(vrtol, &rtola));
2393   PetscCall(VecRestoreArrayRead(U, &u));
2394   PetscCall(VecRestoreArrayRead(Y, &y));
2395 #undef SkipSmallValue
2396 
2397   err_loc[0] = nrm;
2398   err_loc[1] = nrma;
2399   err_loc[2] = nrmr;
2400   err_loc[3] = (PetscReal)n_loc;
2401   err_loc[4] = (PetscReal)na_loc;
2402   err_loc[5] = (PetscReal)nr_loc;
2403   if (wnormtype == NORM_2) {
2404     PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, err_loc, 6, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)U)));
2405   } else {
2406     PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, err_loc, 3, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)U)));
2407     PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, err_loc + 3, 3, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)U)));
2408   }
2409   if (wnormtype == NORM_2) {
2410     *norm  = PetscSqrtReal(err_loc[0]);
2411     *norma = PetscSqrtReal(err_loc[1]);
2412     *normr = PetscSqrtReal(err_loc[2]);
2413   } else {
2414     *norm  = err_loc[0];
2415     *norma = err_loc[1];
2416     *normr = err_loc[2];
2417   }
2418   *norm_loc  = (PetscInt)err_loc[3];
2419   *norma_loc = (PetscInt)err_loc[4];
2420   *normr_loc = (PetscInt)err_loc[5];
2421   PetscFunctionReturn(PETSC_SUCCESS);
2422 }
2423 
2424 /*@
2425   VecErrorWeightedNorms - compute a weighted norm of the difference between two vectors
2426 
2427   Collective
2428 
2429   Input Parameters:
2430 + U          - first vector to be compared
2431 . Y          - second vector to be compared
2432 . E          - optional third vector representing the error (if not provided, the error is ||U-Y||)
2433 . wnormtype  - norm type
2434 . atol       - scalar for absolute tolerance
2435 . vatol      - vector representing per-entry absolute tolerances (can be ``NULL``)
2436 . rtol       - scalar for relative tolerance
2437 . vrtol      - vector representing per-entry relative tolerances (can be ``NULL``)
2438 - ignore_max - ignore values smaller than this value in absolute terms.
2439 
2440   Output Parameters:
2441 + norm      - weighted norm
2442 . norm_loc  - number of vector locations used for the weighted norm
2443 . norma     - weighted norm based on the absolute tolerance
2444 . norma_loc - number of vector locations used for the absolute weighted norm
2445 . normr     - weighted norm based on the relative tolerance
2446 - normr_loc - number of vector locations used for the relative weighted norm
2447 
2448   Level: developer
2449 
2450   Notes:
2451   This is primarily used for computing weighted local truncation errors in ``TS``.
2452 
2453 .seealso: [](ch_vectors), `Vec`, `NormType`, `TSErrorWeightedNorm()`, `TSErrorWeightedENorm()`
2454 @*/
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)2455 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)
2456 {
2457   PetscFunctionBegin;
2458   PetscValidHeaderSpecific(U, VEC_CLASSID, 1);
2459   PetscValidType(U, 1);
2460   PetscValidHeaderSpecific(Y, VEC_CLASSID, 2);
2461   PetscValidType(Y, 2);
2462   if (E) {
2463     PetscValidHeaderSpecific(E, VEC_CLASSID, 3);
2464     PetscValidType(E, 3);
2465   }
2466   PetscValidLogicalCollectiveEnum(U, wnormtype, 4);
2467   PetscValidLogicalCollectiveReal(U, atol, 5);
2468   if (vatol) {
2469     PetscValidHeaderSpecific(vatol, VEC_CLASSID, 6);
2470     PetscValidType(vatol, 6);
2471   }
2472   PetscValidLogicalCollectiveReal(U, rtol, 7);
2473   if (vrtol) {
2474     PetscValidHeaderSpecific(vrtol, VEC_CLASSID, 8);
2475     PetscValidType(vrtol, 8);
2476   }
2477   PetscValidLogicalCollectiveReal(U, ignore_max, 9);
2478   PetscAssertPointer(norm, 10);
2479   PetscAssertPointer(norm_loc, 11);
2480   PetscAssertPointer(norma, 12);
2481   PetscAssertPointer(norma_loc, 13);
2482   PetscAssertPointer(normr, 14);
2483   PetscAssertPointer(normr_loc, 15);
2484   PetscCheck(wnormtype == NORM_2 || wnormtype == NORM_INFINITY, PetscObjectComm((PetscObject)U), PETSC_ERR_SUP, "No support for norm type %s", NormTypes[wnormtype]);
2485 
2486   /* There are potentially 5 vectors involved, some of them may happen to be of different type or bound to cpu.
2487      Here we check that they all implement the same operation and call it if so.
2488      Otherwise, we call the _Basic implementation that always works (provided VecGetArrayRead is implemented). */
2489   PetscBool sameop = (PetscBool)(U->ops->errorwnorm && U->ops->errorwnorm == Y->ops->errorwnorm);
2490   if (sameop && E) sameop = (PetscBool)(U->ops->errorwnorm == E->ops->errorwnorm);
2491   if (sameop && vatol) sameop = (PetscBool)(U->ops->errorwnorm == vatol->ops->errorwnorm);
2492   if (sameop && vrtol) sameop = (PetscBool)(U->ops->errorwnorm == vrtol->ops->errorwnorm);
2493   if (sameop) PetscUseTypeMethod(U, errorwnorm, Y, E, wnormtype, atol, vatol, rtol, vrtol, ignore_max, norm, norm_loc, norma, norma_loc, normr, normr_loc);
2494   else PetscCall(VecErrorWeightedNorms_Basic(U, Y, E, wnormtype, atol, vatol, rtol, vrtol, ignore_max, norm, norm_loc, norma, norma_loc, normr, normr_loc));
2495   PetscFunctionReturn(PETSC_SUCCESS);
2496 }
2497