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