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