xref: /petsc/doc/manual/dmnetwork.md (revision b11d9968bc79904c690b122f9399be46447eb113)
1(ch_network)=
2
3# Networks
4
5The `DMNETWORK` class provides
6abstractions for representing general unstructured networks such as
7communication networks, power grid, computer networks, transportation
8networks, electrical circuits, graphs, and others.
9
10## Application flow
11
12The general flow of an application code using `DMNETWORK` is as
13follows:
14
151. Create a network object.
16
17   ```
18   DMNetworkCreate(MPI_Comm comm, DM *dm);
19   ```
20
212. Create components and register them with the network. A “component”
22   is specific application data at a vertex/edge of the network required
23   for its residual evaluation. For example, components could be
24   resistor/inductor data for circuit applications, edge weights for
25   graph problems, or generator/transmission line data for power grids.
26   Components are registered by calling
27
28   ```
29   DMNetworkRegisterComponent(DM dm, const char *name, size_t size, PetscInt *compkey);
30   ```
31
32   Here, `name` is the component name, `size` is the size of
33   component data, and `compkey` is an integer key that can be
34   used for setting/getting the component at a vertex or an edge.
35
363. A `DMNETWORK` can consist of one or more physical subnetworks. Each subnetwork has its own mathematical model. When
37   multiple subnetworks are used one can (optionally) provide
38   coupling information between subnetworks. That is vertices that are *shared* between multiple subnetworks; edges can only belong to a single subnetwork. The
39   number of subnetwork is set by calling
40
41   ```
42   DMNetworkSetNumSubNetworks(DM dm, PetscInt nsubnet, PetscInt Nsubnet);
43   ```
44
45   Here, `nsubnet` and `Nsubnet` are the local and global number of subnetworks.
46
474. A subnetwork is added to the network by calling
48
49   ```
50   DMNetworkAddSubnetwork(DM dm, const char* name, PetscInt ne, PetscInt edgelist[], PetscInt *netnum);
51   ```
52
53   Here `name` is the subnetwork name, `ne` is the number of local edges on the subnetwork, and `edgelist` is the connectivity for the subnetwork.
54   The output `netnum` is the global numbering of the subnetwork in the network.
55   Each element of `edgelist` is an integer array of size `2*ne`
56   containing the edge connectivity for the subnetwork.
57
58   As an example, consider a network comprised of 2 subnetworks that
59   are coupled. The topological information for the network is as
60   follows:
61
62   subnetwork 0: v0 — v1 — v2 — v3
63
64   subnetwork 1: v1 — v2 — v0
65
66   The two subnetworks are coupled by merging vertex 0 from subnetwork 0 with vertex 2 from subnetwork 1.
67
68   The
69
70   `edgelist`
71
72    of this network is
73
74   edgelist[0] = {0,1,1,2,2,3}
75
76   edgelist[1] = {1,2,2,0}
77
78   The coupling is done by calling
79
80   ```
81   DMNetworkAddSharedVertices(DM dm, PetscInt anet, PetscInt bnet, PetscInt nsv, PetscInt asv[], PetscInt bsv[]);
82   ```
83
84   Here `anet` and `bnet` are the first and second subnetwork global numberings returned by `DMNetworkAddSubnetwork()`,
85   `nsv` is the number of vertices shared by the two subnetworks, `asv` and `bsv` are the vertex indices in the subnetwork `anet` and `bnet` .
86
875. The next step is to have `DMNETWORK` create a bare layout (graph) of
88   the network by calling
89
90   ```
91   DMNetworkLayoutSetUp(DM dm);
92   ```
93
946. After completing the previous steps, the network graph is set up, but
95   no physics is associated yet. This is done by adding the components
96   and setting the number of variables to the vertices and edges.
97
98   A component and number of variables are added to a vertex/edge by calling
99
100   ```
101   DMNetworkAddComponent(DM dm, PetscInt p, PetscInt compkey, void* compdata, PetscInt nvar)
102   ```
103
104   where `p` is the network vertex/edge point in the range obtained by
105   either `DMNetworkGetVertexRange()`/`DMNetworkGetEdgeRange()`, `DMNetworkGetSubnetwork()`, or `DMNetworkGetSharedVertices()`;
106   `compkey` is the component key returned when registering the component
107   (`DMNetworkRegisterComponent()`); `compdata` holds the data for the
108   component; and `nvar` is the number of variables associated to the added component at this network point. `DMNETWORK` supports setting multiple components
109   at a vertex/edge. At a shared vertex, `DMNETWORK` currently requires the owner process of the vertex adds all the components and number of variables.
110
111   `DMNETWORK` currently assumes the component data to be stored in a
112   contiguous chunk of memory. As such, it does not do any
113   packing/unpacking before/after the component data gets distributed.
114   Any such serialization (packing/unpacking) should be done by the
115   application.
116
1177. Set up network internal data structures.
118
119   ```
120   DMSetUp(DM dm);
121   ```
122
1238. Distribute the network (also moves components attached with
124   vertices/edges) to multiple processors.
125
126   ```
127   DMNetworkDistribute(DM dm, const char partitioner[], PetscInt overlap, DM *distDM);
128   ```
129
1309. Associate the `DM` with a PETSc solver:
131
132   ```
133   KSPSetDM(KSP ksp, DM dm) or SNESSetDM(SNES snes, DM dm) or TSSetDM(TS ts, DM dm).
134   ```
135
136## Utility functions
137
138`DMNETWORK` provides several utility functions for operations on the
139network. The most commonly used functions are: obtaining iterators for
140vertices/edges,
141
142```
143DMNetworkGetEdgeRange(DM dm, PetscInt *eStart, PetscInt *eEnd);
144```
145
146```
147DMNetworkGetVertexRange(DM dm, PetscInt *vStart, PetscInt *vEnd);
148```
149
150```
151DMNetworkGetSubnetwork(DM dm, PetscInt netnum, PetscInt *nv, PetscInt *ne, const PetscInt **vtx, const PetscInt **edge);
152```
153
154checking the status of a vertex,
155
156```
157DMNetworkIsGhostVertex(DM dm, PetscInt p, PetscBool *isghost);
158```
159
160```
161DMNetworkIsSharedVertex(DM dm, PetscInt p, PetscBool *isshared);
162```
163
164and retrieving local/global indices of vertex/edge component variables for
165inserting elements in vectors/matrices,
166
167```
168DMNetworkGetLocalVecOffset(DM dm, PetscInt p, PetscInt compnum, PetscInt *offset);
169```
170
171```
172DMNetworkGetGlobalVecOffset(DM dm, PetscInt p, PetscInt compnum, PetscInt *offsetg).
173```
174
175In network applications, one frequently needs to find the supporting
176edges for a vertex or the connecting vertices covering an edge. These
177can be obtained by the following two routines.
178
179```
180DMNetworkGetConnectedVertices(DM dm, PetscInt edge, const PetscInt *vertices[]);
181```
182
183```
184DMNetworkGetSupportingEdges(DM dm, PetscInt vertex, PetscInt *nedges, const PetscInt *edges[]).
185```
186
187## Retrieving components and number of variables
188
189The components and the corresponding number of variables set at a vertex/edge can be accessed by
190
191```
192DMNetworkGetComponent(DM dm, PetscInt p, PetscInt compnum, PetscInt *compkey, void **component, PetscInt *nvar)
193```
194
195input `compnum` is the component number, output `compkey` is the key set by `DMNetworkRegisterComponent()`. An example
196of accessing and retrieving the components and number of variables at vertices is:
197
198```
199PetscInt Start,End,numcomps,key,v,compnum;
200void *component;
201
202DMNetworkGetVertexRange(dm, &Start, &End);
203for (v = Start; v < End; v++) {
204  DMNetworkGetNumComponents(dm, v, &numcomps);
205  for (compnum=0; compnum < numcomps; compnum++) {
206    DMNetworkGetComponent(dm, v, compnum, &key, &component, &nvar);
207    compdata = (UserCompDataType)(component);
208  }
209}
210```
211
212The above example does not explicitly use the component key. It is
213used when different component types are set at different vertices. In
214this case, `compkey` is used to differentiate the component type.
215
216```{eval-rst}
217.. bibliography:: /petsc.bib
218    :filter: docname in docnames
219
220```
221