xref: /petsc/doc/manual/dmcommonality.md (revision b59054469e8e75e7f1217f4456448261033ebd2d)
1(ch_dmcommonality)=
2
3# DM Commonalities
4
5We have introduced a variety of seemingly very different `DM`. Here, we will try to explore the commonalities between them to emphasize that despite superficial
6differences they all tackle the three same basic problems:
7
81. How to map between the indices of (geometric) entities, in some physical space such as $R^3$ or perhaps an abstract space, and
9  the storage location (offsets) of numerical values associated with said entities in PETSc vectors or arrays.
10  In PETSc, these geometric entities are referred to as points.
112. How to iterate over the entities of interest (for example, points) to produce updates to the numerical values associated with the entities in
12  the PETSc vectors or arrays.
133. How to store/access the "connectivity information" that is needed at each entity (point) and provides the correct data dependencies
14   needed to compute the numerical updates.
15
16For several `DM` we will devote a short paragraph for each of the three problems.
17
18## DMDA simple structured grids
19
20For 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$,
21and $l_k \le k \le u_k.$ `DMDAVecGetArray()` returns a multidimensional array that trivially provides the mapping from said points to the numerical values.
22Note that when the programming language gives access to the values in a multi-dimensional array,
23internally 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
25To iterate over the local points, one uses `DMDAGetCorners()` or `DMDAGetGhostCorners()` and iterates over the tuples within the bounds. Specific points, for example
26boundary points, can be skipped or processed differently based on the index values.
27
28For finite difference methods on structured grids using a stencil formula, the "connectivity information" is defined implicitly by the stencil needed
29by the given discretization and is the same for all grid points (except maybe boundaries or other special points). For example, for the standard
30seven 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)$,
31and $(i, j, k \pm 1)$ entities.
32
33## DMSTAG simple stagger grids
34
35A 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)
36as with `DMDA`
37but 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
38numerical 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,
39edge, or face of the cell we are referring to. This is done using `DMStagStencilLocation`. `DMStagVecGetArray()` returns a multidimensional array indexed
40by $(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
41number of numerical values associated with a given entity type, the function `DMStagGetLocationSlot()` provides the final index needed for the array access. After
42this the programming language than computes the `offset` from the beginning of the array from the provided indices using a simple formula.
43
44To iterate over the local points, one uses `DMStagGetCorners()` or `DMStagGetGhostCorners()` and iterates over the tuples within the bounds with an inner iteration
45of the point entities desired for the application. For example, for a discretization with cell-centered pressures and edge-based velocity the application
46would process each of these entities.
47
48For finite difference methods on staggered structured grids using a stencil formula the "connectivity information" is again defined implicitly by the stencil needed
49by 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
50different entities needs to be encoded for the given problem. For example, how do the velocities affect the pressure equation. This information is generally
51embedded directly in lines of code that implement the finite difference formula and is not represented in the data structures.
52
53
54## DMPLEX unstructured meshes
55
56For general unstructured grids, {any}`ch_unstructured`, there is no formula for computing the `offset` into the numerical values
57for 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 on the grid, PDE, and discretization. Hence all the offsets
59must be managed by `DMPLEX`. This is the job of `PetscSection`, {any}`ch_petscsection`. The process of building a `PetscSection` computes
60and stores the offsets and then using the `PetscSection` gives access to the needed offsets.
61
62For 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
63a particular entity. For example, when using the finite element method, the application iterates all the points representing elements (cells) using
64`DMPlexGetHeightStratum()` to access the chart (beginning and end indices) of the cell entities. Then one uses an associated `PetscSection` to determine the offsets into
65vectors or arrays for said points. If needed one can then have an inner iteration over the fields associated with the cell.
66
67For `DMPLEX`, the connectivity information is defined by a graph (and stored explicitly in a data structure used to store graphs),
68and the connectivity of a point (entity) is obtained by `DMPlexGetTransitiveClosure()`.
69
70
71## DMNETWORK computations on graphs of nodes and connecting edges
72
73For networks, {any}`ch_network`, the entities are nodes and edges that connect two nodes, each of which can have any number of submodels.
74Again, in general, there is no formula that can produce the
75appropriate `offset` into the numerical values for a given `point` (node or edge) directly. The routines `DMNetworkGetLocalVecOffset()`
76and `DMNetworkGetGlobalVecOffset()`
77are used to obtain the needed offsets from a given point (node or edge) and submodel at that point. Internally a `PetscSection` is used to
78manage the storage of the `offset` information but the user-level API does not refer to `PetscSection` directly, rather one thinks about
79a collection of submodels at each node and edge of the graph.
80
81To iterate over graph vertices (nodes) one uses `DMNetworkGetVertexRange()` to provide its chart (the starting and end indices)
82and `DMNetworkGetEdgeRange()` to provide the chart of the edges. One can then iterate over the models on each point
83To iterate over sub-networks one can call `DMNetworkGetSubnetwork()` for each network which
84returns lists of the vertex and edge points in said network.
85
86For `DMNETWORK`, the connectivity information is defined by a graph, which is is query-able at each entity by
87`DMNetworkGetSupportingEdges()` and `DMNetworkGetConnectedVertices()`.
88
89# Is it a programming language issue?
90
91Regarding 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(in particular `PetscSection` come from the limitation of programming languages when working
93with complex multidimensional jagged arrays. Both in constructing such arrays at runtime, that is supplying all the jagged information which depends
94on the exact problem, and then providing simple syntax to produce the correct offset into the
95memory for accessing the numerical values when the simple array access methods do not work.
96
97
98
99
100
101
102