Actual source code: meshpcice.c

  1: #include "src/dm/mesh/meshpcice.h"   /*I      "petscmesh.h"   I*/

  3: namespace ALE {
  4:   namespace PCICE {
  5:     //
  6:     // Builder methods
  7:     //
  8:     void Builder::readConnectivity(MPI_Comm comm, const std::string& filename, int& corners, const bool useZeroBase, int& numElements, int *vertices[]) {
  9:       PetscViewer    viewer;
 10:       FILE          *f;
 11:       PetscInt       numCells, cellCount = 0;
 12:       PetscInt      *verts;
 13:       char           buf[2048];
 14:       PetscInt       c;
 15:       PetscInt       commRank;

 18:       MPI_Comm_rank(comm, &commRank);

 20:       if (commRank != 0) return;
 21:       PetscViewerCreate(PETSC_COMM_SELF, &viewer);
 22:       PetscViewerSetType(viewer, PETSC_VIEWER_ASCII);
 23:       PetscViewerFileSetMode(viewer, FILE_MODE_READ);
 24:       PetscViewerFileSetName(viewer, filename.c_str());
 25:       PetscViewerASCIIGetPointer(viewer, &f);
 26:       if (fgets(buf, 2048, f) == NULL) {
 27:         throw ALE::Exception("Invalid connectivity file: Missing number of elements");
 28:       }
 29:       const char *sizes = strtok(buf, " ");
 30:       numCells = atoi(sizes);
 31:       sizes = strtok(NULL, " ");
 32:       if (sizes != NULL) {
 33:         corners = atoi(sizes);
 34:         std::cout << "Reset corners to " << corners << std::endl;
 35:       }
 36:       PetscMalloc(numCells*corners * sizeof(PetscInt), &verts);
 37:       while(fgets(buf, 2048, f) != NULL) {
 38:         const char *v = strtok(buf, " ");
 39: 
 40:         /* Ignore cell number */
 41:         v = strtok(NULL, " ");
 42:         for(c = 0; c < corners; c++) {
 43:           int vertex = atoi(v);
 44: 
 45:           if (!useZeroBase) vertex -= 1;
 46:           verts[cellCount*corners+c] = vertex;
 47:           v = strtok(NULL, " ");
 48:         }
 49:         cellCount++;
 50:       }
 51:       PetscViewerDestroy(viewer);
 52:       numElements = numCells;
 53:       *vertices = verts;
 54:     };
 55:     void Builder::readCoordinates(MPI_Comm comm, const std::string& filename, const int dim, int& numVertices, double *coordinates[]) {
 56:       PetscViewer    viewer;
 57:       FILE          *f;
 58:       PetscInt       numVerts, vertexCount = 0;
 59:       PetscScalar   *coords;
 60:       char           buf[2048];
 61:       PetscInt       c;
 62:       PetscInt       commRank;

 65:       MPI_Comm_rank(comm, &commRank);

 67:       if (commRank != 0) return;
 68:       PetscViewerCreate(PETSC_COMM_SELF, &viewer);
 69:       PetscViewerSetType(viewer, PETSC_VIEWER_ASCII);
 70:       PetscViewerFileSetMode(viewer, FILE_MODE_READ);
 71:       PetscViewerFileSetName(viewer, filename.c_str());
 72:       PetscViewerASCIIGetPointer(viewer, &f);
 73:       numVerts = atoi(fgets(buf, 2048, f));
 74:       PetscMalloc(numVerts*dim * sizeof(PetscScalar), &coords);
 75:       while(fgets(buf, 2048, f) != NULL) {
 76:         const char *x = strtok(buf, " ");
 77: 
 78:         /* Ignore vertex number */
 79:         x = strtok(NULL, " ");
 80:         for(c = 0; c < dim; c++) {
 81:           coords[vertexCount*dim+c] = atof(x);
 82:           x = strtok(NULL, " ");
 83:         }
 84:         vertexCount++;
 85:       }
 86:       PetscViewerDestroy(viewer);
 87:       numVertices = numVerts;
 88:       *coordinates = coords;
 89:     };
 90:     void Builder::buildCoordinates(const Obj<section_type>& coords, const int embedDim, const double coordinates[]) {
 91:       const section_type::patch_type patch = 0;
 92:       const Obj<topology_type::label_sequence>& vertices = coords->getAtlas()->getTopology()->depthStratum(patch, 0);
 93:       const int numCells = coords->getAtlas()->getTopology()->heightStratum(patch, 0)->size();

 95:       coords->getAtlas()->setFiberDimensionByDepth(patch, 0, embedDim);
 96:       coords->getAtlas()->orderPatches();
 97:       coords->allocate();
 98:       for(topology_type::label_sequence::iterator v_iter = vertices->begin(); v_iter != vertices->end(); ++v_iter) {
 99:         coords->update(patch, *v_iter, &(coordinates[(*v_iter - numCells)*embedDim]));
100:       }
101:     };
102:     Obj<Mesh> Builder::readMesh(MPI_Comm comm, const int dim, const std::string& basename, const bool useZeroBase = true, const bool interpolate = true, const int debug = 0) {
103:       Obj<Mesh>          mesh     = Mesh(comm, dim, debug);
104:       Obj<sieve_type>    sieve    = new sieve_type(comm, debug);
105:       Obj<topology_type> topology = new topology_type(comm, debug);
106:       int    *cells;
107:       double *coordinates;
108:       int     numCells = 0, numVertices = 0, numCorners = dim+1;

110:       ALE::PCICE::Builder::readConnectivity(comm, basename+".lcon", numCorners, useZeroBase, numCells, &cells);
111:       ALE::PCICE::Builder::readCoordinates(comm, basename+".nodes", dim, numVertices, &coordinates);
112:       ALE::New::SieveBuilder<sieve_type>::buildTopology(sieve, dim, numCells, cells, numVertices, interpolate, numCorners);
113:       sieve->stratify();
114:       topology->setPatch(0, sieve);
115:       topology->stratify();
116:       mesh->setTopologyNew(topology);
117:       buildCoordinates(mesh->getSection("coordinates"), dim, coordinates);
118:       return mesh;
119:     };
122:     PetscErrorCode Viewer::writeVertices(ALE::Obj<ALE::Mesh> mesh, PetscViewer viewer) {
123:       ALE::Obj<ALE::Mesh::section_type> coordinates = mesh->getSection("coordinates");
124: #if 0
125:       ALE::Mesh::field_type::patch_type patch;
126:       const double  *array = coordinates->restrict(patch);
127:       int            numVertices;

131:       //FIX:
132:       if (vertexBundle->getGlobalOffsets()) {
133:         numVertices = vertexBundle->getGlobalOffsets()[mesh->commSize()];
134:       } else {
135:         numVertices = mesh->getTopology()->depthStratum(0)->size();
136:       }
137:       PetscViewerASCIIPrintf(viewer, "%D\n", numVertices);
138:       if (mesh->commRank() == 0) {
139:         int numLocalVertices = mesh->getTopology()->depthStratum(0)->size();
140:         int embedDim = coordinates->getFiberDimension(patch, *mesh->getTopology()->depthStratum(0)->begin());
141:         int vertexCount = 1;

143:         for(int v = 0; v < numLocalVertices; v++) {
144:           PetscViewerASCIIPrintf(viewer, "%7D   ", vertexCount++);
145:           for(int d = 0; d < embedDim; d++) {
146:             if (d > 0) {
147:               PetscViewerASCIIPrintf(viewer, " ");
148:             }
149:             PetscViewerASCIIPrintf(viewer, "% 12.5E", array[v*embedDim+d]);
150:           }
151:           PetscViewerASCIIPrintf(viewer, "\n");
152:         }
153:         for(int p = 1; p < mesh->commSize(); p++) {
154:           double    *remoteCoords;
155:           MPI_Status status;

157:           MPI_Recv(&numLocalVertices, 1, MPI_INT, p, 1, mesh->comm(), &status);
158:           PetscMalloc(numLocalVertices*embedDim * sizeof(double), &remoteCoords);
159:           MPI_Recv(remoteCoords, numLocalVertices*embedDim, MPI_DOUBLE, p, 1, mesh->comm(), &status);
160:           for(int v = 0; v < numLocalVertices; v++) {
161:             PetscViewerASCIIPrintf(viewer,"%7D   ", vertexCount++);
162:             for(int d = 0; d < embedDim; d++) {
163:               if (d > 0) {
164:                 PetscViewerASCIIPrintf(viewer, " ");
165:               }
166:               PetscViewerASCIIPrintf(viewer, "% 12.5E", remoteCoords[v*embedDim+d]);
167:             }
168:             PetscViewerASCIIPrintf(viewer, "\n");
169:           }
170:         }
171:       } else {
172:         ALE::Obj<ALE::Mesh::bundle_type>                           globalOrder = coordinates->getGlobalOrder();
173:         ALE::Obj<ALE::Mesh::bundle_type::order_type::coneSequence> cone        = globalOrder->getPatch(patch);
174:         const int *offsets = coordinates->getGlobalOffsets();
175:         int        embedDim = coordinates->getFiberDimension(patch, *mesh->getTopology()->depthStratum(0)->begin());
176:         int        numLocalVertices = (offsets[mesh->commRank()+1] - offsets[mesh->commRank()])/embedDim;
177:         double    *localCoords;
178:         int        k = 0;

180:         PetscMalloc(numLocalVertices*embedDim * sizeof(double), &localCoords);
181:         for(ALE::Mesh::bundle_type::order_type::coneSequence::iterator p_iter = cone->begin(); p_iter != cone->end(); ++p_iter) {
182:           int dim = globalOrder->getFiberDimension(patch, *p_iter);

184:           if (dim > 0) {
185:             int offset = coordinates->getFiberOffset(patch, *p_iter);

187:             for(int i = offset; i < offset+dim; ++i) {
188:               localCoords[k++] = array[i];
189:             }
190:           }
191:         }
192:         if (k != numLocalVertices*embedDim) {
193:           SETERRQ2(PETSC_ERR_PLIB, "Invalid number of coordinates to send %d should be %d", k, numLocalVertices*embedDim);
194:         }
195:         MPI_Send(&numLocalVertices, 1, MPI_INT, 0, 1, mesh->comm());
196:         MPI_Send(localCoords, numLocalVertices*embedDim, MPI_DOUBLE, 0, 1, mesh->comm());
197:         PetscFree(localCoords);
198:       }
199: #endif
200:       return(0);
201:     };
204:     PetscErrorCode Viewer::writeElements(ALE::Obj<ALE::Mesh> mesh, PetscViewer viewer) {
205:       ALE::Obj<ALE::Mesh::topology_type> topology = mesh->getTopologyNew();
206: #if 0
207:       ALE::Obj<ALE::Mesh::sieve_type::traits::heightSequence> elements = topology->heightStratum(0);
208:       ALE::Obj<ALE::Mesh::bundle_type> elementBundle = mesh->getBundle(topology->depth());
209:       ALE::Obj<ALE::Mesh::bundle_type> vertexBundle = mesh->getBundle(0);
210:       ALE::Obj<ALE::Mesh::bundle_type> globalVertex = vertexBundle->getGlobalOrder();
211:       ALE::Obj<ALE::Mesh::bundle_type> globalElement = elementBundle->getGlobalOrder();
212:       ALE::Mesh::bundle_type::patch_type patch;
213:       std::string    orderName("element");
214:       int            dim  = mesh->getDimension();
215:       int            corners = topology->nCone(*elements->begin(), topology->depth())->size();
216:       int            numElements;

220:       if (corners != dim+1) {
221:         SETERRQ(PETSC_ERR_SUP, "PCICE only supports simplicies");
222:       }
223:       if (!globalVertex) {
224:         globalVertex = vertexBundle;
225:       }
226:       if (elementBundle->getGlobalOffsets()) {
227:         numElements = elementBundle->getGlobalOffsets()[mesh->commSize()];
228:       } else {
229:         numElements = mesh->getTopology()->heightStratum(0)->size();
230:       }
231:       if (mesh->commRank() == 0) {
232:         int elementCount = 1;

234:         PetscViewerASCIIPrintf(viewer, "%d\n", numElements);
235:         for(ALE::Mesh::sieve_type::traits::heightSequence::iterator e_itor = elements->begin(); e_itor != elements->end(); ++e_itor) {
236:           ALE::Obj<ALE::Mesh::bundle_type::order_type::coneSequence> cone = vertexBundle->getPatch(orderName, *e_itor);

238:           PetscViewerASCIIPrintf(viewer, "%7d", elementCount++);
239:           for(ALE::Mesh::bundle_type::order_type::coneSequence::iterator c_itor = cone->begin(); c_itor != cone->end(); ++c_itor) {
240:             PetscViewerASCIIPrintf(viewer, " %7d", globalVertex->getIndex(patch, *c_itor).prefix);
241:           }
242:           PetscViewerASCIIPrintf(viewer, "\n");
243:         }
244:         for(int p = 1; p < mesh->commSize(); p++) {
245:           int        numLocalElements;
246:           int       *remoteVertices;
247:           MPI_Status status;

249:           MPI_Recv(&numLocalElements, 1, MPI_INT, p, 1, mesh->comm(), &status);
250:           PetscMalloc(numLocalElements*corners * sizeof(int), &remoteVertices);
251:           MPI_Recv(remoteVertices, numLocalElements*corners, MPI_INT, p, 1, mesh->comm(), &status);
252:           for(int e = 0; e < numLocalElements; e++) {
253:             PetscViewerASCIIPrintf(viewer, "%7d", elementCount++);
254:             for(int c = 0; c < corners; c++) {
255:               PetscViewerASCIIPrintf(viewer, " %7d", remoteVertices[e*corners+c]);
256:             }
257:             PetscViewerASCIIPrintf(viewer, "\n");
258:           }
259:           PetscFree(remoteVertices);
260:         }
261:       } else {
262:         const int *offsets = elementBundle->getGlobalOffsets();
263:         int        numLocalElements = offsets[mesh->commRank()+1] - offsets[mesh->commRank()];
264:         int       *localVertices;
265:         int        k = 0;

267:         PetscMalloc(numLocalElements*corners * sizeof(int), &localVertices);
268:         for(ALE::Mesh::sieve_type::traits::heightSequence::iterator e_itor = elements->begin(); e_itor != elements->end(); ++e_itor) {
269:           ALE::Obj<ALE::Mesh::bundle_type::order_type::coneSequence> cone = vertexBundle->getPatch(orderName, *e_itor);

271:           if (globalElement->getFiberDimension(patch, *e_itor) > 0) {
272:             for(ALE::Mesh::bundle_type::order_type::coneSequence::iterator c_itor = cone->begin(); c_itor != cone->end(); ++c_itor) {
273:               localVertices[k++] = globalVertex->getIndex(patch, *c_itor).prefix;
274:             }
275:           }
276:         }
277:         if (k != numLocalElements*corners) {
278:           SETERRQ2(PETSC_ERR_PLIB, "Invalid number of vertices to send %d should be %d", k, numLocalElements*corners);
279:         }
280:         MPI_Send(&numLocalElements, 1, MPI_INT, 0, 1, mesh->comm());
281:         MPI_Send(localVertices, numLocalElements*corners, MPI_INT, 0, 1, mesh->comm());
282:         PetscFree(localVertices);
283:       }
284: #endif
285:       return(0);
286:     };
287:   };
288: };