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