Actual source code: ex3.c

  1: static char help[] = "Test query functions for DMNetwork \n\n";

  3: #include <petscdmnetwork.h>

  5: /*
  6: CreateStarGraphEdgeList - Create a k-Star Graph Edgelist on current processor
  7:   Not Collective

  9:   Input Parameters:
 10: . k    - order of the star graph (number of edges)
 11: . directin - if true direction of edges is towards the center vertex, otherwise they are directed out of the center vertex.

 13:   Output Parameters:
 14: .  ne - number of edges of this star graph
 15: .  edgelist - list of edges for this star graph, this is a one dimensional array with pairs of entries being the two vertices (in global numbering of the vertices) of each edge,
 16:               [first vertex of first edge, second vertex of first edge, first vertex of second edge, second vertex of second edge, etc].

 18:               User is responsible for deallocating this memory.
 19: */
 20: PetscErrorCode StarGraphCreateEdgeList(PetscInt k, PetscBool directin, PetscInt *ne, PetscInt *edgelist[])
 21: {
 22:   PetscFunctionBeginUser;
 23:   *ne = k;
 24:   PetscCall(PetscCalloc1(2 * k, edgelist));

 26:   if (directin) {
 27:     for (PetscInt i = 0; i < k; i++) {
 28:       (*edgelist)[2 * i]     = i + 1;
 29:       (*edgelist)[2 * i + 1] = 0;
 30:     }
 31:   } else {
 32:     for (PetscInt i = 0; i < k; i++) {
 33:       (*edgelist)[2 * i]     = 0;
 34:       (*edgelist)[2 * i + 1] = i + 1;
 35:     }
 36:   }
 37:   PetscFunctionReturn(PETSC_SUCCESS);
 38: }

 40: /*
 41: StarGraphCreate() - Create a distributed k-star graph with integer components on all points and
 42: additional scalar and integer components on edges to exercise component storage alignment and header resizing.

 44:   Input Parameters:
 45: . comm       - the communicator of the dm
 46: . numdofvert - number of degrees of freedom (dofs) on vertices
 47: . numdofedge - number of degrees of freedom (dofs) on edges
 48: . k          - order of the star graph (number of edges)
 49: . directin   - if true direction of edges is towards the center vertex, otherwise they are directed out of the center vertex

 51:   Output Parameter:
 52: . newdm       - The created and distributed simple Star Graph
 53: */
 54: PetscErrorCode StarGraphCreate(MPI_Comm comm, PetscInt numdofvert, PetscInt numdofedge, PetscInt k, PetscBool directin, DM *newdm)
 55: {
 56:   DM          dm;
 57:   PetscMPIInt rank;
 58:   PetscInt    ne        = 0, compkey, scalarkey, eStart, eEnd, vStart, vEnd, e, v;
 59:   PetscInt   *edgelist  = NULL, *compedge, *compvert;
 60:   PetscScalar scalar[2] = {1.25, 2.5};

 62:   PetscFunctionBeginUser;
 63:   PetscCall(DMNetworkCreate(comm, &dm));
 64:   PetscCall(DMNetworkSetNumSubNetworks(dm, PETSC_DECIDE, 1));
 65:   PetscCallMPI(MPI_Comm_rank(comm, &rank));
 66:   if (rank == 0) PetscCall(StarGraphCreateEdgeList(k, directin, &ne, &edgelist));
 67:   PetscCall(DMNetworkAddSubnetwork(dm, "Main", ne, edgelist, NULL));
 68:   PetscCall(DMNetworkRegisterComponent(dm, "unused", sizeof(PetscInt), &compkey));
 69:   PetscCall(DMNetworkRegisterComponent(dm, "scalar", sizeof(scalar), &scalarkey));
 70:   PetscCall(DMNetworkLayoutSetUp(dm));
 71:   PetscCall(PetscFree(edgelist));
 72:   PetscCall(DMNetworkGetEdgeRange(dm, &eStart, &eEnd));
 73:   PetscCall(DMNetworkGetVertexRange(dm, &vStart, &vEnd));
 74:   PetscCall(PetscMalloc2(eEnd - eStart, &compedge, vEnd - vStart, &compvert));
 75:   for (e = eStart; e < eEnd; e++) {
 76:     compedge[e - eStart] = e;
 77:     PetscCall(DMNetworkAddComponent(dm, e, compkey, &compedge[e - eStart], numdofedge));
 78:     PetscCall(DMNetworkAddComponent(dm, e, scalarkey, scalar, 0));
 79:     PetscCall(DMNetworkAddComponent(dm, e, compkey, &compedge[e - eStart], 0));
 80:     PetscCall(DMNetworkAddComponent(dm, e, scalarkey, scalar, 0));
 81:   }
 82:   for (v = vStart; v < vEnd; v++) {
 83:     compvert[v - vStart] = v;
 84:     PetscCall(DMNetworkAddComponent(dm, v, compkey, &compvert[v - vStart], numdofvert));
 85:   }
 86:   PetscCall(DMSetFromOptions(dm));
 87:   PetscCall(DMViewFromOptions(dm, NULL, "-dm_view"));
 88:   PetscCall(DMSetUp(dm));
 89:   PetscCall(PetscFree2(compedge, compvert));
 90:   *newdm = dm;
 91:   PetscFunctionReturn(PETSC_SUCCESS);
 92: }

 94: PetscErrorCode StarGraphTestQuery(DM dm, PetscInt ne)
 95: {
 96:   PetscInt globalnumvert, localnumvert, globalnumedge, localnumedge, eStart, eEnd;

 98:   PetscFunctionBeginUser;
 99:   PetscCall(DMNetworkGetNumEdges(dm, &localnumedge, &globalnumedge));
100:   PetscCall(DMNetworkGetNumVertices(dm, &localnumvert, &globalnumvert));

102:   PetscCheck(globalnumedge == ne, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Global number of edges should be %" PetscInt_FMT "instead was %" PetscInt_FMT, ne, globalnumedge);
103:   PetscCheck(globalnumvert == ne + 1, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Global number of vertices should be %" PetscInt_FMT "instead was %" PetscInt_FMT, ne + 1, globalnumvert);
104:   PetscCall(DMNetworkGetEdgeRange(dm, &eStart, &eEnd));
105:   for (PetscInt e = eStart; e < eEnd; ++e) {
106:     PetscInt ncomp, index;

108:     PetscCall(DMNetworkGetNumComponents(dm, e, &ncomp));
109:     PetscCheck(ncomp == 4, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Expected four edge components, got %" PetscInt_FMT, ncomp);
110:     PetscCall(DMNetworkGetGlobalEdgeIndex(dm, e, &index));
111:     for (PetscInt c = 0; c < ncomp; ++c) {
112:       PetscInt key;

114:       if (c % 2) {
115:         PetscScalar *value;

117:         PetscCall(DMNetworkGetComponent(dm, e, c, &key, &value, NULL));
118:         PetscCheck(key == 1 && value[0] == (PetscScalar)1.25 && value[1] == (PetscScalar)2.5, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Incorrect scalar component");
119:       } else {
120:         PetscInt *value;

122:         PetscCall(DMNetworkGetComponent(dm, e, c, &key, &value, NULL));
123:         PetscCheck(key == 0 && *value == index, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Incorrect integer component");
124:       }
125:     }
126:   }
127:   PetscFunctionReturn(PETSC_SUCCESS);
128: }

130: int main(int argc, char **argv)
131: {
132:   DM          dm;
133:   PetscInt    ne = 1;
134:   PetscMPIInt rank;

136:   PetscFunctionBeginUser;
137:   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
138:   PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &rank));
139:   /* create a distributed k-Star graph DMNetwork */
140:   PetscCall(PetscOptionsGetInt(NULL, NULL, "-ne", &ne, NULL));
141:   PetscCall(StarGraphCreate(PETSC_COMM_WORLD, 1, 0, ne, PETSC_TRUE, &dm));
142:   PetscCall(StarGraphTestQuery(dm, ne));
143:   PetscCall(DMNetworkDistribute(&dm, 0));
144:   /* Test if query functions for DMNetwork run successfully */
145:   PetscCall(StarGraphTestQuery(dm, ne));
146:   PetscCall(DMDestroy(&dm));
147:   PetscCall(PetscFinalize());
148: }

150: /*TEST
151:   test:
152:     suffix: 0
153:     args: -ne 5
154:     output_file: output/empty.out
155:   test:
156:     suffix: 1
157:     nsize: 2
158:     args: -ne 5 -petscpartitioner_type simple
159:     output_file: output/empty.out
160:  TEST*/