xref: /petsc/src/dm/tests/ex10.c (revision ebead697dbf761eb322f829370bbe90b3bd93fa3)
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++) {
70     PetscCall(DMNetworkAddComponent(network,nodes[v],vcompkey,NULL,2));
71   }
72 
73   PetscCall(DMSetUp(network));
74   PetscCall(DMNetworkGetPlex(network,&plex));
75   /* PetscCall(DMView(plex,PETSC_VIEWER_STDOUT_WORLD)); */
76   PetscCall(DMGetLocalSection(plex,&section));
77   PetscCall(PetscSectionView(section,PETSC_VIEWER_STDOUT_WORLD));
78 
79   PetscCall(PetscFree(edgelist));
80 
81   PetscCall(DMNetworkDistribute(&network,0));
82   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"\nNetwork after DMNetworkDistribute:\n"));
83   PetscCall(DMView(network,PETSC_VIEWER_STDOUT_WORLD));
84   PetscCall(DMNetworkGetPlex(network,&plex));
85   /* PetscCall(DMView(plex,PETSC_VIEWER_STDOUT_WORLD)); */
86   PetscCall(DMGetLocalSection(plex,&section));
87   PetscCall(PetscSectionView(section,PETSC_VIEWER_STDOUT_WORLD));
88 
89   PetscCall(DMDestroy(&network));
90   PetscCall(PetscFinalize());
91   return 0;
92 }
93 
94 /*TEST
95 
96    build:
97       requires: !complex double
98 
99    test:
100       nsize: 2
101       args: -petscpartitioner_type simple
102 
103 TEST*/
104