xref: /petsc/doc/manual/vec.md (revision 7f296bb328fcd4c99f2da7bfe8ba7ed8a4ebceee)
1*7f296bb3SBarry Smith(ch_vectors)=
2*7f296bb3SBarry Smith
3*7f296bb3SBarry Smith# Vectors and Parallel Data
4*7f296bb3SBarry Smith
5*7f296bb3SBarry SmithVectors (denoted by `Vec`) are used to store discrete PDE solutions, right-hand sides for
6*7f296bb3SBarry Smithlinear systems, etc. Users can create and manipulate entries in vectors directly with a basic, low-level interface or
7*7f296bb3SBarry Smiththey can use the PETSc `DM` objects to connect actions on vectors to the type of discretization and grid that they are
8*7f296bb3SBarry Smithworking with. These higher-level interfaces handle much of the details of the interactions with vectors and hence, are preferred
9*7f296bb3SBarry Smithin most situations. This chapter is organized as follows:
10*7f296bb3SBarry Smith
11*7f296bb3SBarry Smith- {any}`sec_veccreate`
12*7f296bb3SBarry Smith
13*7f296bb3SBarry Smith  - User managed
14*7f296bb3SBarry Smith  - {any}`sec_struct`
15*7f296bb3SBarry Smith  - {any}`sec_stag`
16*7f296bb3SBarry Smith  - {any}`sec_unstruct`
17*7f296bb3SBarry Smith  - {any}`sec_network`
18*7f296bb3SBarry Smith
19*7f296bb3SBarry Smith- Setting vector values
20*7f296bb3SBarry Smith
21*7f296bb3SBarry Smith  - For generic vectors
22*7f296bb3SBarry Smith  - {any}`sec_struct_set`
23*7f296bb3SBarry Smith  - {any}`sec_stag_set`
24*7f296bb3SBarry Smith  - {any}`sec_unstruct_set`
25*7f296bb3SBarry Smith  - {any}`sec_network_set`
26*7f296bb3SBarry Smith
27*7f296bb3SBarry Smith- {any}`sec_vecbasic`
28*7f296bb3SBarry Smith
29*7f296bb3SBarry Smith- {any}`sec_localglobal`
30*7f296bb3SBarry Smith
31*7f296bb3SBarry Smith- {any}`sec_scatter`
32*7f296bb3SBarry Smith
33*7f296bb3SBarry Smith  - {any}`sec_islocaltoglobalmap`
34*7f296bb3SBarry Smith  - {any}`sec_vecghost`
35*7f296bb3SBarry Smith
36*7f296bb3SBarry Smith- {any}`sec_ao`
37*7f296bb3SBarry Smith
38*7f296bb3SBarry Smith(sec_veccreate)=
39*7f296bb3SBarry Smith
40*7f296bb3SBarry Smith## Creating Vectors
41*7f296bb3SBarry Smith
42*7f296bb3SBarry SmithPETSc provides many ways to create vectors. The most basic, where the user is responsible for managing the
43*7f296bb3SBarry Smithparallel distribution of the vector entries, and a variety of higher-level approaches, based on `DM`, for classes of problems such
44*7f296bb3SBarry Smithas structured grids, staggered grids, unstructured grids, networks, and particles.
45*7f296bb3SBarry Smith
46*7f296bb3SBarry SmithThe most basic way to create a vector with a local size of `m` and a global size of `M`, is to
47*7f296bb3SBarry Smithuse
48*7f296bb3SBarry Smith
49*7f296bb3SBarry Smith```
50*7f296bb3SBarry SmithVecCreate(MPI_Comm comm,Vec *v);
51*7f296bb3SBarry SmithVecSetSizes(Vec v, PetscInt m, PetscInt M);
52*7f296bb3SBarry SmithVecSetFromOptions(Vec v);
53*7f296bb3SBarry Smith```
54*7f296bb3SBarry Smith
55*7f296bb3SBarry Smithwhich automatically generates the appropriate vector type (sequential or
56*7f296bb3SBarry Smithparallel) over all processes in `comm`. The option `-vec_type <type>`
57*7f296bb3SBarry Smithcan be used in conjunction with
58*7f296bb3SBarry Smith`VecSetFromOptions()` to specify the use of a particular type of vector. For example, for NVIDIA GPU CUDA, use `cuda`.
59*7f296bb3SBarry SmithThe GPU-based vectors allow
60*7f296bb3SBarry Smithone to set values on either the CPU or GPU but do their computations on the GPU.
61*7f296bb3SBarry Smith
62*7f296bb3SBarry SmithWe emphasize that all processes in `comm` *must* call the vector
63*7f296bb3SBarry Smithcreation routines since these routines are collective on all
64*7f296bb3SBarry Smithprocesses in the communicator. If you are unfamiliar with MPI
65*7f296bb3SBarry Smithcommunicators, see the discussion in {any}`sec_writing`. In addition, if a sequence of creation routines is
66*7f296bb3SBarry Smithused, they must be called in the same order for each process in the
67*7f296bb3SBarry Smithcommunicator.
68*7f296bb3SBarry Smith
69*7f296bb3SBarry SmithInstead of, or before calling `VecSetFromOptions()`, one can call
70*7f296bb3SBarry Smith
71*7f296bb3SBarry Smith```
72*7f296bb3SBarry SmithVecSetType(Vec v,VecType <VECCUDA, VECHIP, VECKOKKOS etc>)
73*7f296bb3SBarry Smith```
74*7f296bb3SBarry Smith
75*7f296bb3SBarry SmithOne can create vectors whose entries are stored on GPUs using the convenience routine,
76*7f296bb3SBarry Smith
77*7f296bb3SBarry Smith```
78*7f296bb3SBarry SmithVecCreateMPICUDA(MPI_Comm comm,PetscInt m,PetscInt M,Vec *x);
79*7f296bb3SBarry Smith```
80*7f296bb3SBarry Smith
81*7f296bb3SBarry SmithThere are convenience creation routines for almost all vector types; we recommend using the more verbose form because it allows
82*7f296bb3SBarry Smithselecting CPU or GPU simulations at runtime.
83*7f296bb3SBarry Smith
84*7f296bb3SBarry SmithFor applications running in parallel that involve multi-dimensional structured grids, unstructured grids, networks, etc, it is cumbersome for users to explicitly manage the needed local and global sizes of the vectors.
85*7f296bb3SBarry SmithHence, PETSc provides two powerful abstract objects (lower level) `PetscSection` (see {any}`ch_petscsection`) and (higher level) `DM` (see {any}`ch_dmbase`) to help manage the vectors and matrices needed for such applications. Using `DM`, parallel vectors can be created easily with
86*7f296bb3SBarry Smith
87*7f296bb3SBarry Smith```
88*7f296bb3SBarry SmithDMCreateGlobalVector(DM dm,Vec *v)
89*7f296bb3SBarry Smith```
90*7f296bb3SBarry Smith
91*7f296bb3SBarry SmithThe `DM` object, see {any}`sec_struct`, {any}`sec_stag`, and {any}`ch_unstructured` for more details on `DM` for structured grids, staggered
92*7f296bb3SBarry Smithstructured grids, and for unstructured grids,
93*7f296bb3SBarry Smithmanages creating the correctly sized parallel vectors efficiently. One controls the type of vector that `DM` creates by calling
94*7f296bb3SBarry Smith
95*7f296bb3SBarry Smith```
96*7f296bb3SBarry SmithDMSetVecType(DM dm,VecType vt)
97*7f296bb3SBarry Smith```
98*7f296bb3SBarry Smith
99*7f296bb3SBarry Smithor by calling `DMSetFromOptions(DM dm)` and using the option `-dm_vec_type <standard or cuda or kokkos etc>`
100*7f296bb3SBarry Smith
101*7f296bb3SBarry Smith(sec_struct)=
102*7f296bb3SBarry Smith
103*7f296bb3SBarry Smith### DMDA - Creating vectors for structured grids
104*7f296bb3SBarry Smith
105*7f296bb3SBarry SmithEach `DM` type is suitable for a family of problems. The first of these, `DMDA`
106*7f296bb3SBarry Smithare intended for use with *logically structured rectangular grids*
107*7f296bb3SBarry Smithwhen communication of nonlocal data is needed before certain local
108*7f296bb3SBarry Smithcomputations can occur. `DMDA` is designed only for
109*7f296bb3SBarry Smiththe case in which data can be thought of as being stored in a standard
110*7f296bb3SBarry Smithmultidimensional array; thus, `DMDA` are *not* intended for
111*7f296bb3SBarry Smithparallelizing unstructured grid problems, etc.
112*7f296bb3SBarry Smith
113*7f296bb3SBarry SmithFor example, a typical situation one encounters in solving PDEs in
114*7f296bb3SBarry Smithparallel is that, to evaluate a local function, `f(x)`, each process
115*7f296bb3SBarry Smithrequires its local portion of the vector `x` as well as its ghost
116*7f296bb3SBarry Smithpoints (the bordering portions of the vector that are owned by
117*7f296bb3SBarry Smithneighboring processes). Figure {any}`fig_ghosts` illustrates the
118*7f296bb3SBarry Smithghost points for the seventh process of a two-dimensional, structured
119*7f296bb3SBarry Smithparallel grid. Each box represents a process; the ghost points for the
120*7f296bb3SBarry Smithseventh process’s local part of a parallel array are shown in gray.
121*7f296bb3SBarry Smith
122*7f296bb3SBarry Smith:::{figure} /images/manual/ghost.*
123*7f296bb3SBarry Smith:alt: Ghost Points for Two Stencil Types on the Seventh Process
124*7f296bb3SBarry Smith:name: fig_ghosts
125*7f296bb3SBarry Smith
126*7f296bb3SBarry SmithGhost Points for Two Stencil Types on the Seventh Process
127*7f296bb3SBarry Smith:::
128*7f296bb3SBarry Smith
129*7f296bb3SBarry SmithThe `DMDA` object
130*7f296bb3SBarry Smithcontains parallel data layout information and communication
131*7f296bb3SBarry Smithinformation and is used to create vectors and matrices with
132*7f296bb3SBarry Smiththe proper layout.
133*7f296bb3SBarry Smith
134*7f296bb3SBarry SmithOne creates a `DMDA` two
135*7f296bb3SBarry Smithdimensions with the convenience routine
136*7f296bb3SBarry Smith
137*7f296bb3SBarry Smith```
138*7f296bb3SBarry SmithDMDACreate2d(MPI_Comm comm,DMBoundaryType xperiod,DMBoundaryType yperiod,DMDAStencilType st,PetscInt M, PetscInt N,PetscInt m,PetscInt n,PetscInt dof,PetscInt s,PetscInt *lx,PetscInt *ly,DM *da);
139*7f296bb3SBarry Smith```
140*7f296bb3SBarry Smith
141*7f296bb3SBarry SmithThe arguments `M` and `N` indicate the global numbers of grid points
142*7f296bb3SBarry Smithin each direction, while `m` and `n` denote the process partition in
143*7f296bb3SBarry Smitheach direction; `m*n` must equal the number of processes in the MPI
144*7f296bb3SBarry Smithcommunicator, `comm`. Instead of specifying the process layout, one
145*7f296bb3SBarry Smithmay use `PETSC_DECIDE` for `m` and `n` so that PETSc will
146*7f296bb3SBarry Smithselect the partition. The type of periodicity of the array
147*7f296bb3SBarry Smithis specified by `xperiod` and `yperiod`, which can be
148*7f296bb3SBarry Smith`DM_BOUNDARY_NONE` (no periodicity), `DM_BOUNDARY_PERIODIC`
149*7f296bb3SBarry Smith(periodic in that direction), `DM_BOUNDARY_TWIST` (periodic in that
150*7f296bb3SBarry Smithdirection, but identified in reverse order), `DM_BOUNDARY_GHOSTED` ,
151*7f296bb3SBarry Smithor `DM_BOUNDARY_MIRROR`. The argument `dof` indicates the number of
152*7f296bb3SBarry Smithdegrees of freedom at each array point, and `s` is the stencil width
153*7f296bb3SBarry Smith(i.e., the width of the ghost point region). The optional arrays `lx`
154*7f296bb3SBarry Smithand `ly` may contain the number of nodes along the x and y axis for
155*7f296bb3SBarry Smitheach cell, i.e. the dimension of `lx` is `m` and the dimension of
156*7f296bb3SBarry Smith`ly` is `n`; alternately, `NULL` may be passed in.
157*7f296bb3SBarry Smith
158*7f296bb3SBarry SmithTwo types of `DMDA` communication data structures can be
159*7f296bb3SBarry Smithcreated, as specified by `st`. Star-type stencils that radiate outward
160*7f296bb3SBarry Smithonly in the coordinate directions are indicated by
161*7f296bb3SBarry Smith`DMDA_STENCIL_STAR`, while box-type stencils are specified by
162*7f296bb3SBarry Smith`DMDA_STENCIL_BOX`. For example, for the two-dimensional case,
163*7f296bb3SBarry Smith`DMDA_STENCIL_STAR` with width 1 corresponds to the standard 5-point
164*7f296bb3SBarry Smithstencil, while `DMDA_STENCIL_BOX` with width 1 denotes the standard
165*7f296bb3SBarry Smith9-point stencil. In both instances, the ghost points are identical, the
166*7f296bb3SBarry Smithonly difference being that with star-type stencils, certain ghost points
167*7f296bb3SBarry Smithare ignored, substantially decreasing the number of messages sent. Note
168*7f296bb3SBarry Smiththat the `DMDA_STENCIL_STAR` stencils can save interprocess
169*7f296bb3SBarry Smithcommunication in two and three dimensions.
170*7f296bb3SBarry Smith
171*7f296bb3SBarry SmithThese `DMDA` stencils have nothing directly to do with a specific finite
172*7f296bb3SBarry Smithdifference stencil one might choose to use for discretization; they
173*7f296bb3SBarry Smithonly ensure that the correct values are in place for the application of a
174*7f296bb3SBarry Smithuser-defined finite difference stencil (or any other discretization
175*7f296bb3SBarry Smithtechnique).
176*7f296bb3SBarry Smith
177*7f296bb3SBarry SmithThe commands for creating `DMDA`
178*7f296bb3SBarry Smithin one and three dimensions are analogous:
179*7f296bb3SBarry Smith
180*7f296bb3SBarry Smith```
181*7f296bb3SBarry SmithDMDACreate1d(MPI_Comm comm,DMBoundaryType xperiod,PetscInt M,PetscInt w,PetscInt s,PetscInt *lc,DM *inra);
182*7f296bb3SBarry Smith```
183*7f296bb3SBarry Smith
184*7f296bb3SBarry Smith```
185*7f296bb3SBarry SmithDMDACreate3d(MPI_Comm comm,DMBoundaryType xperiod,DMBoundaryType yperiod,DMBoundaryType zperiod, DMDAStencilType stencil_type,PetscInt M,PetscInt N,PetscInt P,PetscInt m,PetscInt n,PetscInt p,PetscInt w,PetscInt s,PetscInt *lx,PetscInt *ly,PetscInt *lz,DM *inra);
186*7f296bb3SBarry Smith```
187*7f296bb3SBarry Smith
188*7f296bb3SBarry SmithThe routines to create a `DM` are collective so that all
189*7f296bb3SBarry Smithprocesses in the communicator `comm` must call the same creation routines in the same order.
190*7f296bb3SBarry Smith
191*7f296bb3SBarry SmithA `DM` may be created, and its type set with
192*7f296bb3SBarry Smith
193*7f296bb3SBarry Smith```
194*7f296bb3SBarry SmithDMCreate(comm,&dm);
195*7f296bb3SBarry SmithDMSetType(dm,"Typename");  // for example, "DMDA"
196*7f296bb3SBarry Smith```
197*7f296bb3SBarry Smith
198*7f296bb3SBarry SmithThen `DMType` specific operations can be performed to provide information from which the specifics of the
199*7f296bb3SBarry Smith`DM` will be provided. For example,
200*7f296bb3SBarry Smith
201*7f296bb3SBarry Smith```
202*7f296bb3SBarry SmithDMSetDimension(dm, 1);
203*7f296bb3SBarry SmithDMDASetSizes(dm, M, 1, 1));
204*7f296bb3SBarry SmithDMDASetDof(dm, 1));
205*7f296bb3SBarry SmithDMSetUp(dm);
206*7f296bb3SBarry Smith```
207*7f296bb3SBarry Smith
208*7f296bb3SBarry SmithWe now very briefly introduce a few more `DMType`.
209*7f296bb3SBarry Smith
210*7f296bb3SBarry Smith(sec_stag)=
211*7f296bb3SBarry Smith
212*7f296bb3SBarry Smith### DMSTAG - Creating vectors for staggered grids
213*7f296bb3SBarry Smith
214*7f296bb3SBarry SmithFor structured grids with staggered data (living on elements, faces, edges,
215*7f296bb3SBarry Smithand/or vertices), the `DMSTAG` object is available. It behaves much
216*7f296bb3SBarry Smithlike `DMDA`.
217*7f296bb3SBarry SmithSee {any}`ch_stag` for discussion of creating vectors with `DMSTAG`.
218*7f296bb3SBarry Smith
219*7f296bb3SBarry Smith(sec_unstruct)=
220*7f296bb3SBarry Smith
221*7f296bb3SBarry Smith### DMPLEX - Creating vectors for unstructured grids
222*7f296bb3SBarry Smith
223*7f296bb3SBarry SmithSee {any}`ch_unstructured` for a discussion of creating vectors with `DMPLEX`.
224*7f296bb3SBarry Smith
225*7f296bb3SBarry Smith(sec_network)=
226*7f296bb3SBarry Smith
227*7f296bb3SBarry Smith### DMNETWORK - Creating vectors for networks
228*7f296bb3SBarry Smith
229*7f296bb3SBarry SmithSee {any}`ch_network` for discussion of creating vectors with `DMNETWORK`.
230*7f296bb3SBarry Smith
231*7f296bb3SBarry Smith## Common vector functions and operations
232*7f296bb3SBarry Smith
233*7f296bb3SBarry SmithOne can examine (print out) a vector with the command
234*7f296bb3SBarry Smith
235*7f296bb3SBarry Smith```
236*7f296bb3SBarry SmithVecView(Vec x,PetscViewer v);
237*7f296bb3SBarry Smith```
238*7f296bb3SBarry Smith
239*7f296bb3SBarry SmithTo print the vector to the screen, one can use the viewer
240*7f296bb3SBarry Smith`PETSC_VIEWER_STDOUT_WORLD`, which ensures that parallel vectors are
241*7f296bb3SBarry Smithprinted correctly to `stdout`. To display the vector in an X-window,
242*7f296bb3SBarry Smithone can use the default X-windows viewer `PETSC_VIEWER_DRAW_WORLD`, or
243*7f296bb3SBarry Smithone can create a viewer with the routine `PetscViewerDrawOpen()`. A
244*7f296bb3SBarry Smithvariety of viewers are discussed further in
245*7f296bb3SBarry Smith{any}`sec_viewers`.
246*7f296bb3SBarry Smith
247*7f296bb3SBarry SmithTo create a new vector of the same format and parallel layout as an existing vector,
248*7f296bb3SBarry Smithuse
249*7f296bb3SBarry Smith
250*7f296bb3SBarry Smith```
251*7f296bb3SBarry SmithVecDuplicate(Vec old,Vec *new);
252*7f296bb3SBarry Smith```
253*7f296bb3SBarry Smith
254*7f296bb3SBarry SmithTo create several new vectors of the same format as an existing vector,
255*7f296bb3SBarry Smithuse
256*7f296bb3SBarry Smith
257*7f296bb3SBarry Smith```
258*7f296bb3SBarry SmithVecDuplicateVecs(Vec old,PetscInt n,Vec **new);
259*7f296bb3SBarry Smith```
260*7f296bb3SBarry Smith
261*7f296bb3SBarry SmithThis routine creates an array of pointers to vectors. The two routines
262*7f296bb3SBarry Smithare useful because they allow one to write library code that does
263*7f296bb3SBarry Smithnot depend on the particular format of the vectors being used. Instead,
264*7f296bb3SBarry Smiththe subroutines can automatically create work vectors based on
265*7f296bb3SBarry Smiththe specified existing vector.
266*7f296bb3SBarry Smith
267*7f296bb3SBarry SmithWhen a vector is no longer needed, it should be destroyed with the
268*7f296bb3SBarry Smithcommand
269*7f296bb3SBarry Smith
270*7f296bb3SBarry Smith```
271*7f296bb3SBarry SmithVecDestroy(Vec *x);
272*7f296bb3SBarry Smith```
273*7f296bb3SBarry Smith
274*7f296bb3SBarry SmithTo destroy an array of vectors, use the command
275*7f296bb3SBarry Smith
276*7f296bb3SBarry Smith```
277*7f296bb3SBarry SmithVecDestroyVecs(PetscInt n,Vec **vecs);
278*7f296bb3SBarry Smith```
279*7f296bb3SBarry Smith
280*7f296bb3SBarry SmithIt is also possible to create vectors that use an array the user provides rather than having PETSc internally allocate the array space. Such
281*7f296bb3SBarry Smithvectors can be created with the routines such as
282*7f296bb3SBarry Smith
283*7f296bb3SBarry Smith```
284*7f296bb3SBarry SmithVecCreateSeqWithArray(PETSC_COMM_SELF,PetscInt bs,PetscInt n,PetscScalar *array,Vec *V);
285*7f296bb3SBarry Smith```
286*7f296bb3SBarry Smith
287*7f296bb3SBarry Smith```
288*7f296bb3SBarry SmithVecCreateMPIWithArray(MPI_Comm comm,PetscInt bs,PetscInt n,PetscInt N,PetscScalar *array,Vec *V);
289*7f296bb3SBarry Smith```
290*7f296bb3SBarry Smith
291*7f296bb3SBarry Smith```
292*7f296bb3SBarry SmithVecCreateMPICUDAWithArray(MPI_Comm comm,PetscInt bs,PetscInt n,PetscInt N,PetscScalar *array,Vec *V);
293*7f296bb3SBarry Smith```
294*7f296bb3SBarry Smith
295*7f296bb3SBarry SmithThe `array` pointer should be a GPU memory location for GPU vectors.
296*7f296bb3SBarry Smith
297*7f296bb3SBarry SmithNote that here, one must provide the value `n`; it cannot be
298*7f296bb3SBarry Smith`PETSC_DECIDE` and the user is responsible for providing enough space
299*7f296bb3SBarry Smithin the array; `n*sizeof(PetscScalar)`.
300*7f296bb3SBarry Smith
301*7f296bb3SBarry Smith## Assembling (putting values in) vectors
302*7f296bb3SBarry Smith
303*7f296bb3SBarry SmithOne can assign a single value to all components of a vector with
304*7f296bb3SBarry Smith
305*7f296bb3SBarry Smith```
306*7f296bb3SBarry SmithVecSet(Vec x,PetscScalar value);
307*7f296bb3SBarry Smith```
308*7f296bb3SBarry Smith
309*7f296bb3SBarry SmithAssigning values to individual vector components is more
310*7f296bb3SBarry Smithcomplicated to make it possible to write efficient parallel
311*7f296bb3SBarry Smithcode. Assigning a set of components on a CPU is a two-step process: one first
312*7f296bb3SBarry Smithcalls
313*7f296bb3SBarry Smith
314*7f296bb3SBarry Smith```
315*7f296bb3SBarry SmithVecSetValues(Vec x,PetscInt n,PetscInt *indices,PetscScalar *values,INSERT_VALUES);
316*7f296bb3SBarry Smith```
317*7f296bb3SBarry Smith
318*7f296bb3SBarry Smithany number of times on any or all of the processes. The argument `n`
319*7f296bb3SBarry Smithgives the number of components being set in this insertion. The integer
320*7f296bb3SBarry Smitharray `indices` contains the *global component indices*, and
321*7f296bb3SBarry Smith`values` is the array of values to be inserted at those global component index locations. Any process can set
322*7f296bb3SBarry Smithany vector components; PETSc ensures that they are automatically
323*7f296bb3SBarry Smithstored in the correct location. Once all of the values have been
324*7f296bb3SBarry Smithinserted with `VecSetValues()`, one must call
325*7f296bb3SBarry Smith
326*7f296bb3SBarry Smith```
327*7f296bb3SBarry SmithVecAssemblyBegin(Vec x);
328*7f296bb3SBarry Smith```
329*7f296bb3SBarry Smith
330*7f296bb3SBarry Smithfollowed by
331*7f296bb3SBarry Smith
332*7f296bb3SBarry Smith```
333*7f296bb3SBarry SmithVecAssemblyEnd(Vec x);
334*7f296bb3SBarry Smith```
335*7f296bb3SBarry Smith
336*7f296bb3SBarry Smithto perform any needed message passing of nonlocal components. In order
337*7f296bb3SBarry Smithto allow the overlap of communication and calculation, the user’s code
338*7f296bb3SBarry Smithcan perform any series of other actions between these two calls while
339*7f296bb3SBarry Smiththe messages are in transition.
340*7f296bb3SBarry Smith
341*7f296bb3SBarry SmithExample usage of `VecSetValues()` may be found in
342*7f296bb3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/vec/vec/tutorials/ex2.c.html">src/vec/vec/tutorials/ex2.c</a>
343*7f296bb3SBarry Smithor <a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/vec/vec/tutorials/ex2f.F90.html">src/vec/vec/tutorials/exf.F90</a>.
344*7f296bb3SBarry Smith
345*7f296bb3SBarry SmithRather than inserting elements in a vector, one may wish to add
346*7f296bb3SBarry Smithvalues. This process is also done with the command
347*7f296bb3SBarry Smith
348*7f296bb3SBarry Smith```
349*7f296bb3SBarry SmithVecSetValues(Vec x,PetscInt n,PetscInt *indices, PetscScalar *values,ADD_VALUES);
350*7f296bb3SBarry Smith```
351*7f296bb3SBarry Smith
352*7f296bb3SBarry SmithAgain, one must call the assembly routines `VecAssemblyBegin()` and
353*7f296bb3SBarry Smith`VecAssemblyEnd()` after all of the values have been added. Note that
354*7f296bb3SBarry Smithaddition and insertion calls to `VecSetValues()` *cannot* be mixed.
355*7f296bb3SBarry SmithInstead, one must add and insert vector elements in phases, with
356*7f296bb3SBarry Smithintervening calls to the assembly routines. This phased assembly
357*7f296bb3SBarry Smithprocedure overcomes the nondeterministic behavior that would occur if
358*7f296bb3SBarry Smithtwo different processes generated values for the same location, with one
359*7f296bb3SBarry Smithprocess adding while the other is inserting its value. (In this case, the
360*7f296bb3SBarry Smithaddition and insertion actions could be performed in either order, thus
361*7f296bb3SBarry Smithresulting in different values at the particular location. Since PETSc
362*7f296bb3SBarry Smithdoes not allow the simultaneous use of `INSERT_VALUES` and
363*7f296bb3SBarry Smith`ADD_VALUES` this nondeterministic behavior will not occur in PETSc.)
364*7f296bb3SBarry Smith
365*7f296bb3SBarry SmithYou can call `VecGetValues()` to pull local values from a vector (but
366*7f296bb3SBarry Smithnot off-process values).
367*7f296bb3SBarry Smith
368*7f296bb3SBarry SmithFor vectors obtained with `DMCreateGlobalVector()`, one can use `VecSetValuesLocal()` to set values into
369*7f296bb3SBarry Smitha global vector but using the local (ghosted) vector indexing of the vector entries. See also {any}`sec_islocaltoglobalmap`
370*7f296bb3SBarry Smiththat allows one to provide arbitrary local-to-global mapping when not working with a `DM`.
371*7f296bb3SBarry Smith
372*7f296bb3SBarry SmithIt is also possible to interact directly with the arrays that the vector values are stored
373*7f296bb3SBarry Smithin. The routine `VecGetArray()` returns a pointer to the elements local to
374*7f296bb3SBarry Smiththe process:
375*7f296bb3SBarry Smith
376*7f296bb3SBarry Smith```
377*7f296bb3SBarry SmithVecGetArray(Vec v,PetscScalar **array);
378*7f296bb3SBarry Smith```
379*7f296bb3SBarry Smith
380*7f296bb3SBarry SmithWhen access to the array is no longer needed, the user should call
381*7f296bb3SBarry Smith
382*7f296bb3SBarry Smith```
383*7f296bb3SBarry SmithVecRestoreArray(Vec v, PetscScalar **array);
384*7f296bb3SBarry Smith```
385*7f296bb3SBarry Smith
386*7f296bb3SBarry SmithIf the values do not need to be modified, the routines
387*7f296bb3SBarry Smith
388*7f296bb3SBarry Smith```
389*7f296bb3SBarry SmithVecGetArrayRead(Vec v, const PetscScalar **array);
390*7f296bb3SBarry SmithVecRestoreArrayRead(Vec v, const PetscScalar **array);
391*7f296bb3SBarry Smith```
392*7f296bb3SBarry Smith
393*7f296bb3SBarry Smithshould be used instead.
394*7f296bb3SBarry Smith
395*7f296bb3SBarry Smith:::{admonition} Listing: <a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tutorials/ex1.c.html">SNES Tutorial src/snes/tutorials/ex1.c</a>
396*7f296bb3SBarry Smith```{literalinclude} /../src/snes/tutorials/ex1.c
397*7f296bb3SBarry Smith:end-at: PetscFunctionReturn(PETSC_SUCCESS);
398*7f296bb3SBarry Smith:name: snesex1
399*7f296bb3SBarry Smith:start-at: PetscErrorCode FormFunction1(SNES snes, Vec x, Vec f, void *ctx)
400*7f296bb3SBarry Smith```
401*7f296bb3SBarry Smith:::
402*7f296bb3SBarry Smith
403*7f296bb3SBarry SmithMinor differences exist in the Fortran interface for `VecGetArray()`
404*7f296bb3SBarry Smithand `VecRestoreArray()`, as discussed in
405*7f296bb3SBarry Smith{any}`sec_fortranarrays`. It is important to note that
406*7f296bb3SBarry Smith`VecGetArray()` and `VecRestoreArray()` do *not* copy the vector
407*7f296bb3SBarry Smithelements; they merely give users direct access to the vector elements.
408*7f296bb3SBarry SmithThus, these routines require essentially no time to call and can be used
409*7f296bb3SBarry Smithefficiently.
410*7f296bb3SBarry Smith
411*7f296bb3SBarry SmithFor GPU vectors, one can access either the values on the CPU as described above or one
412*7f296bb3SBarry Smithcan call, for example,
413*7f296bb3SBarry Smith
414*7f296bb3SBarry Smith```
415*7f296bb3SBarry SmithVecCUDAGetArray(Vec v, PetscScalar **array);
416*7f296bb3SBarry Smith```
417*7f296bb3SBarry Smith
418*7f296bb3SBarry Smith:::{admonition} Listing: <a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tutorials/ex47cu.cu.html">SNES Tutorial src/snes/tutorials/ex47cu.cu</a>
419*7f296bb3SBarry Smith```{literalinclude} /../src/snes/tutorials/ex47cu.cu
420*7f296bb3SBarry Smith:end-at: '}'
421*7f296bb3SBarry Smith:name: snesex47
422*7f296bb3SBarry Smith:start-at: PetscCall(VecCUDAGetArrayRead(xlocal, &xarray));
423*7f296bb3SBarry Smith```
424*7f296bb3SBarry Smith:::
425*7f296bb3SBarry Smith
426*7f296bb3SBarry Smithor
427*7f296bb3SBarry Smith
428*7f296bb3SBarry Smith```
429*7f296bb3SBarry SmithVecGetArrayAndMemType(Vec v, PetscScalar **array,PetscMemType *mtype);
430*7f296bb3SBarry Smith```
431*7f296bb3SBarry Smith
432*7f296bb3SBarry Smithwhich, in the first case, returns a GPU memory address and, in the second case, returns either a CPU or GPU memory
433*7f296bb3SBarry Smithaddress depending on the type of the vector. One can then launch a GPU kernel function that accesses the
434*7f296bb3SBarry Smithvector's memory for usage with GPUs. When computing on GPUs, `VecSetValues()` is not used! One always accesses the vector's arrays and passes them
435*7f296bb3SBarry Smithto the GPU code.
436*7f296bb3SBarry Smith
437*7f296bb3SBarry SmithIt can also be convenient to treat the vector entries as a Kokkos view. One first creates Kokkos vectors and then calls
438*7f296bb3SBarry Smith
439*7f296bb3SBarry Smith```
440*7f296bb3SBarry SmithVecGetKokkosView(Vec v, Kokkos::View<const PetscScalar*,MemorySpace> *kv)
441*7f296bb3SBarry Smith```
442*7f296bb3SBarry Smith
443*7f296bb3SBarry Smithto set or access the vector entries.
444*7f296bb3SBarry Smith
445*7f296bb3SBarry SmithOf course, to provide the correct values to a vector, one must know what parts of the vector are owned by each MPI process.
446*7f296bb3SBarry SmithFor parallel vectors, either CPU or GPU-based, it is possible to determine a process’s local range with the
447*7f296bb3SBarry Smithroutine
448*7f296bb3SBarry Smith
449*7f296bb3SBarry Smith```
450*7f296bb3SBarry SmithVecGetOwnershipRange(Vec vec,PetscInt *start,PetscInt *end);
451*7f296bb3SBarry Smith```
452*7f296bb3SBarry Smith
453*7f296bb3SBarry SmithThe argument `start` indicates the first component owned by the local
454*7f296bb3SBarry Smithprocess, while `end` specifies *one more than* the last owned by the
455*7f296bb3SBarry Smithlocal process. This command is useful, for instance, in assembling
456*7f296bb3SBarry Smithparallel vectors.
457*7f296bb3SBarry Smith
458*7f296bb3SBarry SmithIf the `Vec` was obtained from a `DM` with `DMCreateGlobalVector()`, then the range values are determined by the specific `DM`.
459*7f296bb3SBarry SmithIf the `Vec` was created directly, the range values are determined by the local size passed to `VecSetSizes()` or `VecCreateMPI()`.
460*7f296bb3SBarry SmithIf `PETSC_DECIDE` was passed as the local size, then the vector uses default values for the range using `PetscSplitOwnership()`.
461*7f296bb3SBarry SmithFor certain `DM`, such as `DMDA`, it is better to use `DM` specific routines, such as `DMDAGetGhostCorners()`, to determine
462*7f296bb3SBarry Smiththe local values in the vector.
463*7f296bb3SBarry Smith
464*7f296bb3SBarry SmithVery occasionally, all MPI processes need to know all the range values, these can be obtained with
465*7f296bb3SBarry Smith
466*7f296bb3SBarry Smith```
467*7f296bb3SBarry SmithVecGetOwnershipRanges(Vec vec,PetscInt range[]);
468*7f296bb3SBarry Smith```
469*7f296bb3SBarry Smith
470*7f296bb3SBarry SmithThe number of elements stored locally can be accessed with
471*7f296bb3SBarry Smith
472*7f296bb3SBarry Smith```
473*7f296bb3SBarry SmithVecGetLocalSize(Vec v,PetscInt *size);
474*7f296bb3SBarry Smith```
475*7f296bb3SBarry Smith
476*7f296bb3SBarry SmithThe global vector length can be determined by
477*7f296bb3SBarry Smith
478*7f296bb3SBarry Smith```
479*7f296bb3SBarry SmithVecGetSize(Vec v,PetscInt *size);
480*7f296bb3SBarry Smith```
481*7f296bb3SBarry Smith
482*7f296bb3SBarry Smith(sec_struct_set)=
483*7f296bb3SBarry Smith
484*7f296bb3SBarry Smith### DMDA - Setting vector values
485*7f296bb3SBarry Smith
486*7f296bb3SBarry SmithPETSc provides an easy way to set values into the `DMDA` vectors and
487*7f296bb3SBarry Smithaccess them using the natural grid indexing. This is done with the
488*7f296bb3SBarry Smithroutines
489*7f296bb3SBarry Smith
490*7f296bb3SBarry Smith```
491*7f296bb3SBarry SmithDMDAVecGetArray(DM da,Vec l,void *array);
492*7f296bb3SBarry Smith... use the array indexing it with 1, 2, or 3 dimensions ...
493*7f296bb3SBarry Smith... depending on the dimension of the DMDA ...
494*7f296bb3SBarry SmithDMDAVecRestoreArray(DM da,Vec l,void *array);
495*7f296bb3SBarry SmithDMDAVecGetArrayRead(DM da,Vec l,void *array);
496*7f296bb3SBarry Smith... use the array indexing it with 1, 2, or 3 dimensions ...
497*7f296bb3SBarry Smith... depending on the dimension of the DMDA ...
498*7f296bb3SBarry SmithDMDAVecRestoreArrayRead(DM da,Vec l,void *array);
499*7f296bb3SBarry Smith```
500*7f296bb3SBarry Smith
501*7f296bb3SBarry Smithwhere `array` is a multidimensional C array with the same dimension as `da`, and
502*7f296bb3SBarry Smith
503*7f296bb3SBarry Smith```
504*7f296bb3SBarry SmithDMDAVecGetArrayDOF(DM da,Vec l,void *array);
505*7f296bb3SBarry Smith... use the array indexing it with 2, 3, or 4 dimensions ...
506*7f296bb3SBarry Smith... depending on the dimension of the DMDA ...
507*7f296bb3SBarry SmithDMDAVecRestoreArrayDOF(DM da,Vec l,void *array);
508*7f296bb3SBarry SmithDMDAVecGetArrayDOFRead(DM da,Vec l,void *array);
509*7f296bb3SBarry Smith... use the array indexing it with 2, 3, or 4 dimensions ...
510*7f296bb3SBarry Smith... depending on the dimension of the DMDA ...
511*7f296bb3SBarry SmithDMDAVecRestoreArrayDOFRead(DM da,Vec l,void *array);
512*7f296bb3SBarry Smith```
513*7f296bb3SBarry Smith
514*7f296bb3SBarry Smithwhere `array` is a multidimensional C array with one more dimension than
515*7f296bb3SBarry Smith`da`. The vector `l` can be either a global vector or a local
516*7f296bb3SBarry Smithvector. The `array` is accessed using the usual *global* indexing on
517*7f296bb3SBarry Smiththe entire grid, but the user may *only* refer to this array's local and ghost
518*7f296bb3SBarry Smithentries as all other entries are undefined. For example,
519*7f296bb3SBarry Smithfor a scalar problem in two dimensions, one could use
520*7f296bb3SBarry Smith
521*7f296bb3SBarry Smith```
522*7f296bb3SBarry SmithPetscScalar **f,**u;
523*7f296bb3SBarry Smith...
524*7f296bb3SBarry SmithDMDAVecGetArrayRead(DM da,Vec local,&u);
525*7f296bb3SBarry SmithDMDAVecGetArray(DM da,Vec global,&f);
526*7f296bb3SBarry Smith...
527*7f296bb3SBarry Smith  f[i][j] = u[i][j] - ...
528*7f296bb3SBarry Smith...
529*7f296bb3SBarry SmithDMDAVecRestoreArrayRead(DM da,Vec local,&u);
530*7f296bb3SBarry SmithDMDAVecRestoreArray(DM da,Vec global,&f);
531*7f296bb3SBarry Smith```
532*7f296bb3SBarry Smith
533*7f296bb3SBarry Smith:::{admonition} Listing: <a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tutorials/ex3.c.html">SNES Tutorial src/snes/tutorials/ex3.c</a>
534*7f296bb3SBarry Smith```{literalinclude} /../src/snes/tutorials/ex3.c
535*7f296bb3SBarry Smith:end-at: PetscFunctionReturn(PETSC_SUCCESS);
536*7f296bb3SBarry Smith:name: snesex3
537*7f296bb3SBarry Smith:start-at: PetscErrorCode FormFunction(SNES snes, Vec x, Vec f, void *ctx)
538*7f296bb3SBarry Smith```
539*7f296bb3SBarry Smith:::
540*7f296bb3SBarry Smith
541*7f296bb3SBarry SmithThe recommended approach for multi-component PDEs is to declare a
542*7f296bb3SBarry Smith`struct` representing the fields defined at each node of the grid,
543*7f296bb3SBarry Smithe.g.
544*7f296bb3SBarry Smith
545*7f296bb3SBarry Smith```
546*7f296bb3SBarry Smithtypedef struct {
547*7f296bb3SBarry Smith  PetscScalar u,v,omega,temperature;
548*7f296bb3SBarry Smith} Node;
549*7f296bb3SBarry Smith```
550*7f296bb3SBarry Smith
551*7f296bb3SBarry Smithand write the residual evaluation using
552*7f296bb3SBarry Smith
553*7f296bb3SBarry Smith```
554*7f296bb3SBarry SmithNode **f,**u;
555*7f296bb3SBarry SmithDMDAVecGetArray(DM da,Vec local,&u);
556*7f296bb3SBarry SmithDMDAVecGetArray(DM da,Vec global,&f);
557*7f296bb3SBarry Smith ...
558*7f296bb3SBarry Smith    f[i][j].omega = ...
559*7f296bb3SBarry Smith ...
560*7f296bb3SBarry SmithDMDAVecRestoreArray(DM da,Vec local,&u);
561*7f296bb3SBarry SmithDMDAVecRestoreArray(DM da,Vec global,&f);
562*7f296bb3SBarry Smith```
563*7f296bb3SBarry Smith
564*7f296bb3SBarry SmithThe `DMDAVecGetArray` routines are also provided for GPU access with CUDA, HIP, and Kokkos. For example,
565*7f296bb3SBarry Smith
566*7f296bb3SBarry Smith```
567*7f296bb3SBarry SmithDMDAVecGetKokkosOffsetView(DM da,Vec vec,Kokkos::View<const PetscScalar*XX*,MemorySpace> *ov)
568*7f296bb3SBarry Smith```
569*7f296bb3SBarry Smith
570*7f296bb3SBarry Smithwhere `*XX*` can contain any number of `*`. This allows one to write very natural Kokkos multi-dimensional parallel for kernels
571*7f296bb3SBarry Smiththat act on the local portion of `DMDA` vectors.
572*7f296bb3SBarry Smith
573*7f296bb3SBarry Smith:::{admonition} Listing: <a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tutorials/ex3k.kokkos.cxx.html">SNES Tutorial src/snes/tutorials/ex3k.kokkos.cxx</a>
574*7f296bb3SBarry Smith:name: snes-ex3-kokkos
575*7f296bb3SBarry Smith
576*7f296bb3SBarry Smith```{literalinclude} /../src/snes/tutorials/ex3k.kokkos.cxx
577*7f296bb3SBarry Smith:end-at: PetscFunctionReturn(PETSC_SUCCESS);
578*7f296bb3SBarry Smith:start-at: PetscErrorCode KokkosFunction(SNES snes, Vec x, Vec r, void *ctx)
579*7f296bb3SBarry Smith```
580*7f296bb3SBarry Smith:::
581*7f296bb3SBarry Smith
582*7f296bb3SBarry SmithThe global indices of the lower left corner of the local portion of vectors obtained from `DMDA`
583*7f296bb3SBarry Smithas well as the local array size can be obtained with the commands
584*7f296bb3SBarry Smith
585*7f296bb3SBarry Smith```
586*7f296bb3SBarry SmithDMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p);
587*7f296bb3SBarry SmithDMDAGetGhostCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p);
588*7f296bb3SBarry Smith```
589*7f296bb3SBarry Smith
590*7f296bb3SBarry SmithThese values can then be used as loop bounds for local function evaluations as demonstrated in the function examples above.
591*7f296bb3SBarry Smith
592*7f296bb3SBarry SmithThe first version excludes ghost points, while the second
593*7f296bb3SBarry Smithincludes them. The routine `DMDAGetGhostCorners()` deals with the fact
594*7f296bb3SBarry Smiththat subarrays along boundaries of the problem domain have ghost points
595*7f296bb3SBarry Smithonly on their interior edges, but not on their boundary edges.
596*7f296bb3SBarry Smith
597*7f296bb3SBarry SmithWhen either type of stencil is used, `DMDA_STENCIL_STAR` or
598*7f296bb3SBarry Smith`DMDA_STENCIL_BOX`, the local vectors (with the ghost points)
599*7f296bb3SBarry Smithrepresent rectangular arrays, including the extra corner elements in the
600*7f296bb3SBarry Smith`DMDA_STENCIL_STAR` case. This configuration provides simple access to
601*7f296bb3SBarry Smiththe elements by employing two- (or three--) dimensional indexing. The
602*7f296bb3SBarry Smithonly difference between the two cases is that when `DMDA_STENCIL_STAR`
603*7f296bb3SBarry Smithis used, the extra corner components are *not* scattered between the
604*7f296bb3SBarry Smithprocesses and thus contain undefined values that should *not* be used.
605*7f296bb3SBarry Smith
606*7f296bb3SBarry Smith(sec_stag_set)=
607*7f296bb3SBarry Smith
608*7f296bb3SBarry Smith### DMSTAG - Setting vector values
609*7f296bb3SBarry Smith
610*7f296bb3SBarry SmithFor structured grids with staggered data (living on elements, faces, edges,
611*7f296bb3SBarry Smithand/or vertices), the `DMStag` object is available. It behaves
612*7f296bb3SBarry Smithlike `DMDA`; see the `DMSTAG` manual page for more information.
613*7f296bb3SBarry Smith
614*7f296bb3SBarry Smith:::{admonition} Listing: <a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/dm/impls/stag/tutorials/ex6.c.html">SNES Tutorial src/dm/impls/stag/tutorials/ex6.c</a>
615*7f296bb3SBarry Smith```{literalinclude} /../src/dm/impls/stag/tutorials/ex6.c
616*7f296bb3SBarry Smith:end-at: /* Update x-velocity */
617*7f296bb3SBarry Smith:name: stagex6
618*7f296bb3SBarry Smith:start-at: static PetscErrorCode UpdateVelocity_2d(const Ctx *ctx, Vec velocity, Vec
619*7f296bb3SBarry Smith:  stress, Vec buoyancy)
620*7f296bb3SBarry Smith```
621*7f296bb3SBarry Smith:::
622*7f296bb3SBarry Smith
623*7f296bb3SBarry Smith(sec_unstruct_set)=
624*7f296bb3SBarry Smith
625*7f296bb3SBarry Smith### DMPLEX - Setting vector values
626*7f296bb3SBarry Smith
627*7f296bb3SBarry SmithSee {any}`ch_unstructured` for a discussion on setting vector values with `DMPLEX`.
628*7f296bb3SBarry Smith
629*7f296bb3SBarry Smith(sec_network_set)=
630*7f296bb3SBarry Smith
631*7f296bb3SBarry Smith### DMNETWORK - Setting vector values
632*7f296bb3SBarry Smith
633*7f296bb3SBarry SmithSee {any}`ch_network` for a discussion on setting vector values with `DMNETWORK`.
634*7f296bb3SBarry Smith
635*7f296bb3SBarry Smith(sec_vecbasic)=
636*7f296bb3SBarry Smith
637*7f296bb3SBarry Smith## Basic Vector Operations
638*7f296bb3SBarry Smith
639*7f296bb3SBarry Smith% Should make the table more attractive by using, for example, cloud_sptheme.ext.table_styling and the lines below
640*7f296bb3SBarry Smith% :column-alignment: left left
641*7f296bb3SBarry Smith% :widths: 72 28
642*7f296bb3SBarry Smith
643*7f296bb3SBarry Smith:::{container}
644*7f296bb3SBarry Smith:name: fig_vectorops
645*7f296bb3SBarry Smith
646*7f296bb3SBarry Smith```{eval-rst}
647*7f296bb3SBarry Smith.. table:: PETSc Vector Operations
648*7f296bb3SBarry Smith
649*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
650*7f296bb3SBarry Smith   | **Function Name**                                         | **Operation**                     |
651*7f296bb3SBarry Smith   +===========================================================+===================================+
652*7f296bb3SBarry Smith   | ``VecAXPY(Vec y,PetscScalar a,Vec x);``                   | :math:`y = y + a*x`               |
653*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
654*7f296bb3SBarry Smith   | ``VecAYPX(Vec y,PetscScalar a,Vec x);``                   | :math:`y = x + a*y`               |
655*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
656*7f296bb3SBarry Smith   | ``VecWAXPY(Vec  w,PetscScalar a,Vec x,Vec y);``           | :math:`w = a*x + y`               |
657*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
658*7f296bb3SBarry Smith   | ``VecAXPBY(Vec y,PetscScalar a,PetscScalar b,Vec x);``    | :math:`y = a*x + b*y`             |
659*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
660*7f296bb3SBarry Smith   | ``VecAXPBYPCZ(Vec z,PetscScalar a,PetscScalar b,          | :math:`z = a*x + b*y + c*z`       |
661*7f296bb3SBarry Smith   | PetscScalar c,Vec x,Vec y);``                             |                                   |
662*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
663*7f296bb3SBarry Smith   | ``VecScale(Vec x, PetscScalar a);``                       | :math:`x = a*x`                   |
664*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
665*7f296bb3SBarry Smith   | ``VecDot(Vec x, Vec y, PetscScalar *r);``                 | :math:`r = \bar{x}^T*y`           |
666*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
667*7f296bb3SBarry Smith   | ``VecTDot(Vec x, Vec y, PetscScalar *r);``                | :math:`r = x'*y`                  |
668*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
669*7f296bb3SBarry Smith   | ``VecNorm(Vec x, NormType type,  PetscReal *r);``         | :math:`r = ||x||_{type}`          |
670*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
671*7f296bb3SBarry Smith   | ``VecSum(Vec x, PetscScalar *r);``                        | :math:`r = \sum x_{i}`            |
672*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
673*7f296bb3SBarry Smith   | ``VecCopy(Vec x, Vec y);``                                | :math:`y = x`                     |
674*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
675*7f296bb3SBarry Smith   | ``VecSwap(Vec x, Vec y);``                                | :math:`y = x` while               |
676*7f296bb3SBarry Smith   |                                                           | :math:`x = y`                     |
677*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
678*7f296bb3SBarry Smith   | ``VecPointwiseMult(Vec w,Vec x,Vec y);``                  | :math:`w_{i} = x_{i}*y_{i}`       |
679*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
680*7f296bb3SBarry Smith   | ``VecPointwiseDivide(Vec w,Vec x,Vec y);``                | :math:`w_{i} = x_{i}/y_{i}`       |
681*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
682*7f296bb3SBarry Smith   | ``VecMDot(Vec x,PetscInt n,Vec y[],PetscScalar *r);``     | :math:`r[i] = \bar{x}^T*y[i]`     |
683*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
684*7f296bb3SBarry Smith   | ``VecMTDot(Vec x,PetscInt n,Vec y[],PetscScalar *r);``    | :math:`r[i] = x^T*y[i]`           |
685*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
686*7f296bb3SBarry Smith   | ``VecMAXPY(Vec y,PetscInt n, PetscScalar *a, Vec x[]);``  | :math:`y = y + \sum_i a_{i}*x[i]` |
687*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
688*7f296bb3SBarry Smith   | ``VecMax(Vec x, PetscInt *idx, PetscReal *r);``           | :math:`r = \max x_{i}`            |
689*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
690*7f296bb3SBarry Smith   | ``VecMin(Vec x, PetscInt *idx, PetscReal *r);``           | :math:`r = \min x_{i}`            |
691*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
692*7f296bb3SBarry Smith   | ``VecAbs(Vec x);``                                        | :math:`x_i = |x_{i}|`             |
693*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
694*7f296bb3SBarry Smith   | ``VecReciprocal(Vec x);``                                 | :math:`x_i = 1/x_{i}`             |
695*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
696*7f296bb3SBarry Smith   | ``VecShift(Vec x,PetscScalar s);``                        | :math:`x_i = s + x_{i}`           |
697*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
698*7f296bb3SBarry Smith   | ``VecSet(Vec x,PetscScalar alpha);``                      | :math:`x_i = \alpha`              |
699*7f296bb3SBarry Smith   +-----------------------------------------------------------+-----------------------------------+
700*7f296bb3SBarry Smith```
701*7f296bb3SBarry Smith:::
702*7f296bb3SBarry Smith
703*7f296bb3SBarry SmithAs the table lists, we have chosen certain
704*7f296bb3SBarry Smithbasic vector operations to support within the PETSc vector library.
705*7f296bb3SBarry SmithThese operations were selected because they often arise in application
706*7f296bb3SBarry Smithcodes. The `NormType` argument to `VecNorm()` is one of `NORM_1`,
707*7f296bb3SBarry Smith`NORM_2`, or `NORM_INFINITY`. The 1-norm is $\sum_i |x_{i}|$,
708*7f296bb3SBarry Smiththe 2-norm is $( \sum_{i} x_{i}^{2})^{1/2}$ and the infinity norm
709*7f296bb3SBarry Smithis $\max_{i} |x_{i}|$.
710*7f296bb3SBarry Smith
711*7f296bb3SBarry SmithIn addition to `VecDot()` and `VecMDot()` and `VecNorm()`, PETSc
712*7f296bb3SBarry Smithprovides split phase versions of this functionality that allow several independent
713*7f296bb3SBarry Smithinner products and/or norms to share the same communication (thus
714*7f296bb3SBarry Smithimproving parallel efficiency). For example, one may have code such as
715*7f296bb3SBarry Smith
716*7f296bb3SBarry Smith```
717*7f296bb3SBarry SmithVecDot(Vec x,Vec y,PetscScalar *dot);
718*7f296bb3SBarry SmithVecMDot(Vec x,PetscInt nv, Vec y[],PetscScalar *dot);
719*7f296bb3SBarry SmithVecNorm(Vec x,NormType NORM_2,PetscReal *norm2);
720*7f296bb3SBarry SmithVecNorm(Vec x,NormType NORM_1,PetscReal *norm1);
721*7f296bb3SBarry Smith```
722*7f296bb3SBarry Smith
723*7f296bb3SBarry SmithThis code works fine, but it performs four separate parallel
724*7f296bb3SBarry Smithcommunication operations. Instead, one can write
725*7f296bb3SBarry Smith
726*7f296bb3SBarry Smith```
727*7f296bb3SBarry SmithVecDotBegin(Vec x,Vec y,PetscScalar *dot);
728*7f296bb3SBarry SmithVecMDotBegin(Vec x, PetscInt nv,Vec y[],PetscScalar *dot);
729*7f296bb3SBarry SmithVecNormBegin(Vec x,NormType NORM_2,PetscReal *norm2);
730*7f296bb3SBarry SmithVecNormBegin(Vec x,NormType NORM_1,PetscReal *norm1);
731*7f296bb3SBarry SmithVecDotEnd(Vec x,Vec y,PetscScalar *dot);
732*7f296bb3SBarry SmithVecMDotEnd(Vec x, PetscInt nv,Vec y[],PetscScalar *dot);
733*7f296bb3SBarry SmithVecNormEnd(Vec x,NormType NORM_2,PetscReal *norm2);
734*7f296bb3SBarry SmithVecNormEnd(Vec x,NormType NORM_1,PetscReal *norm1);
735*7f296bb3SBarry Smith```
736*7f296bb3SBarry Smith
737*7f296bb3SBarry SmithWith this code, the communication is delayed until the first call to
738*7f296bb3SBarry Smith`VecxxxEnd()` at which a single MPI reduction is used to communicate
739*7f296bb3SBarry Smithall the values. It is required that the calls to the
740*7f296bb3SBarry Smith`VecxxxEnd()` are performed in the same order as the calls to the
741*7f296bb3SBarry Smith`VecxxxBegin()`; however, if you mistakenly make the calls in the
742*7f296bb3SBarry Smithwrong order, PETSc will generate an error informing you of this. There
743*7f296bb3SBarry Smithare additional routines `VecTDotBegin()` and `VecTDotEnd()`,
744*7f296bb3SBarry Smith`VecMTDotBegin()`, `VecMTDotEnd()`.
745*7f296bb3SBarry Smith
746*7f296bb3SBarry SmithFor GPU vectors (like CUDA), the numerical computations will, by default, run on the GPU. Any
747*7f296bb3SBarry Smithscalar output, like the result of a `VecDot()` are placed in CPU memory.
748*7f296bb3SBarry Smith
749*7f296bb3SBarry Smith(sec_localglobal)=
750*7f296bb3SBarry Smith
751*7f296bb3SBarry Smith## Local/global vectors and communicating between vectors
752*7f296bb3SBarry Smith
753*7f296bb3SBarry SmithMany PDE problems require ghost (or halo) values in each MPI process or even more general parallel communication
754*7f296bb3SBarry Smithof vector values. These values are needed
755*7f296bb3SBarry Smithto perform function evaluation on that MPI process. The exact structure of the ghost values needed
756*7f296bb3SBarry Smithdepends on the type of grid being used. `DM` provides a uniform API for communicating the needed
757*7f296bb3SBarry Smithvalues. We introduce the concept in detail for `DMDA`.
758*7f296bb3SBarry Smith
759*7f296bb3SBarry SmithEach `DM` object defines the layout of two vectors: a distributed
760*7f296bb3SBarry Smithglobal vector and a local vector that includes room for the appropriate
761*7f296bb3SBarry Smithghost points. The `DM` object provides information about the size
762*7f296bb3SBarry Smithand layout of these vectors. The user can create
763*7f296bb3SBarry Smithvector objects that use the `DM` layout information with the
764*7f296bb3SBarry Smithroutines
765*7f296bb3SBarry Smith
766*7f296bb3SBarry Smith```
767*7f296bb3SBarry SmithDMCreateGlobalVector(DM da,Vec *g);
768*7f296bb3SBarry SmithDMCreateLocalVector(DM da,Vec *l);
769*7f296bb3SBarry Smith```
770*7f296bb3SBarry Smith
771*7f296bb3SBarry SmithThese vectors will generally serve as the building blocks for local and
772*7f296bb3SBarry Smithglobal PDE solutions, etc. If additional vectors with such layout
773*7f296bb3SBarry Smithinformation are needed in a code, they can be obtained by duplicating
774*7f296bb3SBarry Smith`l` or `g` via `VecDuplicate()` or `VecDuplicateVecs()`.
775*7f296bb3SBarry Smith
776*7f296bb3SBarry SmithWe emphasize that a `DM` provides the information needed to
777*7f296bb3SBarry Smithcommunicate the ghost value information between processes. In most
778*7f296bb3SBarry Smithcases, several different vectors can share the same communication
779*7f296bb3SBarry Smithinformation (or, in other words, can share a given `DM`). The design
780*7f296bb3SBarry Smithof the `DM` object makes this easy, as each `DM` operation may
781*7f296bb3SBarry Smithoperate on vectors of the appropriate size, as obtained via
782*7f296bb3SBarry Smith`DMCreateLocalVector()` and `DMCreateGlobalVector()` or as produced
783*7f296bb3SBarry Smithby `VecDuplicate()`.
784*7f296bb3SBarry Smith
785*7f296bb3SBarry SmithAt certain stages of many applications, there is a need to work on a
786*7f296bb3SBarry Smithlocal portion of the vector that includes the ghost points. This may be
787*7f296bb3SBarry Smithdone by scattering a global vector into its local parts by using the
788*7f296bb3SBarry Smithtwo-stage commands
789*7f296bb3SBarry Smith
790*7f296bb3SBarry Smith```
791*7f296bb3SBarry SmithDMGlobalToLocalBegin(DM da,Vec g,InsertMode iora,Vec l);
792*7f296bb3SBarry SmithDMGlobalToLocalEnd(DM da,Vec g,InsertMode iora,Vec l);
793*7f296bb3SBarry Smith```
794*7f296bb3SBarry Smith
795*7f296bb3SBarry Smithwhich allows the overlap of communication and computation. Since the
796*7f296bb3SBarry Smithglobal and local vectors, given by `g` and `l`, respectively, must
797*7f296bb3SBarry Smithbe compatible with the `DM`, `da`, they should be
798*7f296bb3SBarry Smithgenerated by `DMCreateGlobalVector()` and `DMCreateLocalVector()`
799*7f296bb3SBarry Smith(or be duplicates of such a vector obtained via `VecDuplicate()`). The
800*7f296bb3SBarry Smith`InsertMode` can be `ADD_VALUES` or `INSERT_VALUES` among other possible values.
801*7f296bb3SBarry Smith
802*7f296bb3SBarry SmithOne can scatter the local vectors into the distributed global vector with the
803*7f296bb3SBarry Smithcommand
804*7f296bb3SBarry Smith
805*7f296bb3SBarry Smith```
806*7f296bb3SBarry SmithDMLocalToGlobal(DM da,Vec l,InsertMode mode,Vec g);
807*7f296bb3SBarry Smith```
808*7f296bb3SBarry Smith
809*7f296bb3SBarry Smithor the commands
810*7f296bb3SBarry Smith
811*7f296bb3SBarry Smith```
812*7f296bb3SBarry SmithDMLocalToGlobalBegin(DM da,Vec l,InsertMode mode,Vec g);
813*7f296bb3SBarry Smith/* (Computation to overlap with communication) */
814*7f296bb3SBarry SmithDMLocalToGlobalEnd(DM da,Vec l,InsertMode mode,Vec g);
815*7f296bb3SBarry Smith```
816*7f296bb3SBarry Smith
817*7f296bb3SBarry SmithIn general this is used with an `InsertMode` of `ADD_VALUES`,
818*7f296bb3SBarry Smithbecause if one wishes to insert values into the global vector, they
819*7f296bb3SBarry Smithshould access the global vector directly and put in the values.
820*7f296bb3SBarry Smith
821*7f296bb3SBarry SmithA third type of `DM` scatter is from a local vector
822*7f296bb3SBarry Smith(including ghost points that contain irrelevant values) to a local
823*7f296bb3SBarry Smithvector with correct ghost point values. This scatter may be done with
824*7f296bb3SBarry Smiththe commands
825*7f296bb3SBarry Smith
826*7f296bb3SBarry Smith```
827*7f296bb3SBarry SmithDMLocalToLocalBegin(DM da,Vec l1,InsertMode iora,Vec l2);
828*7f296bb3SBarry SmithDMLocalToLocalEnd(DM da,Vec l1,InsertMode iora,Vec l2);
829*7f296bb3SBarry Smith```
830*7f296bb3SBarry Smith
831*7f296bb3SBarry SmithSince both local vectors, `l1` and `l2`, must be compatible with `da`, they should be generated by
832*7f296bb3SBarry Smith`DMCreateLocalVector()` (or be duplicates of such vectors obtained via
833*7f296bb3SBarry Smith`VecDuplicate()`). The `InsertMode` can be either `ADD_VALUES` or
834*7f296bb3SBarry Smith`INSERT_VALUES`.
835*7f296bb3SBarry Smith
836*7f296bb3SBarry SmithIn most applications, the local ghosted vectors are only needed temporarily during
837*7f296bb3SBarry Smithuser “function evaluations”. PETSc provides an easy, light-weight
838*7f296bb3SBarry Smith(requiring essentially no CPU time) way to temporarily obtain these work vectors and
839*7f296bb3SBarry Smithreturn them when no longer needed. This is done with the
840*7f296bb3SBarry Smithroutines
841*7f296bb3SBarry Smith
842*7f296bb3SBarry Smith```
843*7f296bb3SBarry SmithDMGetLocalVector(DM da,Vec *l);
844*7f296bb3SBarry Smith... use the local vector l ...
845*7f296bb3SBarry SmithDMRestoreLocalVector(DM da,Vec *l);
846*7f296bb3SBarry Smith```
847*7f296bb3SBarry Smith
848*7f296bb3SBarry Smith(sec_scatter)=
849*7f296bb3SBarry Smith
850*7f296bb3SBarry Smith## Low-level Vector Communication
851*7f296bb3SBarry Smith
852*7f296bb3SBarry SmithMost users of PETSc who can utilize a `DM` will not need to utilize the lower-level routines discussed in the rest of this section
853*7f296bb3SBarry Smithand should skip ahead to {any}`ch_matrices`.
854*7f296bb3SBarry Smith
855*7f296bb3SBarry SmithTo facilitate creating general vector scatters and gathers used, for example, in
856*7f296bb3SBarry Smithupdating ghost points for problems for which no `DM` currently exists
857*7f296bb3SBarry SmithPETSc employs the concept of an *index set*, via the `IS` class. An
858*7f296bb3SBarry Smithindex set, a generalization of a set of integer indices, is
859*7f296bb3SBarry Smithused to define scatters, gathers, and similar operations on vectors and
860*7f296bb3SBarry Smithmatrices. Much of the underlying code that implements `DMGlobalToLocal` communication is built
861*7f296bb3SBarry Smithon the infrastructure discussed below.
862*7f296bb3SBarry Smith
863*7f296bb3SBarry SmithThe following command creates an index set based on a list of integers:
864*7f296bb3SBarry Smith
865*7f296bb3SBarry Smith```
866*7f296bb3SBarry SmithISCreateGeneral(MPI_Comm comm,PetscInt n,PetscInt *indices,PetscCopyMode mode, IS *is);
867*7f296bb3SBarry Smith```
868*7f296bb3SBarry Smith
869*7f296bb3SBarry SmithWhen `mode` is `PETSC_COPY_VALUES`, this routine copies the `n`
870*7f296bb3SBarry Smithindices passed to it by the integer array `indices`. Thus, the user
871*7f296bb3SBarry Smithshould be sure to free the integer array `indices` when it is no
872*7f296bb3SBarry Smithlonger needed, perhaps directly after the call to `ISCreateGeneral()`.
873*7f296bb3SBarry SmithThe communicator, `comm`, should include all processes
874*7f296bb3SBarry Smithusing the `IS`.
875*7f296bb3SBarry Smith
876*7f296bb3SBarry SmithAnother standard index set is defined by a starting point (`first`)
877*7f296bb3SBarry Smithand a stride (`step`), and can be created with the command
878*7f296bb3SBarry Smith
879*7f296bb3SBarry Smith```
880*7f296bb3SBarry SmithISCreateStride(MPI_Comm comm,PetscInt n,PetscInt first,PetscInt step,IS *is);
881*7f296bb3SBarry Smith```
882*7f296bb3SBarry Smith
883*7f296bb3SBarry SmithThe meaning of `n`, `first`, and `step` correspond to the MATLAB notation
884*7f296bb3SBarry Smith`first:step:first+n*step`.
885*7f296bb3SBarry Smith
886*7f296bb3SBarry SmithIndex sets can be destroyed with the command
887*7f296bb3SBarry Smith
888*7f296bb3SBarry Smith```
889*7f296bb3SBarry SmithISDestroy(IS &is);
890*7f296bb3SBarry Smith```
891*7f296bb3SBarry Smith
892*7f296bb3SBarry SmithOn rare occasions, the user may need to access information directly from
893*7f296bb3SBarry Smithan index set. Several commands assist in this process:
894*7f296bb3SBarry Smith
895*7f296bb3SBarry Smith```
896*7f296bb3SBarry SmithISGetSize(IS is,PetscInt *size);
897*7f296bb3SBarry SmithISStrideGetInfo(IS is,PetscInt *first,PetscInt *stride);
898*7f296bb3SBarry SmithISGetIndices(IS is,PetscInt **indices);
899*7f296bb3SBarry Smith```
900*7f296bb3SBarry Smith
901*7f296bb3SBarry SmithThe function `ISGetIndices()` returns a pointer to a list of the
902*7f296bb3SBarry Smithindices in the index set. For certain index sets, this may be a
903*7f296bb3SBarry Smithtemporary array of indices created specifically for the call.
904*7f296bb3SBarry SmithThus, once the user finishes using the array of indices, the routine
905*7f296bb3SBarry Smith
906*7f296bb3SBarry Smith```
907*7f296bb3SBarry SmithISRestoreIndices(IS is, PetscInt **indices);
908*7f296bb3SBarry Smith```
909*7f296bb3SBarry Smith
910*7f296bb3SBarry Smithshould be called to ensure that the system can free the space it may
911*7f296bb3SBarry Smithhave used to generate the list of indices.
912*7f296bb3SBarry Smith
913*7f296bb3SBarry SmithA blocked version of index sets can be created with the command
914*7f296bb3SBarry Smith
915*7f296bb3SBarry Smith```
916*7f296bb3SBarry SmithISCreateBlock(MPI_Comm comm,PetscInt bs,PetscInt n,PetscInt *indices,PetscCopyMode mode, IS *is);
917*7f296bb3SBarry Smith```
918*7f296bb3SBarry Smith
919*7f296bb3SBarry SmithThis version is used for defining operations in which each element of
920*7f296bb3SBarry Smiththe index set refers to a block of `bs` vector entries. Related
921*7f296bb3SBarry Smithroutines analogous to those described above exist as well, including
922*7f296bb3SBarry Smith`ISBlockGetIndices()`, `ISBlockGetSize()`,
923*7f296bb3SBarry Smith`ISBlockGetLocalSize()`, `ISGetBlockSize()`.
924*7f296bb3SBarry Smith
925*7f296bb3SBarry SmithMost PETSc applications use a particular `DM` object to manage the communication details needed for their grids.
926*7f296bb3SBarry SmithIn some rare cases, however, codes need to directly set up their required communication patterns. This is done using
927*7f296bb3SBarry SmithPETSc's `VecScatter` and `PetscSF` (for more general data than vectors). One
928*7f296bb3SBarry Smithcan select any subset of the components of a vector to insert or add to
929*7f296bb3SBarry Smithany subset of the components of another vector. We refer to these
930*7f296bb3SBarry Smithoperations as *generalized scatters*, though they are a
931*7f296bb3SBarry Smithcombination of scatters and gathers.
932*7f296bb3SBarry Smith
933*7f296bb3SBarry SmithTo copy selected components from one vector to another, one uses the
934*7f296bb3SBarry Smithfollowing set of commands:
935*7f296bb3SBarry Smith
936*7f296bb3SBarry Smith```
937*7f296bb3SBarry SmithVecScatterCreate(Vec x,IS ix,Vec y,IS iy,VecScatter *ctx);
938*7f296bb3SBarry SmithVecScatterBegin(VecScatter ctx,Vec x,Vec y,INSERT_VALUES,SCATTER_FORWARD);
939*7f296bb3SBarry SmithVecScatterEnd(VecScatter ctx,Vec x,Vec y,INSERT_VALUES,SCATTER_FORWARD);
940*7f296bb3SBarry SmithVecScatterDestroy(VecScatter *ctx);
941*7f296bb3SBarry Smith```
942*7f296bb3SBarry Smith
943*7f296bb3SBarry SmithHere `ix` denotes the index set of the first vector, while `iy`
944*7f296bb3SBarry Smithindicates the index set of the destination vector. The vectors can be
945*7f296bb3SBarry Smithparallel or sequential. The only requirements are that the number of
946*7f296bb3SBarry Smithentries in the index set of the first vector, `ix`, equals the number
947*7f296bb3SBarry Smithin the destination index set, `iy`, and that the vectors be long
948*7f296bb3SBarry Smithenough to contain all the indices referred to in the index sets. If both
949*7f296bb3SBarry Smith`x` and `y` are parallel, their communicator must have the same set
950*7f296bb3SBarry Smithof processes, but their process order can differ. The argument
951*7f296bb3SBarry Smith`INSERT_VALUES` specifies that the vector elements will be inserted
952*7f296bb3SBarry Smithinto the specified locations of the destination vector, overwriting any
953*7f296bb3SBarry Smithexisting values. To add the components, rather than insert them, the
954*7f296bb3SBarry Smithuser should select the option `ADD_VALUES` instead of
955*7f296bb3SBarry Smith`INSERT_VALUES`. One can also use `MAX_VALUES` or `MIN_VALUES` to
956*7f296bb3SBarry Smithreplace the destination with the maximal or minimal of its current value and
957*7f296bb3SBarry Smiththe scattered values.
958*7f296bb3SBarry Smith
959*7f296bb3SBarry SmithTo perform a conventional gather operation, the user makes the
960*7f296bb3SBarry Smithdestination index set, `iy`, be a stride index set with a stride of
961*7f296bb3SBarry Smithone. Similarly, a conventional scatter can be done with an initial
962*7f296bb3SBarry Smith(sending) index set consisting of a stride. The scatter routines are
963*7f296bb3SBarry Smithcollective operations (i.e. all processes that own a parallel vector
964*7f296bb3SBarry Smith*must* call the scatter routines). When scattering from a parallel
965*7f296bb3SBarry Smithvector to sequential vectors, each process has its own sequential vector
966*7f296bb3SBarry Smiththat receives values from locations as indicated in its own index set.
967*7f296bb3SBarry SmithSimilarly, in scattering from sequential vectors to a parallel vector,
968*7f296bb3SBarry Smitheach process has its own sequential vector that contributes to
969*7f296bb3SBarry Smiththe parallel vector.
970*7f296bb3SBarry Smith
971*7f296bb3SBarry Smith*Caution*: When `INSERT_VALUES` is used, if two different processes
972*7f296bb3SBarry Smithcontribute different values to the same component in a parallel vector,
973*7f296bb3SBarry Smitheither value may be inserted. When `ADD_VALUES` is used, the
974*7f296bb3SBarry Smithcorrect sum is added to the correct location.
975*7f296bb3SBarry Smith
976*7f296bb3SBarry SmithIn some cases, one may wish to “undo” a scatter, that is, perform the
977*7f296bb3SBarry Smithscatter backward, switching the roles of the sender and receiver. This
978*7f296bb3SBarry Smithis done by using
979*7f296bb3SBarry Smith
980*7f296bb3SBarry Smith```
981*7f296bb3SBarry SmithVecScatterBegin(VecScatter ctx,Vec y,Vec x,INSERT_VALUES,SCATTER_REVERSE);
982*7f296bb3SBarry SmithVecScatterEnd(VecScatter ctx,Vec y,Vec x,INSERT_VALUES,SCATTER_REVERSE);
983*7f296bb3SBarry Smith```
984*7f296bb3SBarry Smith
985*7f296bb3SBarry SmithNote that the roles of the first two arguments to these routines must be
986*7f296bb3SBarry Smithswapped whenever the `SCATTER_REVERSE` option is used.
987*7f296bb3SBarry Smith
988*7f296bb3SBarry SmithOnce a `VecScatter` object has been created, it may be used with any
989*7f296bb3SBarry Smithvectors that have the same parallel data layout. That is, one can
990*7f296bb3SBarry Smithcall `VecScatterBegin()` and `VecScatterEnd()` with different
991*7f296bb3SBarry Smithvectors than used in the call to `VecScatterCreate()` as long as they
992*7f296bb3SBarry Smithhave the same parallel layout (the number of elements on each process are
993*7f296bb3SBarry Smiththe same). Usually, these “different” vectors would have been obtained
994*7f296bb3SBarry Smithvia calls to `VecDuplicate()` from the original vectors used in the
995*7f296bb3SBarry Smithcall to `VecScatterCreate()`.
996*7f296bb3SBarry Smith
997*7f296bb3SBarry Smith`VecGetValues()` can only access
998*7f296bb3SBarry Smithlocal values from the vector. To get off-process values, the user should
999*7f296bb3SBarry Smithcreate a new vector where the components will be stored and then
1000*7f296bb3SBarry Smithperform the appropriate vector scatter. For example, if one desires to
1001*7f296bb3SBarry Smithobtain the values of the 100th and 200th entries of a parallel vector,
1002*7f296bb3SBarry Smith`p`, one could use a code such as that below. In this example, the
1003*7f296bb3SBarry Smithvalues of the 100th and 200th components are placed in the array values.
1004*7f296bb3SBarry SmithIn this example, each process now has the 100th and 200th component, but
1005*7f296bb3SBarry Smithobviously, each process could gather any elements it needed, or none by
1006*7f296bb3SBarry Smithcreating an index set with no entries.
1007*7f296bb3SBarry Smith
1008*7f296bb3SBarry Smith```
1009*7f296bb3SBarry SmithVec         p, x;         /* initial vector, destination vector */
1010*7f296bb3SBarry SmithVecScatter  scatter;      /* scatter context */
1011*7f296bb3SBarry SmithIS          from, to;     /* index sets that define the scatter */
1012*7f296bb3SBarry SmithPetscScalar *values;
1013*7f296bb3SBarry SmithPetscInt    idx_from[] = {100,200}, idx_to[] = {0,1};
1014*7f296bb3SBarry Smith
1015*7f296bb3SBarry SmithVecCreateSeq(PETSC_COMM_SELF,2,&x);
1016*7f296bb3SBarry SmithISCreateGeneral(PETSC_COMM_SELF,2,idx_from,PETSC_COPY_VALUES,&from);
1017*7f296bb3SBarry SmithISCreateGeneral(PETSC_COMM_SELF,2,idx_to,PETSC_COPY_VALUES,&to);
1018*7f296bb3SBarry SmithVecScatterCreate(p,from,x,to,&scatter);
1019*7f296bb3SBarry SmithVecScatterBegin(scatter,p,x,INSERT_VALUES,SCATTER_FORWARD);
1020*7f296bb3SBarry SmithVecScatterEnd(scatter,p,x,INSERT_VALUES,SCATTER_FORWARD);
1021*7f296bb3SBarry SmithVecGetArray(x,&values);
1022*7f296bb3SBarry SmithISDestroy(&from);
1023*7f296bb3SBarry SmithISDestroy(&to);
1024*7f296bb3SBarry SmithVecScatterDestroy(&scatter);
1025*7f296bb3SBarry Smith```
1026*7f296bb3SBarry Smith
1027*7f296bb3SBarry SmithThe scatter comprises two stages to allow for the overlap of
1028*7f296bb3SBarry Smithcommunication and computation. The introduction of the `VecScatter`
1029*7f296bb3SBarry Smithcontext allows the communication patterns for the scatter to be computed
1030*7f296bb3SBarry Smithonce and reused repeatedly. Generally, even setting up the
1031*7f296bb3SBarry Smithcommunication for a scatter requires communication; hence, it is best to
1032*7f296bb3SBarry Smithreuse such information when possible.
1033*7f296bb3SBarry Smith
1034*7f296bb3SBarry SmithScatters provide a very general method for managing the
1035*7f296bb3SBarry Smithcommunication of required ghost values for unstructured grid
1036*7f296bb3SBarry Smithcomputations. One scatters the global vector into a local “ghosted” work
1037*7f296bb3SBarry Smithvector, performs the computation on the local work vectors, and then
1038*7f296bb3SBarry Smithscatters back into the global solution vector. In the simplest case, this
1039*7f296bb3SBarry Smithmay be written as
1040*7f296bb3SBarry Smith
1041*7f296bb3SBarry Smith```
1042*7f296bb3SBarry SmithVecScatterBegin(VecScatter scatter,Vec globalin,Vec localin,InsertMode INSERT_VALUES, ScatterMode SCATTER_FORWARD);
1043*7f296bb3SBarry SmithVecScatterEnd(VecScatter scatter,Vec globalin,Vec localin,InsertMode INSERT_VALUES,ScatterMode SCATTER_FORWARD);
1044*7f296bb3SBarry Smith/* For example, do local calculations from localin to localout */
1045*7f296bb3SBarry Smith...
1046*7f296bb3SBarry SmithVecScatterBegin(VecScatter scatter,Vec localout,Vec globalout,InsertMode ADD_VALUES,ScatterMode SCATTER_REVERSE);
1047*7f296bb3SBarry SmithVecScatterEnd(VecScatter scatter,Vec localout,Vec globalout,InsertMode ADD_VALUES,ScatterMode SCATTER_REVERSE);
1048*7f296bb3SBarry Smith```
1049*7f296bb3SBarry Smith
1050*7f296bb3SBarry SmithIn this case, the scatter is used in a way similar to the usage of `DMGlobalToLocal()` and `DMLocalToGlobal()` discussed above.
1051*7f296bb3SBarry Smith
1052*7f296bb3SBarry Smith(sec_islocaltoglobalmap)=
1053*7f296bb3SBarry Smith
1054*7f296bb3SBarry Smith### Local to global mappings
1055*7f296bb3SBarry Smith
1056*7f296bb3SBarry SmithWhen working with a global representation of a vector
1057*7f296bb3SBarry Smith(usually on a vector obtained with `DMCreateGlobalVector()`) and a local
1058*7f296bb3SBarry Smithrepresentation of the same vector that includes ghost points required
1059*7f296bb3SBarry Smithfor local computation (obtained with `DMCreateLocalVector()`). PETSc provides routines to help map indices from
1060*7f296bb3SBarry Smitha local numbering scheme to the PETSc global numbering scheme, recall their use above for the routine `VecSetValuesLocal()` introduced above.
1061*7f296bb3SBarry SmithThis is done via the following routines
1062*7f296bb3SBarry Smith
1063*7f296bb3SBarry Smith```
1064*7f296bb3SBarry SmithISLocalToGlobalMappingCreate(MPI_Comm comm,PetscInt bs,PetscInt N,PetscInt* globalnum,PetscCopyMode mode,ISLocalToGlobalMapping* ctx);
1065*7f296bb3SBarry SmithISLocalToGlobalMappingApply(ISLocalToGlobalMapping ctx,PetscInt n,PetscInt *in,PetscInt *out);
1066*7f296bb3SBarry SmithISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping ctx,IS isin,IS* isout);
1067*7f296bb3SBarry SmithISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *ctx);
1068*7f296bb3SBarry Smith```
1069*7f296bb3SBarry Smith
1070*7f296bb3SBarry SmithHere `N` denotes the number of local indices, `globalnum` contains
1071*7f296bb3SBarry Smiththe global number of each local number, and `ISLocalToGlobalMapping`
1072*7f296bb3SBarry Smithis the resulting PETSc object that contains the information needed to
1073*7f296bb3SBarry Smithapply the mapping with either `ISLocalToGlobalMappingApply()` or
1074*7f296bb3SBarry Smith`ISLocalToGlobalMappingApplyIS()`.
1075*7f296bb3SBarry Smith
1076*7f296bb3SBarry SmithNote that the `ISLocalToGlobalMapping` routines serve a different
1077*7f296bb3SBarry Smithpurpose than the `AO` routines. In the former case, they provide a
1078*7f296bb3SBarry Smithmapping from a local numbering scheme (including ghost points) to a
1079*7f296bb3SBarry Smithglobal numbering scheme, while in the latter, they provide a mapping
1080*7f296bb3SBarry Smithbetween two global numbering schemes. Many applications may use
1081*7f296bb3SBarry Smithboth `AO` and `ISLocalToGlobalMapping` routines. The `AO` routines
1082*7f296bb3SBarry Smithare first used to map from an application global ordering (that has no
1083*7f296bb3SBarry Smithrelationship to parallel processing, etc.) to the PETSc ordering scheme
1084*7f296bb3SBarry Smith(where each process has a contiguous set of indices in the numbering).
1085*7f296bb3SBarry SmithThen, to perform function or Jacobian evaluations locally on
1086*7f296bb3SBarry Smitheach process, one works with a local numbering scheme that includes
1087*7f296bb3SBarry Smithghost points. The mapping from this local numbering scheme back to the
1088*7f296bb3SBarry Smithglobal PETSc numbering can be handled with the
1089*7f296bb3SBarry Smith`ISLocalToGlobalMapping` routines.
1090*7f296bb3SBarry Smith
1091*7f296bb3SBarry SmithIf one is given a list of block indices in a global numbering, the
1092*7f296bb3SBarry Smithroutine
1093*7f296bb3SBarry Smith
1094*7f296bb3SBarry Smith```
1095*7f296bb3SBarry SmithISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping ctx,ISGlobalToLocalMappingMode type,PetscInt nin,PetscInt idxin[],PetscInt *nout,PetscInt idxout[]);
1096*7f296bb3SBarry Smith```
1097*7f296bb3SBarry Smith
1098*7f296bb3SBarry Smithwill provide a new list of indices in the local numbering. Again,
1099*7f296bb3SBarry Smithnegative values in `idxin` are left unmapped. But in addition, if
1100*7f296bb3SBarry Smith`type` is set to `IS_GTOLM_MASK` , then `nout` is set to `nin`
1101*7f296bb3SBarry Smithand all global values in `idxin` that are not represented in the local
1102*7f296bb3SBarry Smithto global mapping are replaced by -1. When `type` is set to
1103*7f296bb3SBarry Smith`IS_GTOLM_DROP`, the values in `idxin` that are not represented
1104*7f296bb3SBarry Smithlocally in the mapping are not included in `idxout`, so that
1105*7f296bb3SBarry Smithpotentially `nout` is smaller than `nin`. One must pass in an array
1106*7f296bb3SBarry Smithlong enough to hold all the indices. One can call
1107*7f296bb3SBarry Smith`ISGlobalToLocalMappingApplyBlock()` with `idxout` equal to `NULL`
1108*7f296bb3SBarry Smithto determine the required length (returned in `nout`) and then
1109*7f296bb3SBarry Smithallocate the required space and call
1110*7f296bb3SBarry Smith`ISGlobalToLocalMappingApplyBlock()` a second time to set the values.
1111*7f296bb3SBarry Smith
1112*7f296bb3SBarry SmithOften it is convenient to set elements into a vector using the local
1113*7f296bb3SBarry Smithnode numbering rather than the global node numbering (e.g., each process
1114*7f296bb3SBarry Smithmay maintain its own sublist of vertices and elements and number them
1115*7f296bb3SBarry Smithlocally). To set values into a vector with the local numbering, one must
1116*7f296bb3SBarry Smithfirst call
1117*7f296bb3SBarry Smith
1118*7f296bb3SBarry Smith```
1119*7f296bb3SBarry SmithVecSetLocalToGlobalMapping(Vec v,ISLocalToGlobalMapping ctx);
1120*7f296bb3SBarry Smith```
1121*7f296bb3SBarry Smith
1122*7f296bb3SBarry Smithand then call
1123*7f296bb3SBarry Smith
1124*7f296bb3SBarry Smith```
1125*7f296bb3SBarry SmithVecSetValuesLocal(Vec x,PetscInt n,const PetscInt indices[],const PetscScalar values[],INSERT_VALUES);
1126*7f296bb3SBarry Smith```
1127*7f296bb3SBarry Smith
1128*7f296bb3SBarry SmithNow the `indices` use the local numbering rather than the global,
1129*7f296bb3SBarry Smithmeaning the entries lie in $[0,n)$ where $n$ is the local
1130*7f296bb3SBarry Smithsize of the vector. Global vectors obtained from a `DM` already have the global to local mapping
1131*7f296bb3SBarry Smithprovided by the `DM`.
1132*7f296bb3SBarry Smith
1133*7f296bb3SBarry SmithOne can use global indices
1134*7f296bb3SBarry Smithwith `MatSetValues()` or `MatSetValuesStencil()` to assemble global stiffness matrices. Alternately, the
1135*7f296bb3SBarry Smithglobal node number of each local node, including the ghost nodes, can be
1136*7f296bb3SBarry Smithobtained by calling
1137*7f296bb3SBarry Smith
1138*7f296bb3SBarry Smith```
1139*7f296bb3SBarry SmithDMGetLocalToGlobalMapping(DM da,ISLocalToGlobalMapping *map);
1140*7f296bb3SBarry Smith```
1141*7f296bb3SBarry Smith
1142*7f296bb3SBarry Smithfollowed by
1143*7f296bb3SBarry Smith
1144*7f296bb3SBarry Smith```
1145*7f296bb3SBarry SmithVecSetLocalToGlobalMapping(Vec v,ISLocalToGlobalMapping map);
1146*7f296bb3SBarry SmithMatSetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping);
1147*7f296bb3SBarry Smith```
1148*7f296bb3SBarry Smith
1149*7f296bb3SBarry SmithNow, entries may be added to the vector and matrix using the local
1150*7f296bb3SBarry Smithnumbering and `VecSetValuesLocal()` and `MatSetValuesLocal()`.
1151*7f296bb3SBarry Smith
1152*7f296bb3SBarry SmithThe example
1153*7f296bb3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tutorials/ex5.c.html">SNES Tutorial ex5</a>
1154*7f296bb3SBarry Smithillustrates the use of a `DMDA` in the solution of a
1155*7f296bb3SBarry Smithnonlinear problem. The analogous Fortran program is
1156*7f296bb3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tutorials/ex5f90.F90.html">SNES Tutorial ex5f90</a>;
1157*7f296bb3SBarry Smithsee {any}`ch_snes` for a discussion of the
1158*7f296bb3SBarry Smithnonlinear solvers.
1159*7f296bb3SBarry Smith
1160*7f296bb3SBarry Smith(sec_vecghost)=
1161*7f296bb3SBarry Smith
1162*7f296bb3SBarry Smith### Global Vectors with locations for ghost values
1163*7f296bb3SBarry Smith
1164*7f296bb3SBarry SmithThere are two minor drawbacks to the basic approach described above for unstructured grids:
1165*7f296bb3SBarry Smith
1166*7f296bb3SBarry Smith- the extra memory requirement for the local work vector, `localin`,
1167*7f296bb3SBarry Smith  which duplicates the local values in the memory in `globalin`, and
1168*7f296bb3SBarry Smith- the extra time required to copy the local values from `localin` to
1169*7f296bb3SBarry Smith  `globalin`.
1170*7f296bb3SBarry Smith
1171*7f296bb3SBarry SmithAn alternative approach is to allocate global vectors with space
1172*7f296bb3SBarry Smithpreallocated for the ghost values.
1173*7f296bb3SBarry Smith
1174*7f296bb3SBarry Smith```
1175*7f296bb3SBarry SmithVecCreateGhost(MPI_Comm comm,PetscInt n,PetscInt N,PetscInt nghost,PetscInt *ghosts,Vec *vv)
1176*7f296bb3SBarry Smith```
1177*7f296bb3SBarry Smith
1178*7f296bb3SBarry Smithor
1179*7f296bb3SBarry Smith
1180*7f296bb3SBarry Smith```
1181*7f296bb3SBarry SmithVecCreateGhostWithArray(MPI_Comm comm,PetscInt n,PetscInt N,PetscInt nghost,PetscInt *ghosts,PetscScalar *array,Vec *vv)
1182*7f296bb3SBarry Smith```
1183*7f296bb3SBarry Smith
1184*7f296bb3SBarry SmithHere `n` is the number of local vector entries, `N` is the number of
1185*7f296bb3SBarry Smithglobal entries (or `NULL`), and `nghost` is the number of ghost
1186*7f296bb3SBarry Smithentries. The array `ghosts` is of size `nghost` and contains the
1187*7f296bb3SBarry Smithglobal vector location for each local ghost location. Using
1188*7f296bb3SBarry Smith`VecDuplicate()` or `VecDuplicateVecs()` on a ghosted vector will
1189*7f296bb3SBarry Smithgenerate additional ghosted vectors.
1190*7f296bb3SBarry Smith
1191*7f296bb3SBarry SmithIn many ways, a ghosted vector behaves like any other MPI vector
1192*7f296bb3SBarry Smithcreated by `VecCreateMPI()`. The difference is that the ghosted vector
1193*7f296bb3SBarry Smithhas an additional “local” representation that allows one to access the
1194*7f296bb3SBarry Smithghost locations. This is done through the call to
1195*7f296bb3SBarry Smith
1196*7f296bb3SBarry Smith```
1197*7f296bb3SBarry SmithVecGhostGetLocalForm(Vec g,Vec *l);
1198*7f296bb3SBarry Smith```
1199*7f296bb3SBarry Smith
1200*7f296bb3SBarry SmithThe vector `l` is a sequential representation of the parallel vector
1201*7f296bb3SBarry Smith`g` that shares the same array space (and hence numerical values); but
1202*7f296bb3SBarry Smithallows one to access the “ghost” values past “the end of the” array.
1203*7f296bb3SBarry SmithNote that one accesses the entries in `l` using the local numbering of
1204*7f296bb3SBarry Smithelements and ghosts, while they are accessed in `g` using the global
1205*7f296bb3SBarry Smithnumbering.
1206*7f296bb3SBarry Smith
1207*7f296bb3SBarry SmithA common usage of a ghosted vector is given by
1208*7f296bb3SBarry Smith
1209*7f296bb3SBarry Smith```
1210*7f296bb3SBarry SmithVecGhostUpdateBegin(Vec globalin,InsertMode INSERT_VALUES, ScatterMode SCATTER_FORWARD);
1211*7f296bb3SBarry SmithVecGhostUpdateEnd(Vec globalin,InsertMode INSERT_VALUES, ScatterMode SCATTER_FORWARD);
1212*7f296bb3SBarry SmithVecGhostGetLocalForm(Vec globalin,Vec *localin);
1213*7f296bb3SBarry SmithVecGhostGetLocalForm(Vec globalout,Vec *localout);
1214*7f296bb3SBarry Smith...  Do local calculations from localin to localout ...
1215*7f296bb3SBarry SmithVecGhostRestoreLocalForm(Vec globalin,Vec *localin);
1216*7f296bb3SBarry SmithVecGhostRestoreLocalForm(Vec globalout,Vec *localout);
1217*7f296bb3SBarry SmithVecGhostUpdateBegin(Vec globalout,InsertMode ADD_VALUES, ScatterMode SCATTER_REVERSE);
1218*7f296bb3SBarry SmithVecGhostUpdateEnd(Vec globalout,InsertMode ADD_VALUES, ScatterMode SCATTER_REVERSE);
1219*7f296bb3SBarry Smith```
1220*7f296bb3SBarry Smith
1221*7f296bb3SBarry SmithThe routines `VecGhostUpdateBegin()` and `VecGhostUpdateEnd()` are
1222*7f296bb3SBarry Smithequivalent to the routines `VecScatterBegin()` and `VecScatterEnd()`
1223*7f296bb3SBarry Smithabove, except that since they are scattering into the ghost locations,
1224*7f296bb3SBarry Smiththey do not need to copy the local vector values, which are already in
1225*7f296bb3SBarry Smithplace. In addition, the user does not have to allocate the local work
1226*7f296bb3SBarry Smithvector since the ghosted vector already has allocated slots to contain
1227*7f296bb3SBarry Smiththe ghost values.
1228*7f296bb3SBarry Smith
1229*7f296bb3SBarry SmithThe input arguments `INSERT_VALUES` and `SCATTER_FORWARD` cause the
1230*7f296bb3SBarry Smithghost values to be correctly updated from the appropriate process. The
1231*7f296bb3SBarry Smitharguments `ADD_VALUES` and `SCATTER_REVERSE` update the “local”
1232*7f296bb3SBarry Smithportions of the vector from all the other processes’ ghost values. This
1233*7f296bb3SBarry Smithwould be appropriate, for example, when performing a finite element
1234*7f296bb3SBarry Smithassembly of a load vector. One can also use `MAX_VALUES` or
1235*7f296bb3SBarry Smith`MIN_VALUES` with `SCATTER_REVERSE`.
1236*7f296bb3SBarry Smith
1237*7f296bb3SBarry Smith`DMPLEX` does not yet support ghosted vectors sharing memory with the global representation.
1238*7f296bb3SBarry SmithThis is a work in progress; if you are interested in this feature, please contact the PETSc community members.
1239*7f296bb3SBarry Smith
1240*7f296bb3SBarry Smith{any}`sec_partitioning` discusses the important topic of
1241*7f296bb3SBarry Smithpartitioning an unstructured grid.
1242*7f296bb3SBarry Smith
1243*7f296bb3SBarry Smith(sec_ao)=
1244*7f296bb3SBarry Smith
1245*7f296bb3SBarry Smith## Application Orderings
1246*7f296bb3SBarry Smith
1247*7f296bb3SBarry SmithWhen writing parallel PDE codes, there is extra complexity caused by
1248*7f296bb3SBarry Smithhaving multiple ways of indexing (numbering) and ordering objects such
1249*7f296bb3SBarry Smithas vertices and degrees of freedom. For example, a grid generator or
1250*7f296bb3SBarry Smithpartitioner may renumber the nodes, requiring adjustment of the other
1251*7f296bb3SBarry Smithdata structures that refer to these objects; see Figure
1252*7f296bb3SBarry Smith{any}`fig_daao`.
1253*7f296bb3SBarry SmithPETSc provides various tools to help manage the mapping amongst
1254*7f296bb3SBarry Smiththe various numbering systems. The most basic is the `AO`
1255*7f296bb3SBarry Smith(application ordering), which enables mapping between different global
1256*7f296bb3SBarry Smith(cross-process) numbering schemes.
1257*7f296bb3SBarry Smith
1258*7f296bb3SBarry SmithIn many applications, it is desirable to work with one or more
1259*7f296bb3SBarry Smith“orderings” (or numberings) of degrees of freedom, cells, nodes, etc.
1260*7f296bb3SBarry SmithDoing so in a parallel environment is complicated by the fact that each
1261*7f296bb3SBarry Smithprocess cannot keep complete lists of the mappings between different
1262*7f296bb3SBarry Smithorderings. In addition, the orderings used in the PETSc linear algebra
1263*7f296bb3SBarry Smithroutines (often contiguous ranges) may not correspond to the “natural”
1264*7f296bb3SBarry Smithorderings for the application.
1265*7f296bb3SBarry Smith
1266*7f296bb3SBarry SmithPETSc provides certain utility routines that allow one to deal cleanly
1267*7f296bb3SBarry Smithand efficiently with the various orderings. To define a new application
1268*7f296bb3SBarry Smithordering (called an `AO` in PETSc), one can call the routine
1269*7f296bb3SBarry Smith
1270*7f296bb3SBarry Smith```
1271*7f296bb3SBarry SmithAOCreateBasic(MPI_Comm comm,PetscInt n,const PetscInt apordering[],const PetscInt petscordering[],AO *ao);
1272*7f296bb3SBarry Smith```
1273*7f296bb3SBarry Smith
1274*7f296bb3SBarry SmithThe arrays `apordering` and `petscordering`, respectively, contain a
1275*7f296bb3SBarry Smithlist of integers in the application ordering and their corresponding
1276*7f296bb3SBarry Smithmapped values in the PETSc ordering. Each process can provide whatever
1277*7f296bb3SBarry Smithsubset of the ordering it chooses, but multiple processes should never
1278*7f296bb3SBarry Smithcontribute duplicate values. The argument `n` indicates the number of
1279*7f296bb3SBarry Smithlocal contributed values.
1280*7f296bb3SBarry Smith
1281*7f296bb3SBarry SmithFor example, consider a vector of length 5, where node 0 in the
1282*7f296bb3SBarry Smithapplication ordering corresponds to node 3 in the PETSc ordering. In
1283*7f296bb3SBarry Smithaddition, nodes 1, 2, 3, and 4 of the application ordering correspond,
1284*7f296bb3SBarry Smithrespectively, to nodes 2, 1, 4, and 0 of the PETSc ordering. We can
1285*7f296bb3SBarry Smithwrite this correspondence as
1286*7f296bb3SBarry Smith
1287*7f296bb3SBarry Smith$$
1288*7f296bb3SBarry Smith\{ 0, 1, 2, 3, 4 \}  \to  \{ 3, 2, 1, 4, 0 \}.
1289*7f296bb3SBarry Smith$$
1290*7f296bb3SBarry Smith
1291*7f296bb3SBarry SmithThe user can create the PETSc `AO` mappings in several ways. For
1292*7f296bb3SBarry Smithexample, if using two processes, one could call
1293*7f296bb3SBarry Smith
1294*7f296bb3SBarry Smith```
1295*7f296bb3SBarry SmithAOCreateBasic(PETSC_COMM_WORLD,2,{0,3},{3,4},&ao);
1296*7f296bb3SBarry Smith```
1297*7f296bb3SBarry Smith
1298*7f296bb3SBarry Smithon the first process and
1299*7f296bb3SBarry Smith
1300*7f296bb3SBarry Smith```
1301*7f296bb3SBarry SmithAOCreateBasic(PETSC_COMM_WORLD,3,{1,2,4},{2,1,0},&ao);
1302*7f296bb3SBarry Smith```
1303*7f296bb3SBarry Smith
1304*7f296bb3SBarry Smithon the other process.
1305*7f296bb3SBarry Smith
1306*7f296bb3SBarry SmithOnce the application ordering has been created, it can be used with
1307*7f296bb3SBarry Smitheither of the commands
1308*7f296bb3SBarry Smith
1309*7f296bb3SBarry Smith```
1310*7f296bb3SBarry SmithAOPetscToApplication(AO ao,PetscInt n,PetscInt *indices);
1311*7f296bb3SBarry SmithAOApplicationToPetsc(AO ao,PetscInt n,PetscInt *indices);
1312*7f296bb3SBarry Smith```
1313*7f296bb3SBarry Smith
1314*7f296bb3SBarry SmithUpon input, the `n`-dimensional array `indices` specifies the
1315*7f296bb3SBarry Smithindices to be mapped, while upon output, `indices` contains the mapped
1316*7f296bb3SBarry Smithvalues. Since we, in general, employ a parallel database for the `AO`
1317*7f296bb3SBarry Smithmappings, it is crucial that all processes that called
1318*7f296bb3SBarry Smith`AOCreateBasic()` also call these routines; these routines *cannot* be
1319*7f296bb3SBarry Smithcalled by just a subset of processes in the MPI communicator that was
1320*7f296bb3SBarry Smithused in the call to `AOCreateBasic()`.
1321*7f296bb3SBarry Smith
1322*7f296bb3SBarry SmithAn alternative routine to create the application ordering, `AO`, is
1323*7f296bb3SBarry Smith
1324*7f296bb3SBarry Smith```
1325*7f296bb3SBarry SmithAOCreateBasicIS(IS apordering,IS petscordering,AO *ao);
1326*7f296bb3SBarry Smith```
1327*7f296bb3SBarry Smith
1328*7f296bb3SBarry Smithwhere index sets are used
1329*7f296bb3SBarry Smithinstead of integer arrays.
1330*7f296bb3SBarry Smith
1331*7f296bb3SBarry SmithThe mapping routines
1332*7f296bb3SBarry Smith
1333*7f296bb3SBarry Smith```
1334*7f296bb3SBarry SmithAOPetscToApplicationIS(AO ao,IS indices);
1335*7f296bb3SBarry SmithAOApplicationToPetscIS(AO ao,IS indices);
1336*7f296bb3SBarry Smith```
1337*7f296bb3SBarry Smith
1338*7f296bb3SBarry Smithwill map index sets (`IS` objects) between orderings. Both the
1339*7f296bb3SBarry Smith`AOXxxToYyy()` and `AOXxxToYyyIS()` routines can be used regardless
1340*7f296bb3SBarry Smithof whether the `AO` was created with a `AOCreateBasic()` or
1341*7f296bb3SBarry Smith`AOCreateBasicIS()`.
1342*7f296bb3SBarry Smith
1343*7f296bb3SBarry SmithThe `AO` context should be destroyed with `AODestroy(AO *ao)` and
1344*7f296bb3SBarry Smithviewed with `AOView(AO ao,PetscViewer viewer)`.
1345*7f296bb3SBarry Smith
1346*7f296bb3SBarry SmithAlthough we refer to the two orderings as “PETSc” and “application”
1347*7f296bb3SBarry Smithorderings, the user is free to use them both for application orderings
1348*7f296bb3SBarry Smithand to maintain relationships among a variety of orderings by employing
1349*7f296bb3SBarry Smithseveral `AO` contexts.
1350*7f296bb3SBarry Smith
1351*7f296bb3SBarry SmithThe `AOxxToxx()` routines allow negative entries in the input integer
1352*7f296bb3SBarry Smitharray. These entries are not mapped; they remain unchanged. This
1353*7f296bb3SBarry Smithfunctionality enables, for example, mapping neighbor lists that use
1354*7f296bb3SBarry Smithnegative numbers to indicate nonexistent neighbors due to boundary
1355*7f296bb3SBarry Smithconditions, etc.
1356*7f296bb3SBarry Smith
1357*7f296bb3SBarry SmithSince the global ordering that PETSc uses to manage its parallel vectors
1358*7f296bb3SBarry Smith(and matrices) does not usually correspond to the “natural” ordering of
1359*7f296bb3SBarry Smitha two- or three-dimensional array, the `DMDA` structure provides an
1360*7f296bb3SBarry Smithapplication ordering `AO` (see {any}`sec_ao`) that maps
1361*7f296bb3SBarry Smithbetween the natural ordering on a rectangular grid and the ordering
1362*7f296bb3SBarry SmithPETSc uses to parallelize. This ordering context can be obtained with
1363*7f296bb3SBarry Smiththe command
1364*7f296bb3SBarry Smith
1365*7f296bb3SBarry Smith```
1366*7f296bb3SBarry SmithDMDAGetAO(DM da,AO *ao);
1367*7f296bb3SBarry Smith```
1368*7f296bb3SBarry Smith
1369*7f296bb3SBarry SmithIn Figure {any}`fig_daao`, we indicate the orderings for a
1370*7f296bb3SBarry Smithtwo-dimensional `DMDA`, divided among four processes.
1371*7f296bb3SBarry Smith
1372*7f296bb3SBarry Smith:::{figure} /images/manual/danumbering.*
1373*7f296bb3SBarry Smith:alt: Natural Ordering and PETSc Ordering for a 2D Distributed Array (Four Processes)
1374*7f296bb3SBarry Smith:name: fig_daao
1375*7f296bb3SBarry Smith
1376*7f296bb3SBarry SmithNatural Ordering and PETSc Ordering for a 2D Distributed Array (Four
1377*7f296bb3SBarry SmithProcesses)
1378*7f296bb3SBarry Smith:::
1379