1*dac9a9d1SBarry Smith(ch_dmcommonality)= 2*dac9a9d1SBarry Smith 3*dac9a9d1SBarry Smith# DM Commonalities 4*dac9a9d1SBarry Smith 5*dac9a9d1SBarry SmithWe have introduced a variety of seemingly very different `DM`. Here, we will try to explore the commonalities between them to emphasize that despite superficial 6*dac9a9d1SBarry Smithdifferences they all tackle the three same basic problems: 7*dac9a9d1SBarry Smith 8*dac9a9d1SBarry Smith1. How to map between the indices of (geometric) entities, in some physical space such as $R^3$ or perhaps an abstract space, and 9*dac9a9d1SBarry Smith the storage location (offsets) of numerical values associated with said entities in PETSc vectors or arrays. 10*dac9a9d1SBarry Smith In PETSc, these geometric entities are referred to as points. 11*dac9a9d1SBarry Smith2. How to iterate over the entities of interest (for example, points) to produce updates to the numerical values associated with the entities in 12*dac9a9d1SBarry Smith the PETSc vectors or arrays. 13*dac9a9d1SBarry Smith3. How to store/access the "connectivity information" that is needed at each entity (point) and provides the correct data dependencies 14*dac9a9d1SBarry Smith needed to compute the numerical updates. 15*dac9a9d1SBarry Smith 16*dac9a9d1SBarry SmithFor several `DM` we will devote a short paragraph for each of the three problems. 17*dac9a9d1SBarry Smith 18*dac9a9d1SBarry Smith## DMDA simple structured grids 19*dac9a9d1SBarry Smith 20*dac9a9d1SBarry SmithFor structured grids, {any}`sec_struct`, the indexing is trivial, the points are represented as tuples $(i, j, k)$, where $l_i \le i \le u_i$, $l_j \le j \le u_j$, 21*dac9a9d1SBarry Smithand $l_k \le k \le u_k.$ `DMDAVecGetArray()` returns a multidimensional array that trivially provides the mapping from said points to the numerical values. 22*dac9a9d1SBarry SmithNote that when the programming language gives access to the values in a multi-dimensional array, 23*dac9a9d1SBarry Smithinternally it computes the `offset` from the beginning of the array using a formula based on the value of $i$, $j$, and $k$ and the array dimensions. 24*dac9a9d1SBarry Smith 25*dac9a9d1SBarry SmithTo iterate over the local points, one uses `DMDAGetCorners()` or `DMDAGetGhostCorners()` and iterates over the tuples within the bounds. Specific points, for example 26*dac9a9d1SBarry Smithboundary points, can be skipped or processed differently based on the index values. 27*dac9a9d1SBarry Smith 28*dac9a9d1SBarry SmithFor finite difference methods on structured grids using a stencil formula, the "connectivity information" is defined implicitly by the stencil needed 29*dac9a9d1SBarry Smithby the given discretization and is the same for all grid points (except maybe boundaries or other special points). For example, for the standard 30*dac9a9d1SBarry Smithseven point stencil computed at the $(i, j, k)$ entity one needs the numerical values at the $(i \pm 1, j, k)$, $(i, j \pm 1, k)$, 31*dac9a9d1SBarry Smithand $(i, j, k \pm 1)$ entities. 32*dac9a9d1SBarry Smith 33*dac9a9d1SBarry Smith## DMSTAG simple stagger grids 34*dac9a9d1SBarry Smith 35*dac9a9d1SBarry SmithA staggered grid, {any}`ch_stag`, extends the idea of a simple structured grid by allowing not only entities associated with grid vertices (or equivalently cells) 36*dac9a9d1SBarry Smithas with `DMDA` 37*dac9a9d1SBarry Smithbut also with grid edges, grid faces, and grid cells (also called elements). As with `DMDA` each type of entity must have the same number of associated 38*dac9a9d1SBarry Smithnumerical values. As with simple structured grids, each cell can be represented as a $(i, j, k)$ tuple. But, in addition we need to represent what vertex, 39*dac9a9d1SBarry Smithedge, or face of the cell we are referring to. This is done using `DMStagStencilLocation`. `DMStagVecGetArray()` returns a multidimensional array indexed 40*dac9a9d1SBarry Smithby $(i, j, k)$ plus a `slot` that tells us which entity on the cell is being accessed. Since a staggered grid can have any problem-dependent 41*dac9a9d1SBarry Smithnumber of numerical values associated with a given entity type, the function `DMStagGetLocationSlot()` provides the final index needed for the array access. After 42*dac9a9d1SBarry Smiththis the programming language than computes the `offset` from the beginning of the array from the provided indices using a simple formula. 43*dac9a9d1SBarry Smith 44*dac9a9d1SBarry SmithTo iterate over the local points, one uses `DMStagGetCorners()` or `DMStagGetGhostCorners()` and iterates over the tuples within the bounds with an inner iteration 45*dac9a9d1SBarry Smithof the point entities desired for the application. For example, for a discretization with cell-centered pressures and edge-based velocity the application 46*dac9a9d1SBarry Smithwould process each of these entities. 47*dac9a9d1SBarry Smith 48*dac9a9d1SBarry SmithFor finite difference methods on staggered structured grids using a stencil formula the "connectivity information" is again defined implicitly by the stencil needed 49*dac9a9d1SBarry Smithby the given discretization and is the same for all grid points (except maybe boundaries or other special points). In addition, any required cross coupling between 50*dac9a9d1SBarry Smithdifferent entities needs to be encoded for the given problem. For example, how do the velocities affect the pressure equation. This information is generally 51*dac9a9d1SBarry Smithembedded directly in lines of code that implement the finite difference formula and is not represented in the data structures. 52*dac9a9d1SBarry Smith 53*dac9a9d1SBarry Smith 54*dac9a9d1SBarry Smith## DMPLEX unstructured meshes 55*dac9a9d1SBarry Smith 56*dac9a9d1SBarry SmithFor general unstructured grids, {any}`ch_unstructured`, there is no formula for computing the `offset` into the numerical values 57*dac9a9d1SBarry Smithfor an entity on the grid from its `point` value, since each `point` can have any number of values which is determined at runtime based 58*dac9a9d1SBarry Smith on the grid, PDE, and discretization. Hence all the offsets 59*dac9a9d1SBarry Smithmust be managed by `DMPLEX`. This is the job of `PetscSection`, {any}`ch_petscsection`. The process of building a `PetscSection` computes 60*dac9a9d1SBarry Smithand stores the offsets and then using the `PetscSection` gives access to the needed offsets. 61*dac9a9d1SBarry Smith 62*dac9a9d1SBarry SmithFor unstructured grids, one does not in general iterate over all the entities on all the points. Rather it iterates over a subset of the points representing 63*dac9a9d1SBarry Smitha particular entity. For example, when using the finite element method, the application iterates all the points representing elements (cells) using 64*dac9a9d1SBarry Smith`DMPlexGetHeightStratum()` to access the chart (beginning and end indices) of the cell entities. Then one uses an associated `PetscSection` to determine the offsets into 65*dac9a9d1SBarry Smithvectors or arrays for said points. If needed one can then have an inner iteration over the fields associated with the cell. 66*dac9a9d1SBarry Smith 67*dac9a9d1SBarry SmithFor `DMPLEX`, the connectivity information is defined by a graph (and stored explicitly in a data structure used to store graphs), 68*dac9a9d1SBarry Smithand the connectivity of a point (entity) is obtained by `DMPlexGetTransitiveClosure()`. 69*dac9a9d1SBarry Smith 70*dac9a9d1SBarry Smith 71*dac9a9d1SBarry Smith## DMNETWORK computations on graphs of nodes and connecting edges 72*dac9a9d1SBarry Smith 73*dac9a9d1SBarry SmithFor networks, {any}`ch_network`, the entities are nodes and edges that connect two nodes, each of which can have any number of submodels. 74*dac9a9d1SBarry SmithAgain, in general, there is no formula that can produce the 75*dac9a9d1SBarry Smithappropriate `offset` into the numerical values for a given `point` (node or edge) directly. The routines `DMNetworkGetLocalVecOffset()` 76*dac9a9d1SBarry Smithand `DMNetworkGetGlobalVecOffset()` 77*dac9a9d1SBarry Smithare used to obtain the needed offsets from a given point (node or edge) and submodel at that point. Internally a `PetscSection` is used to 78*dac9a9d1SBarry Smithmanage the storage of the `offset` information but the user-level API does not refer to `PetscSection` directly, rather one thinks about 79*dac9a9d1SBarry Smitha collection of submodels at each node and edge of the graph. 80*dac9a9d1SBarry Smith 81*dac9a9d1SBarry SmithTo iterate over graph vertices (nodes) one uses `DMNetworkGetVertexRange()` to provide its chart (the starting and end indices) 82*dac9a9d1SBarry Smithand `DMNetworkGetEdgeRange()` to provide the chart of the edges. One can then iterate over the models on each point 83*dac9a9d1SBarry SmithTo iterate over sub-networks one can call `DMNetworkGetSubnetwork()` for each network which 84*dac9a9d1SBarry Smithreturns lists of the vertex and edge points in said network. 85*dac9a9d1SBarry Smith 86*dac9a9d1SBarry SmithFor `DMNETWORK`, the connectivity information is defined by a graph, which is is query-able at each entity by 87*dac9a9d1SBarry Smith`DMNetworkGetSupportingEdges()` and `DMNetworkGetConnectedVertices()`. 88*dac9a9d1SBarry Smith 89*dac9a9d1SBarry Smith# Is it a programming language issue? 90*dac9a9d1SBarry Smith 91*dac9a9d1SBarry SmithRegarding problem 1. Does the need for these various approaches for mapping between the entities and the related array offsets and the large amount of code 92*dac9a9d1SBarry Smith(in particular `PetscSection` come from the limitation of programming languages when working 93*dac9a9d1SBarry Smithwith complex multidimensional jagged arrays. Both in constructing such arrays at runtime, that is supplying all the jagged information which depends 94*dac9a9d1SBarry Smithon the exact problem, and then providing simple syntax to produce the correct offset into the 95*dac9a9d1SBarry Smithmemory for accessing the numerical values when the simple array access methods do not work. 96*dac9a9d1SBarry Smith 97*dac9a9d1SBarry Smith 98*dac9a9d1SBarry Smith 99*dac9a9d1SBarry Smith 100*dac9a9d1SBarry Smith 101*dac9a9d1SBarry Smith 102