Actual source code: ex2.c

  1: static char help[] = "Test DMCreateCoordinateDM_Network, and related functions \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: static PetscErrorCode StarGraphCreateEdgeList(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: /* Simple Circular embedding of the star graph */
 43: static PetscErrorCode StarGraphSetCoordinates(DM dm, PetscReal *vcolor)
 44: {
 45:   DM           cdm;
 46:   Vec          Coord;
 47:   PetscScalar *coord;
 48:   PetscInt     vStart, vEnd, v, vglobal, compkey = 0, off, NVert;
 49:   PetscReal    theta;

 51:   PetscFunctionBegin;
 52:   PetscCall(DMSetCoordinateDim(dm, 2));
 53:   PetscCall(DMGetCoordinateDM(dm, &cdm));

 55:   PetscCall(DMNetworkGetVertexRange(cdm, &vStart, &vEnd));
 56:   PetscCall(DMNetworkRegisterComponent(cdm, "coordinate", sizeof(PetscReal), &compkey));
 57:   for (v = vStart; v < vEnd; v++) {
 58:     PetscCall(DMNetworkGetGlobalVertexIndex(cdm, v, &vglobal));
 59:     vcolor[v - vStart] = vglobal;
 60:     PetscCall(DMNetworkAddComponent(cdm, v, compkey, &vcolor[v - vStart], 2));
 61:   }
 62:   PetscCall(DMNetworkFinalizeComponents(cdm));

 64:   PetscCall(DMCreateLocalVector(cdm, &Coord));
 65:   PetscCall(VecGetArray(Coord, &coord));
 66:   PetscCall(DMNetworkGetNumVertices(cdm, NULL, &NVert));
 67:   theta = 2 * PETSC_PI / (NVert - 1);
 68:   for (v = vStart; v < vEnd; v++) {
 69:     PetscCall(DMNetworkGetGlobalVertexIndex(cdm, v, &vglobal));
 70:     PetscCall(DMNetworkGetLocalVecOffset(cdm, v, 0, &off));
 71:     if (vglobal == 0) {
 72:       coord[off]     = 0.0;
 73:       coord[off + 1] = 0.0;
 74:     } else {
 75:       /* embed on the unit circle */
 76:       coord[off]     = PetscCosReal(theta * (vglobal - 1));
 77:       coord[off + 1] = PetscSinReal(theta * (vglobal - 1));
 78:     }
 79:   }
 80:   PetscCall(VecRestoreArray(Coord, &coord));
 81:   PetscCall(DMSetCoordinatesLocal(dm, Coord));
 82:   PetscCall(VecDestroy(&Coord));
 83:   PetscFunctionReturn(PETSC_SUCCESS);
 84: }

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

 90:   Input Parameters:
 91: . comm       - the communicator of the dm
 92: . numdofvert - number of degrees of freedom (dofs) on vertices
 93: . numdofedge - number of degrees of freedom (dofs) on edges
 94: . k          - order of the star graph (number of edges)
 95: . directin   - if true direction of edges is towards the center vertex, otherwise they are directed out of the center vertex

 97:   Output Parameters:
 98: . newdm       - The created and distributed simple Star Graph
 99: */
100: static PetscErrorCode StarGraphCreate(MPI_Comm comm, PetscInt numdofvert, PetscInt numdofedge, PetscInt k, PetscBool directin, DM *newdm)
101: {
102:   DM          dm;
103:   PetscMPIInt rank;
104:   PetscInt    ne       = 0, compkey, eStart, eEnd, vStart, vEnd, e, v;
105:   PetscInt   *edgelist = NULL, *compedge, *compvert;
106:   PetscReal  *vcolor;

108:   PetscFunctionBegin;
109:   PetscCall(DMNetworkCreate(comm, &dm));
110:   PetscCall(DMNetworkSetNumSubNetworks(dm, PETSC_DECIDE, 1));
111:   PetscCallMPI(MPI_Comm_rank(comm, &rank));
112:   if (rank == 0) PetscCall(StarGraphCreateEdgeList(k, directin, &ne, &edgelist));
113:   PetscCall(DMNetworkAddSubnetwork(dm, "Main", ne, edgelist, NULL));
114:   PetscCall(DMNetworkRegisterComponent(dm, "dummy", sizeof(PetscInt), &compkey));
115:   PetscCall(DMNetworkLayoutSetUp(dm));
116:   PetscCall(PetscFree(edgelist));
117:   PetscCall(DMNetworkGetEdgeRange(dm, &eStart, &eEnd));
118:   PetscCall(DMNetworkGetVertexRange(dm, &vStart, &vEnd));
119:   PetscCall(PetscCalloc3(eEnd - eStart, &compedge, vEnd - vStart, &compvert, vEnd - vStart, &vcolor));
120:   for (e = eStart; e < eEnd; e++) {
121:     compedge[e - eStart] = e;
122:     PetscCall(DMNetworkAddComponent(dm, e, compkey, &compedge[e - eStart], numdofedge));
123:   }
124:   for (v = vStart; v < vEnd; v++) {
125:     compvert[v - vStart] = v;
126:     PetscCall(DMNetworkAddComponent(dm, v, compkey, &compvert[v - vStart], numdofvert));
127:   }

129:   PetscCall(StarGraphSetCoordinates(dm, vcolor));

131:   PetscCall(DMSetFromOptions(dm));
132:   PetscCall(DMSetUp(dm));
133:   PetscCall(PetscFree3(compedge, compvert, vcolor));

135:   *newdm = dm;
136:   PetscFunctionReturn(PETSC_SUCCESS);
137: }

139: /* This subroutine is used in petsc/src/snes/tutorials/network/ex1.c */
140: static PetscErrorCode CoordinatePrint(DM dm)
141: {
142:   DM                 dmclone;
143:   PetscInt           cdim, v, off, vglobal, vStart, vEnd;
144:   const PetscScalar *carray;
145:   Vec                coords;
146:   MPI_Comm           comm;
147:   PetscMPIInt        rank;

149:   PetscFunctionBegin;
150:   PetscCall(PetscObjectGetComm((PetscObject)dm, &comm));
151:   PetscCallMPI(MPI_Comm_rank(comm, &rank));

153:   PetscCall(DMGetCoordinateDM(dm, &dmclone));
154:   PetscCall(DMNetworkGetVertexRange(dm, &vStart, &vEnd));
155:   PetscCall(DMGetCoordinatesLocal(dm, &coords));

157:   PetscCall(DMGetCoordinateDim(dm, &cdim));
158:   PetscCall(VecGetArrayRead(coords, &carray));

160:   PetscCall(PetscPrintf(MPI_COMM_WORLD, "\nCoordinatePrint, cdim %" PetscInt_FMT ":\n", cdim));
161:   PetscCall(PetscSynchronizedPrintf(MPI_COMM_WORLD, "[%d]\n", rank));
162:   for (v = vStart; v < vEnd; v++) {
163:     PetscCall(DMNetworkGetLocalVecOffset(dmclone, v, 0, &off));
164:     PetscCall(DMNetworkGetGlobalVertexIndex(dmclone, v, &vglobal));
165:     switch (cdim) {
166:     case 2:
167:       PetscCall(PetscSynchronizedPrintf(MPI_COMM_WORLD, "Vertex: %" PetscInt_FMT ", x =  %f y = %f \n", vglobal, (double)PetscRealPart(carray[off]), (double)PetscRealPart(carray[off + 1])));
168:       break;
169:     default:
170:       PetscCheck(cdim == 2, MPI_COMM_WORLD, PETSC_ERR_SUP, "Only supports Network embedding dimension of 2, not supplied  %" PetscInt_FMT, cdim);
171:       break;
172:     }
173:   }
174:   PetscCall(PetscSynchronizedFlush(MPI_COMM_WORLD, NULL));
175:   PetscCall(VecRestoreArrayRead(coords, &carray));
176:   PetscFunctionReturn(PETSC_SUCCESS);
177: }

179: int main(int argc, char **argv)
180: {
181:   DM          dm;
182:   PetscInt    dofv = 1, dofe = 1, ne = 1;
183:   PetscMPIInt rank;
184:   PetscBool   viewCSV = PETSC_FALSE;

186:   PetscFunctionBeginUser;
187:   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
188:   PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &rank));

190:   /* create a distributed k-Star graph DMNetwork */
191:   PetscCall(PetscOptionsGetInt(NULL, NULL, "-dofv", &dofv, NULL));
192:   PetscCall(PetscOptionsGetInt(NULL, NULL, "-dofe", &dofe, NULL));
193:   PetscCall(PetscOptionsGetInt(NULL, NULL, "-ne", &ne, NULL));
194:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-viewCSV", &viewCSV, NULL));

196:   /* create and setup a quick R^2 embedding of the star graph */
197:   PetscCall(StarGraphCreate(PETSC_COMM_WORLD, dofv, dofe, ne, PETSC_TRUE, &dm));

199:   PetscCall(DMNetworkDistribute(&dm, 0));
200:   if (viewCSV) { /* CSV View of network with coordinates */
201:     PetscCall(PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_CSV));
202:     PetscCall(DMView(dm, PETSC_VIEWER_STDOUT_WORLD));
203:     PetscCall(PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD));
204:   } else {
205:     PetscCall(DMView(dm, PETSC_VIEWER_STDOUT_WORLD));
206:   }

208:   /* print or view the coordinates of each vertex */
209:   PetscCall(CoordinatePrint(dm));

211:   PetscCall(DMDestroy(&dm));
212:   PetscCall(PetscFinalize());
213: }

215: /*TEST

217:   test:
218:     suffix: 0
219:     args: -ne 4

221:   test:
222:     suffix: 1
223:     nsize: 2
224:     args: -ne 4 -petscpartitioner_type simple

226:  TEST*/