xref: /petsc/src/dm/tests/ex10.c (revision ffeef943c8ee50edff320d8a3135bb0c94853e4c)
1 /*
2     Simple example demonstrating creating a one sub-network DMNetwork in parallel.
3 
4     In this example vertices 0 and 1 are not connected to any edges.
5 */
6 
7 #include <petscdmnetwork.h>
8 
9 int main(int argc, char **argv)
10 {
11   DM              network;
12   PetscMPIInt     size, rank;
13   MPI_Comm        comm;
14   PetscInt        e, ne, nv, v, ecompkey, vcompkey;
15   PetscInt       *edgelist = NULL;
16   const PetscInt *nodes, *edges;
17   DM              plex;
18   PetscSection    section;
19   PetscInt        Ne, Ni;
20   PetscInt        nodeOffset, k = 2, nedge;
21 
22   PetscFunctionBeginUser;
23   PetscCall(PetscInitialize(&argc, &argv, NULL, NULL));
24   PetscCall(PetscOptionsSetValue(NULL, "-petscpartitioner_use_vertex_weights", "No"));
25   comm = PETSC_COMM_WORLD;
26   PetscCallMPI(MPI_Comm_rank(comm, &rank));
27   PetscCallMPI(MPI_Comm_size(comm, &size));
28 
29   PetscCall(DMNetworkCreate(PETSC_COMM_WORLD, &network));
30 
31   /* Register zero size components to get compkeys to be used by DMNetworkAddComponent() */
32   PetscCall(DMNetworkRegisterComponent(network, "ecomp", 0, &ecompkey));
33   PetscCall(DMNetworkRegisterComponent(network, "vcomp", 0, &vcompkey));
34 
35   Ne         = 2;
36   Ni         = 1;
37   nodeOffset = (Ne + Ni) * rank; /* The global node index of the first node defined on this process */
38 
39   /* There are three nodes on each rank and two edges. The edges only connect nodes on the given rank */
40   nedge = k * Ni;
41 
42   if (rank == 0) {
43     nedge = 1;
44     PetscCall(PetscCalloc1(2 * nedge, &edgelist));
45     edgelist[0] = nodeOffset + 2;
46     edgelist[1] = nodeOffset + 3;
47   } else {
48     nedge = 2;
49     PetscCall(PetscCalloc1(2 * nedge, &edgelist));
50     edgelist[0] = nodeOffset + 0;
51     edgelist[1] = nodeOffset + 2;
52     edgelist[2] = nodeOffset + 1;
53     edgelist[3] = nodeOffset + 2;
54   }
55 
56   PetscCall(DMNetworkSetNumSubNetworks(network, PETSC_DECIDE, 1));
57   PetscCall(DMNetworkAddSubnetwork(network, "Subnetwork 1", nedge, edgelist, NULL));
58   PetscCall(DMNetworkLayoutSetUp(network));
59 
60   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Network after DMNetworkLayoutSetUp:\n"));
61   PetscCall(DMView(network, PETSC_VIEWER_STDOUT_WORLD));
62 
63   /* Add components and variables for the network */
64   PetscCall(DMNetworkGetSubnetwork(network, 0, &nv, &ne, &nodes, &edges));
65   for (e = 0; e < ne; e++) {
66     /* The edges have no degrees of freedom */
67     PetscCall(DMNetworkAddComponent(network, edges[e], ecompkey, NULL, 1));
68   }
69   for (v = 0; v < nv; v++) PetscCall(DMNetworkAddComponent(network, nodes[v], vcompkey, NULL, 2));
70 
71   PetscCall(DMSetUp(network));
72   PetscCall(DMNetworkGetPlex(network, &plex));
73   /* PetscCall(DMView(plex,PETSC_VIEWER_STDOUT_WORLD)); */
74   PetscCall(DMGetLocalSection(plex, &section));
75   PetscCall(PetscSectionView(section, PETSC_VIEWER_STDOUT_WORLD));
76 
77   PetscCall(PetscFree(edgelist));
78 
79   PetscCall(DMNetworkDistribute(&network, 0));
80   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "\nNetwork after DMNetworkDistribute:\n"));
81   PetscCall(DMView(network, PETSC_VIEWER_STDOUT_WORLD));
82   PetscCall(DMNetworkGetPlex(network, &plex));
83   /* PetscCall(DMView(plex,PETSC_VIEWER_STDOUT_WORLD)); */
84   PetscCall(DMGetLocalSection(plex, &section));
85   PetscCall(PetscSectionView(section, PETSC_VIEWER_STDOUT_WORLD));
86 
87   PetscCall(DMDestroy(&network));
88   PetscCall(PetscFinalize());
89   return 0;
90 }
91 
92 /*TEST
93 
94    build:
95       requires: !complex double
96 
97    test:
98       nsize: 2
99       args: -petscpartitioner_type simple
100 
101 TEST*/
102