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: };