Networks#
The DMNETWORK
class provides
abstractions for representing general unstructured networks such as
communication networks, power grid, computer networks, transportation
networks, electrical circuits, graphs, and others.
Application flow#
The general flow of an application code using DMNETWORK
is as
follows:
Create a network object.
DMNetworkCreate(MPI_Comm comm, DM *dm);
Create components and register them with the network. A “component” is specific application data at a vertex/edge of the network required for its residual evaluation. For example, components could be resistor/inductor data for circuit applications, edge weights for graph problems, or generator/transmission line data for power grids. Components are registered by calling
DMNetworkRegisterComponent(DM dm, const char *name, size_t size, PetscInt *compkey);
Here,
name
is the component name,size
is the size of component data, andcompkey
is an integer key that can be used for setting/getting the component at a vertex or an edge.A
DMNETWORK
can consist of one or more physical subnetworks. Each subnetwork has its own mathematical model. When multiple subnetworks are used one can (optionally) provide coupling information between subnetworks. That is vertices that are shared between multiple subnetworks; edges can only belong to a single subnetwork. The number of subnetwork is set by callingDMNetworkSetNumSubNetworks(DM dm, PetscInt nsubnet, PetscInt Nsubnet);
Here,
nsubnet
andNsubnet
are the local and global number of subnetworks.A subnetwork is added to the network by calling
DMNetworkAddSubnetwork(DM dm, const char* name, PetscInt ne, PetscInt edgelist[], PetscInt *netnum);
Here
name
is the subnetwork name,ne
is the number of local edges on the subnetwork, andedgelist
is the connectivity for the subnetwork. The outputnetnum
is the global numbering of the subnetwork in the network. Each element ofedgelist
is an integer array of size2*ne
containing the edge connectivity for the subnetwork.As an example, consider a network comprised of 2 subnetworks that are coupled. The topological information for the network is as follows:subnetwork 0: v0 — v1 — v2 — v3subnetwork 1: v1 — v2 — v0The two subnetworks are coupled by merging vertex 0 from subnetwork 0 with vertex 2 from subnetwork 1.Theedgelist
of this network isedgelist[0] = {0,1,1,2,2,3}edgelist[1] = {1,2,2,0}The coupling is done by calling
Here
anet
andbnet
are the first and second subnetwork global numberings returned byDMNetworkAddSubnetwork()
,nsv
is the number of vertices shared by the two subnetworks,asv
andbsv
are the vertex indices in the subnetworkanet
andbnet
.The next step is to have
DMNETWORK
create a bare layout (graph) of the network by callingDMNetworkLayoutSetUp(DM dm);
After completing the previous steps, the network graph is set up, but no physics is associated yet. This is done by adding the components and setting the number of variables to the vertices and edges.
A component and number of variables are added to a vertex/edge by calling
DMNetworkAddComponent(DM dm, PetscInt p, PetscInt compkey, void* compdata, PetscInt nvar)
where
p
is the network vertex/edge point in the range obtained by eitherDMNetworkGetVertexRange()
/DMNetworkGetEdgeRange()
,DMNetworkGetSubnetwork()
, orDMNetworkGetSharedVertices()
;compkey
is the component key returned when registering the component (DMNetworkRegisterComponent()
);compdata
holds the data for the component; andnvar
is the number of variables associated to the added component at this network point.DMNETWORK
supports setting multiple components 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.DMNETWORK
currently assumes the component data to be stored in a contiguous chunk of memory. As such, it does not do any packing/unpacking before/after the component data gets distributed. Any such serialization (packing/unpacking) should be done by the application.Set up network internal data structures.
Distribute the network (also moves components attached with vertices/edges) to multiple processors.
DMNetworkDistribute(DM dm, const char partitioner[], PetscInt overlap, DM *distDM);
Associate the
DM
with a PETSc solver:
Utility functions#
DMNETWORK
provides several utility functions for operations on the
network. The most commonly used functions are: obtaining iterators for
vertices/edges,
DMNetworkGetEdgeRange(DM dm, PetscInt *eStart, PetscInt *eEnd);
DMNetworkGetVertexRange(DM dm, PetscInt *vStart, PetscInt *vEnd);
checking the status of a vertex,
DMNetworkIsGhostVertex(DM dm, PetscInt p, PetscBool *isghost);
DMNetworkIsSharedVertex(DM dm, PetscInt p, PetscBool *isshared);
and retrieving local/global indices of vertex/edge component variables for inserting elements in vectors/matrices,
DMNetworkGetLocalVecOffset(DM dm, PetscInt p, PetscInt compnum, PetscInt *offset);
DMNetworkGetGlobalVecOffset(DM dm, PetscInt p, PetscInt compnum, PetscInt *offsetg).
In network applications, one frequently needs to find the supporting edges for a vertex or the connecting vertices covering an edge. These can be obtained by the following two routines.
DMNetworkGetConnectedVertices(DM dm, PetscInt edge, const PetscInt *vertices[]);
DMNetworkGetSupportingEdges(DM dm, PetscInt vertex, PetscInt *nedges, const PetscInt *edges[]).
Retrieving components and number of variables#
The components and the corresponding number of variables set at a vertex/edge can be accessed by
input compnum
is the component number, output compkey
is the key set by DMNetworkRegisterComponent()
. An example
of accessing and retrieving the components and number of variables at vertices is:
PetscInt Start,End,numcomps,key,v,compnum;
void *component;
DMNetworkGetVertexRange(dm, &Start, &End);
for (v = Start; v < End; v++) {
DMNetworkGetNumComponents(dm, v, &numcomps);
for (compnum=0; compnum < numcomps; compnum++) {
DMNetworkGetComponent(dm, v, compnum, &key, &component, &nvar);
compdata = (UserCompDataType)(component);
}
}
The above example does not explicitly use the component key. It is
used when different component types are set at different vertices. In
this case, compkey
is used to differentiate the component type.