Actual source code: ex1.c

  1: static char help[] = "Check if DMClone for DMNetwork Correctly Shallow Clones Topology Only \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 CreateStarGraphEdgeList(PetscInt k, PetscBool directin, PetscInt *ne, PetscInt *edgelist[])
 21: {
 22:   PetscInt i;

 24:   PetscFunctionBegin;
 25:   *ne = k;
 26:   PetscCall(PetscCalloc1(2 * k, edgelist));

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

 42: /*
 43: CreateSimpleStarGraph - Create a Distributed k-Star Graph DMNetwork with a single PetscInt component on
 44: all edges and vertices, aselectable number of dofs on vertices and edges. Intended mostly to be used for testing purposes.

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

 53:   Output Parameter:
 54: . newdm       - The created and distributed simple Star Graph
 55: */
 56: PetscErrorCode CreateSimpleStarGraph(MPI_Comm comm, PetscInt numdofvert, PetscInt numdofedge, PetscInt k, PetscBool directin, DM *newdm)
 57: {
 58:   DM          dm;
 59:   PetscMPIInt rank;
 60:   PetscInt    ne       = 0, compkey, eStart, eEnd, vStart, vEnd, e, v;
 61:   PetscInt   *edgelist = NULL, *compedge, *compvert;

 63:   PetscFunctionBegin;
 64:   PetscCall(DMNetworkCreate(comm, &dm));
 65:   PetscCall(DMNetworkSetNumSubNetworks(dm, PETSC_DECIDE, 1));
 66:   PetscCallMPI(MPI_Comm_rank(comm, &rank));
 67:   if (rank == 0) PetscCall(CreateStarGraphEdgeList(k, directin, &ne, &edgelist));
 68:   PetscCall(DMNetworkAddSubnetwork(dm, "Main", ne, edgelist, NULL));
 69:   PetscCall(DMNetworkRegisterComponent(dm, "dummy", sizeof(PetscInt), &compkey));
 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:   }
 79:   for (v = vStart; v < vEnd; v++) {
 80:     compvert[v - vStart] = v;
 81:     PetscCall(DMNetworkAddComponent(dm, v, compkey, &compvert[v - vStart], numdofvert));
 82:   }
 83:   PetscCall(DMSetFromOptions(dm));
 84:   PetscCall(DMViewFromOptions(dm, NULL, "-dm_view"));
 85:   PetscCall(DMSetUp(dm));
 86:   PetscCall(PetscFree2(compedge, compvert));
 87:   PetscCall(DMNetworkDistribute(&dm, 0));
 88:   *newdm = dm;
 89:   PetscFunctionReturn(PETSC_SUCCESS);
 90: }

 92: int main(int argc, char **argv)
 93: {
 94:   DM           dm, dmclone, plex;
 95:   PetscInt     e, eStart, eEnd, ndofs, ndofsprev;
 96:   PetscInt    *compprev, *comp, compkey;
 97:   PetscInt     dofv = 1, dofe = 1, ne = 1;
 98:   PetscSection sec;
 99:   Vec          vec;

101:   PetscFunctionBeginUser;
102:   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
103:   /* create a distributed k-Star graph DMNetwork */
104:   PetscCall(PetscOptionsGetInt(NULL, NULL, "-dofv", &dofv, NULL));
105:   PetscCall(PetscOptionsGetInt(NULL, NULL, "-dofe", &dofe, NULL));
106:   PetscCall(PetscOptionsGetInt(NULL, NULL, "-ne", &ne, NULL));
107:   PetscCall(CreateSimpleStarGraph(PETSC_COMM_WORLD, dofv, dofe, ne, PETSC_TRUE, &dm));
108:   PetscCall(DMNetworkGetEdgeRange(dm, &eStart, &eEnd));

110:   /* check if cloning changed any component */
111:   if (eStart < eEnd) PetscCall(DMNetworkGetComponent(dm, eStart, 0, NULL, (void **)&compprev, &ndofsprev));
112:   PetscCall(DMClone(dm, &dmclone));
113:   if (eStart < eEnd) {
114:     PetscCall(DMNetworkGetComponent(dm, eStart, 0, NULL, (void **)&comp, &ndofs));
115:     PetscCheck(*comp == *compprev, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Cloning changed the Original, comp (previous) : %" PetscInt_FMT " comp (now) : %" PetscInt_FMT, *compprev, *comp);
116:     PetscCheck(ndofsprev == ndofs, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Cloning changed the Original, ndofs (previous) : %" PetscInt_FMT " ndofs (now) : %" PetscInt_FMT, ndofsprev, ndofs);
117:   }

119:   /* register new components to the clone and add a dummy component to every point */
120:   PetscCall(DMNetworkRegisterComponent(dmclone, "dummyclone", sizeof(PetscInt), &compkey));
121:   PetscCall(DMNetworkGetEdgeRange(dmclone, &eStart, &eEnd));
122:   PetscCall(PetscMalloc1(eEnd - eStart, &comp));
123:   for (e = eStart; e < eEnd; e++) {
124:     comp[e - eStart] = e;
125:     PetscCall(DMNetworkAddComponent(dmclone, e, compkey, &comp[e - eStart], 2));
126:   }
127:   PetscCall(DMNetworkFinalizeComponents(dmclone));
128:   PetscCall(PetscFree(comp));

130:   PetscCall(PetscPrintf(PETSC_COMM_WORLD, " dm: \n"));
131:   PetscCall(DMView(dm, PETSC_VIEWER_STDOUT_WORLD));
132:   PetscCall(DMNetworkGetPlex(dm, &plex));
133:   PetscCall(DMGetLocalSection(plex, &sec));
134:   PetscCall(PetscSectionView(sec, PETSC_VIEWER_STDOUT_WORLD));

136:   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "\n dmclone: \n"));
137:   PetscCall(DMView(dmclone, PETSC_VIEWER_STDOUT_WORLD));
138:   PetscCall(DMNetworkGetPlex(dmclone, &plex));
139:   PetscCall(DMGetLocalSection(plex, &sec));
140:   PetscCall(PetscSectionView(sec, PETSC_VIEWER_STDOUT_WORLD));

142:   /* create Vectors */
143:   PetscCall(DMCreateGlobalVector(dm, &vec));
144:   PetscCall(VecSet(vec, 1.0));
145:   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "\n dm vec:\n"));
146:   PetscCall(VecView(vec, PETSC_VIEWER_STDOUT_WORLD));
147:   PetscCall(VecDestroy(&vec));

149:   PetscCall(DMCreateGlobalVector(dmclone, &vec));
150:   PetscCall(VecSet(vec, 2.0));
151:   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "\n dmclone vec:\n"));
152:   PetscCall(VecView(vec, PETSC_VIEWER_STDOUT_WORLD));
153:   PetscCall(VecDestroy(&vec));

155:   PetscCall(DMDestroy(&dm));
156:   PetscCall(DMDestroy(&dmclone));
157:   PetscCall(PetscFinalize());
158: }

160: /*TEST

162:   test:
163:     suffix: 0
164:     args:

166:   test:
167:     suffix: 1
168:     nsize: 2
169:     args: -dofv 2 -dofe 2 -ne 2

171:  TEST*/