1 #define PETSCDM_DLL 2 #include <petsc-private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 3 #include <../src/sys/classes/viewer/impls/vtk/vtkvimpl.h> 4 5 #undef __FUNCT__ 6 #define __FUNCT__ "DMPlexVTKGetCellType" 7 PetscErrorCode DMPlexVTKGetCellType(DM dm, PetscInt dim, PetscInt corners, PetscInt *cellType) 8 { 9 PetscFunctionBegin; 10 *cellType = -1; 11 switch (dim) { 12 case 0: 13 switch (corners) { 14 case 1: 15 *cellType = 1; /* VTK_VERTEX */ 16 break; 17 default: 18 break; 19 } 20 break; 21 case 1: 22 switch (corners) { 23 case 2: 24 *cellType = 3; /* VTK_LINE */ 25 break; 26 case 3: 27 *cellType = 21; /* VTK_QUADRATIC_EDGE */ 28 break; 29 default: 30 break; 31 } 32 break; 33 case 2: 34 switch (corners) { 35 case 3: 36 *cellType = 5; /* VTK_TRIANGLE */ 37 break; 38 case 4: 39 *cellType = 9; /* VTK_QUAD */ 40 break; 41 case 6: 42 *cellType = 22; /* VTK_QUADRATIC_TRIANGLE */ 43 break; 44 case 9: 45 *cellType = 23; /* VTK_QUADRATIC_QUAD */ 46 break; 47 default: 48 break; 49 } 50 break; 51 case 3: 52 switch (corners) { 53 case 4: 54 *cellType = 10; /* VTK_TETRA */ 55 break; 56 case 8: 57 *cellType = 12; /* VTK_HEXAHEDRON */ 58 break; 59 case 10: 60 *cellType = 24; /* VTK_QUADRATIC_TETRA */ 61 break; 62 case 27: 63 *cellType = 29; /* VTK_QUADRATIC_HEXAHEDRON */ 64 break; 65 default: 66 break; 67 } 68 } 69 PetscFunctionReturn(0); 70 } 71 72 #undef __FUNCT__ 73 #define __FUNCT__ "DMPlexVTKWriteCells_ASCII" 74 PetscErrorCode DMPlexVTKWriteCells_ASCII(DM dm, FILE *fp, PetscInt *totalCells) 75 { 76 MPI_Comm comm; 77 IS globalVertexNumbers; 78 const PetscInt *gvertex; 79 PetscInt dim; 80 PetscInt numCorners = 0, totCorners = 0, maxCorners, *corners; 81 PetscInt numCells = 0, totCells = 0, maxCells, cellHeight; 82 PetscInt numLabelCells, cMax, cStart, cEnd, c, vStart, vEnd, v; 83 PetscMPIInt numProcs, rank, proc, tag; 84 PetscBool hasLabel; 85 PetscErrorCode ierr; 86 87 PetscFunctionBegin; 88 ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 89 ierr = PetscCommGetNewTag(comm, &tag);CHKERRQ(ierr); 90 ierr = MPI_Comm_size(comm, &numProcs);CHKERRQ(ierr); 91 ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 92 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 93 ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 94 ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 95 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 96 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 97 if (cMax >= 0) cEnd = PetscMin(cEnd, cMax); 98 ierr = DMPlexGetStratumSize(dm, "vtk", 1, &numLabelCells);CHKERRQ(ierr); 99 100 hasLabel = numLabelCells > 0 ? PETSC_TRUE : PETSC_FALSE; 101 for (c = cStart; c < cEnd; ++c) { 102 PetscInt *closure = NULL; 103 PetscInt closureSize; 104 105 if (hasLabel) { 106 PetscInt value; 107 108 ierr = DMPlexGetLabelValue(dm, "vtk", c, &value);CHKERRQ(ierr); 109 if (value != 1) continue; 110 } 111 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 112 for (v = 0; v < closureSize*2; v += 2) { 113 if ((closure[v] >= vStart) && (closure[v] < vEnd)) ++numCorners; 114 } 115 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 116 ++numCells; 117 } 118 maxCells = numCells; 119 ierr = MPI_Reduce(&numCells, &totCells, 1, MPIU_INT, MPI_SUM, 0, comm);CHKERRQ(ierr); 120 ierr = MPI_Reduce(&numCells, &maxCells, 1, MPIU_INT, MPI_MAX, 0, comm);CHKERRQ(ierr); 121 ierr = MPI_Reduce(&numCorners, &totCorners, 1, MPIU_INT, MPI_SUM, 0, comm);CHKERRQ(ierr); 122 ierr = MPI_Reduce(&numCorners, &maxCorners, 1, MPIU_INT, MPI_MAX, 0, comm);CHKERRQ(ierr); 123 ierr = DMPlexGetVertexNumbering(dm, &globalVertexNumbers);CHKERRQ(ierr); 124 ierr = ISGetIndices(globalVertexNumbers, &gvertex);CHKERRQ(ierr); 125 ierr = PetscMalloc(maxCells * sizeof(PetscInt), &corners);CHKERRQ(ierr); 126 ierr = PetscFPrintf(comm, fp, "CELLS %d %d\n", totCells, totCorners+totCells);CHKERRQ(ierr); 127 if (!rank) { 128 PetscInt *remoteVertices; 129 130 for (c = cStart, numCells = 0; c < cEnd; ++c) { 131 PetscInt *closure = NULL; 132 PetscInt closureSize, nC = 0; 133 134 if (hasLabel) { 135 PetscInt value; 136 137 ierr = DMPlexGetLabelValue(dm, "vtk", c, &value);CHKERRQ(ierr); 138 if (value != 1) continue; 139 } 140 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 141 for (v = 0; v < closureSize*2; v += 2) { 142 if ((closure[v] >= vStart) && (closure[v] < vEnd)) { 143 const PetscInt gv = gvertex[closure[v] - vStart]; 144 closure[nC++] = gv < 0 ? -(gv+1) : gv; 145 } 146 } 147 corners[numCells++] = nC; 148 ierr = PetscFPrintf(comm, fp, "%d ", nC);CHKERRQ(ierr); 149 for (v = 0; v < nC; ++v) { 150 ierr = PetscFPrintf(comm, fp, " %d", closure[v]);CHKERRQ(ierr); 151 } 152 ierr = PetscFPrintf(comm, fp, "\n");CHKERRQ(ierr); 153 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 154 } 155 if (numProcs > 1) {ierr = PetscMalloc((maxCorners+maxCells) * sizeof(PetscInt), &remoteVertices);CHKERRQ(ierr);} 156 for (proc = 1; proc < numProcs; ++proc) { 157 MPI_Status status; 158 159 ierr = MPI_Recv(&numCorners, 1, MPIU_INT, proc, tag, comm, &status);CHKERRQ(ierr); 160 ierr = MPI_Recv(remoteVertices, numCorners, MPIU_INT, proc, tag, comm, &status);CHKERRQ(ierr); 161 for (c = 0; c < numCorners;) { 162 PetscInt nC = remoteVertices[c++]; 163 164 ierr = PetscFPrintf(comm, fp, "%d ", nC);CHKERRQ(ierr); 165 for (v = 0; v < nC; ++v, ++c) { 166 ierr = PetscFPrintf(comm, fp, " %d", remoteVertices[c]);CHKERRQ(ierr); 167 } 168 ierr = PetscFPrintf(comm, fp, "\n");CHKERRQ(ierr); 169 } 170 } 171 if (numProcs > 1) {ierr = PetscFree(remoteVertices);CHKERRQ(ierr);} 172 } else { 173 PetscInt *localVertices, numSend = numCells+numCorners, k = 0; 174 175 ierr = PetscMalloc(numSend * sizeof(PetscInt), &localVertices);CHKERRQ(ierr); 176 for (c = cStart, numCells = 0; c < cEnd; ++c) { 177 PetscInt *closure = NULL; 178 PetscInt closureSize, nC = 0; 179 180 if (hasLabel) { 181 PetscInt value; 182 183 ierr = DMPlexGetLabelValue(dm, "vtk", c, &value);CHKERRQ(ierr); 184 if (value != 1) continue; 185 } 186 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 187 for (v = 0; v < closureSize*2; v += 2) { 188 if ((closure[v] >= vStart) && (closure[v] < vEnd)) { 189 const PetscInt gv = gvertex[closure[v] - vStart]; 190 closure[nC++] = gv < 0 ? -(gv+1) : gv; 191 } 192 } 193 corners[numCells++] = nC; 194 localVertices[k++] = nC; 195 for (v = 0; v < nC; ++v, ++k) { 196 localVertices[k] = closure[v]; 197 } 198 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 199 } 200 if (k != numSend) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Invalid number of vertices to send %d should be %d", k, numSend); 201 ierr = MPI_Send(&numSend, 1, MPIU_INT, 0, tag, comm);CHKERRQ(ierr); 202 ierr = MPI_Send(localVertices, numSend, MPIU_INT, 0, tag, comm);CHKERRQ(ierr); 203 ierr = PetscFree(localVertices);CHKERRQ(ierr); 204 } 205 ierr = ISRestoreIndices(globalVertexNumbers, &gvertex);CHKERRQ(ierr); 206 ierr = PetscFPrintf(comm, fp, "CELL_TYPES %d\n", totCells);CHKERRQ(ierr); 207 if (!rank) { 208 PetscInt cellType; 209 210 for (c = 0; c < numCells; ++c) { 211 ierr = DMPlexVTKGetCellType(dm, dim, corners[c], &cellType);CHKERRQ(ierr); 212 ierr = PetscFPrintf(comm, fp, "%d\n", cellType);CHKERRQ(ierr); 213 } 214 for (proc = 1; proc < numProcs; ++proc) { 215 MPI_Status status; 216 217 ierr = MPI_Recv(&numCells, 1, MPIU_INT, proc, tag, comm, &status);CHKERRQ(ierr); 218 ierr = MPI_Recv(corners, numCells, MPIU_INT, proc, tag, comm, &status);CHKERRQ(ierr); 219 for (c = 0; c < numCells; ++c) { 220 ierr = DMPlexVTKGetCellType(dm, dim, corners[c], &cellType);CHKERRQ(ierr); 221 ierr = PetscFPrintf(comm, fp, "%d\n", cellType);CHKERRQ(ierr); 222 } 223 } 224 } else { 225 ierr = MPI_Send(&numCells, 1, MPIU_INT, 0, tag, comm);CHKERRQ(ierr); 226 ierr = MPI_Send(corners, numCells, MPIU_INT, 0, tag, comm);CHKERRQ(ierr); 227 } 228 ierr = PetscFree(corners);CHKERRQ(ierr); 229 *totalCells = totCells; 230 PetscFunctionReturn(0); 231 } 232 233 #undef __FUNCT__ 234 #define __FUNCT__ "DMPlexVTKWriteSection_ASCII" 235 PetscErrorCode DMPlexVTKWriteSection_ASCII(DM dm, PetscSection section, PetscSection globalSection, Vec v, FILE *fp, PetscInt enforceDof, PetscInt precision, PetscReal scale) 236 { 237 MPI_Comm comm; 238 const MPI_Datatype mpiType = MPIU_SCALAR; 239 PetscScalar *array; 240 PetscInt numDof = 0, maxDof; 241 PetscInt numLabelCells, cellHeight, cMax, cStart, cEnd, numLabelVertices, vMax, vStart, vEnd, pStart, pEnd, p; 242 PetscMPIInt numProcs, rank, proc, tag; 243 PetscBool hasLabel; 244 PetscErrorCode ierr; 245 246 PetscFunctionBegin; 247 ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 248 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 249 PetscValidHeaderSpecific(v,VEC_CLASSID,4); 250 if (precision < 0) precision = 6; 251 ierr = PetscCommGetNewTag(comm, &tag);CHKERRQ(ierr); 252 ierr = MPI_Comm_size(comm, &numProcs);CHKERRQ(ierr); 253 ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 254 ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 255 /* VTK only wants the values at cells or vertices */ 256 ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 257 ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 258 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 259 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, &vMax);CHKERRQ(ierr); 260 if (cMax >= 0) cEnd = PetscMin(cEnd, cMax); 261 if (vMax >= 0) vEnd = PetscMin(vEnd, vMax); 262 pStart = PetscMax(PetscMin(cStart, vStart), pStart); 263 pEnd = PetscMin(PetscMax(cEnd, vEnd), pEnd); 264 ierr = DMPlexGetStratumSize(dm, "vtk", 1, &numLabelCells);CHKERRQ(ierr); 265 ierr = DMPlexGetStratumSize(dm, "vtk", 2, &numLabelVertices);CHKERRQ(ierr); 266 hasLabel = numLabelCells > 0 || numLabelVertices > 0 ? PETSC_TRUE : PETSC_FALSE; 267 for (p = pStart; p < pEnd; ++p) { 268 /* Reject points not either cells or vertices */ 269 if (((p < cStart) || (p >= cEnd)) && ((p < vStart) || (p >= vEnd))) continue; 270 if (hasLabel) { 271 PetscInt value; 272 273 if (((p >= cStart) && (p < cEnd) && numLabelCells) || 274 ((p >= vStart) && (p < vEnd) && numLabelVertices)) { 275 ierr = DMPlexGetLabelValue(dm, "vtk", p, &value);CHKERRQ(ierr); 276 if (value != 1) continue; 277 } 278 } 279 ierr = PetscSectionGetDof(section, p, &numDof);CHKERRQ(ierr); 280 if (numDof) break; 281 } 282 ierr = MPI_Allreduce(&numDof, &maxDof, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); 283 enforceDof = PetscMax(enforceDof, maxDof); 284 ierr = VecGetArray(v, &array);CHKERRQ(ierr); 285 if (!rank) { 286 char formatString[8]; 287 288 ierr = PetscSNPrintf(formatString, 8, "%%.%de", precision);CHKERRQ(ierr); 289 for (p = pStart; p < pEnd; ++p) { 290 /* Here we lose a way to filter points by keeping them out of the Numbering */ 291 PetscInt dof, off, goff, d; 292 293 /* Reject points not either cells or vertices */ 294 if (((p < cStart) || (p >= cEnd)) && ((p < vStart) || (p >= vEnd))) continue; 295 if (hasLabel) { 296 PetscInt value; 297 298 if (((p >= cStart) && (p < cEnd) && numLabelCells) || 299 ((p >= vStart) && (p < vEnd) && numLabelVertices)) { 300 ierr = DMPlexGetLabelValue(dm, "vtk", p, &value);CHKERRQ(ierr); 301 if (value != 1) continue; 302 } 303 } 304 ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 305 ierr = PetscSectionGetOffset(section, p, &off);CHKERRQ(ierr); 306 ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr); 307 if (dof && goff >= 0) { 308 for (d = 0; d < dof; d++) { 309 if (d > 0) { 310 ierr = PetscFPrintf(comm, fp, " ");CHKERRQ(ierr); 311 } 312 ierr = PetscFPrintf(comm, fp, formatString, PetscRealPart(array[off+d])*scale);CHKERRQ(ierr); 313 } 314 for (d = dof; d < enforceDof; d++) { 315 ierr = PetscFPrintf(comm, fp, " 0.0");CHKERRQ(ierr); 316 } 317 ierr = PetscFPrintf(comm, fp, "\n");CHKERRQ(ierr); 318 } 319 } 320 for (proc = 1; proc < numProcs; ++proc) { 321 PetscScalar *remoteValues; 322 PetscInt size, d; 323 MPI_Status status; 324 325 ierr = MPI_Recv(&size, 1, MPIU_INT, proc, tag, comm, &status);CHKERRQ(ierr); 326 ierr = PetscMalloc(size * sizeof(PetscScalar), &remoteValues);CHKERRQ(ierr); 327 ierr = MPI_Recv(remoteValues, size, mpiType, proc, tag, comm, &status);CHKERRQ(ierr); 328 for (p = 0; p < size/maxDof; ++p) { 329 for (d = 0; d < maxDof; ++d) { 330 if (d > 0) { 331 ierr = PetscFPrintf(comm, fp, " ");CHKERRQ(ierr); 332 } 333 ierr = PetscFPrintf(comm, fp, formatString, PetscRealPart(remoteValues[p*maxDof+d])*scale);CHKERRQ(ierr); 334 } 335 for (d = maxDof; d < enforceDof; ++d) { 336 ierr = PetscFPrintf(comm, fp, " 0.0");CHKERRQ(ierr); 337 } 338 ierr = PetscFPrintf(comm, fp, "\n");CHKERRQ(ierr); 339 } 340 ierr = PetscFree(remoteValues);CHKERRQ(ierr); 341 } 342 } else { 343 PetscScalar *localValues; 344 PetscInt size, k = 0; 345 346 ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 347 ierr = PetscMalloc(size * sizeof(PetscScalar), &localValues);CHKERRQ(ierr); 348 for (p = pStart; p < pEnd; ++p) { 349 PetscInt dof, off, goff, d; 350 351 /* Reject points not either cells or vertices */ 352 if (((p < cStart) || (p >= cEnd)) && ((p < vStart) || (p >= vEnd))) continue; 353 if (hasLabel) { 354 PetscInt value; 355 356 if (((p >= cStart) && (p < cEnd) && numLabelCells) || 357 ((p >= vStart) && (p < vEnd) && numLabelVertices)) { 358 ierr = DMPlexGetLabelValue(dm, "vtk", p, &value);CHKERRQ(ierr); 359 if (value != 1) continue; 360 } 361 } 362 ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); 363 ierr = PetscSectionGetOffset(section, p, &off);CHKERRQ(ierr); 364 ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr); 365 if (goff >= 0) { 366 for (d = 0; d < dof; ++d) { 367 localValues[k++] = array[off+d]; 368 } 369 } 370 } 371 ierr = MPI_Send(&k, 1, MPIU_INT, 0, tag, comm);CHKERRQ(ierr); 372 ierr = MPI_Send(localValues, k, mpiType, 0, tag, comm);CHKERRQ(ierr); 373 ierr = PetscFree(localValues);CHKERRQ(ierr); 374 } 375 ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 376 PetscFunctionReturn(0); 377 } 378 379 #undef __FUNCT__ 380 #define __FUNCT__ "DMPlexVTKWriteField_ASCII" 381 PetscErrorCode DMPlexVTKWriteField_ASCII(DM dm, PetscSection section, PetscSection globalSection, Vec field, const char name[], FILE *fp, PetscInt enforceDof, PetscInt precision, PetscReal scale) 382 { 383 MPI_Comm comm; 384 PetscInt numDof = 0, maxDof; 385 PetscInt pStart, pEnd, p; 386 PetscErrorCode ierr; 387 388 PetscFunctionBegin; 389 ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 390 ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 391 for (p = pStart; p < pEnd; ++p) { 392 ierr = PetscSectionGetDof(section, p, &numDof);CHKERRQ(ierr); 393 if (numDof) break; 394 } 395 numDof = PetscMax(numDof, enforceDof); 396 ierr = MPI_Allreduce(&numDof, &maxDof, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 397 if (!name) name = "Unknown"; 398 if (maxDof == 3) { 399 ierr = PetscFPrintf(comm, fp, "VECTORS %s double\n", name);CHKERRQ(ierr); 400 } else { 401 ierr = PetscFPrintf(comm, fp, "SCALARS %s double %d\n", name, maxDof);CHKERRQ(ierr); 402 ierr = PetscFPrintf(comm, fp, "LOOKUP_TABLE default\n");CHKERRQ(ierr); 403 } 404 ierr = DMPlexVTKWriteSection_ASCII(dm, section, globalSection, field, fp, enforceDof, precision, scale);CHKERRQ(ierr); 405 PetscFunctionReturn(0); 406 } 407 408 #undef __FUNCT__ 409 #define __FUNCT__ "DMPlexVTKWriteAll_ASCII" 410 static PetscErrorCode DMPlexVTKWriteAll_ASCII(DM dm, PetscViewer viewer) 411 { 412 MPI_Comm comm; 413 PetscViewer_VTK *vtk = (PetscViewer_VTK*) viewer->data; 414 FILE *fp; 415 PetscViewerVTKObjectLink link; 416 PetscSection coordSection, globalCoordSection; 417 PetscLayout vLayout; 418 Vec coordinates; 419 PetscReal lengthScale; 420 PetscInt vMax, totVertices, totCells; 421 PetscBool hasPoint = PETSC_FALSE, hasCell = PETSC_FALSE; 422 PetscErrorCode ierr; 423 424 PetscFunctionBegin; 425 ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 426 ierr = PetscFOpen(comm, vtk->filename, "wb", &fp);CHKERRQ(ierr); 427 ierr = PetscFPrintf(comm, fp, "# vtk DataFile Version 2.0\n");CHKERRQ(ierr); 428 ierr = PetscFPrintf(comm, fp, "Simplicial Mesh Example\n");CHKERRQ(ierr); 429 ierr = PetscFPrintf(comm, fp, "ASCII\n");CHKERRQ(ierr); 430 ierr = PetscFPrintf(comm, fp, "DATASET UNSTRUCTURED_GRID\n");CHKERRQ(ierr); 431 /* Vertices */ 432 ierr = DMPlexGetScale(dm, PETSC_UNIT_LENGTH, &lengthScale);CHKERRQ(ierr); 433 ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 434 ierr = PetscSectionCreateGlobalSection(coordSection, dm->sf, PETSC_FALSE, &globalCoordSection);CHKERRQ(ierr); 435 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 436 ierr = DMPlexGetHybridBounds(dm, NULL, NULL, NULL, &vMax);CHKERRQ(ierr); 437 if (vMax >= 0) { 438 PetscInt pStart, pEnd, p, localSize = 0; 439 440 ierr = PetscSectionGetChart(globalCoordSection, &pStart, &pEnd);CHKERRQ(ierr); 441 pEnd = PetscMin(pEnd, vMax); 442 for (p = pStart; p < pEnd; ++p) { 443 PetscInt dof; 444 445 ierr = PetscSectionGetDof(globalCoordSection, p, &dof);CHKERRQ(ierr); 446 if (dof > 0) ++localSize; 447 } 448 ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)dm), &vLayout);CHKERRQ(ierr); 449 ierr = PetscLayoutSetLocalSize(vLayout, localSize);CHKERRQ(ierr); 450 ierr = PetscLayoutSetBlockSize(vLayout, 1);CHKERRQ(ierr); 451 ierr = PetscLayoutSetUp(vLayout);CHKERRQ(ierr); 452 } else { 453 ierr = PetscSectionGetPointLayout(PetscObjectComm((PetscObject)dm), globalCoordSection, &vLayout);CHKERRQ(ierr); 454 } 455 ierr = PetscLayoutGetSize(vLayout, &totVertices);CHKERRQ(ierr); 456 ierr = PetscFPrintf(comm, fp, "POINTS %d double\n", totVertices);CHKERRQ(ierr); 457 ierr = DMPlexVTKWriteSection_ASCII(dm, coordSection, globalCoordSection, coordinates, fp, 3, PETSC_DETERMINE, lengthScale);CHKERRQ(ierr); 458 /* Cells */ 459 ierr = DMPlexVTKWriteCells_ASCII(dm, fp, &totCells);CHKERRQ(ierr); 460 /* Vertex fields */ 461 for (link = vtk->link; link; link = link->next) { 462 if ((link->ft == PETSC_VTK_POINT_FIELD) || (link->ft == PETSC_VTK_POINT_VECTOR_FIELD)) hasPoint = PETSC_TRUE; 463 if ((link->ft == PETSC_VTK_CELL_FIELD) || (link->ft == PETSC_VTK_CELL_VECTOR_FIELD)) hasCell = PETSC_TRUE; 464 } 465 if (hasPoint) { 466 ierr = PetscFPrintf(comm, fp, "POINT_DATA %d\n", totVertices);CHKERRQ(ierr); 467 for (link = vtk->link; link; link = link->next) { 468 Vec X = (Vec) link->vec; 469 DM dmX; 470 PetscSection section, globalSection, newSection = NULL; 471 const char *name; 472 PetscInt enforceDof = PETSC_DETERMINE; 473 474 if ((link->ft != PETSC_VTK_POINT_FIELD) && (link->ft != PETSC_VTK_POINT_VECTOR_FIELD)) continue; 475 if (link->ft == PETSC_VTK_POINT_VECTOR_FIELD) enforceDof = 3; 476 ierr = PetscObjectGetName(link->vec, &name);CHKERRQ(ierr); 477 ierr = VecGetDM(X, &dmX);CHKERRQ(ierr); 478 if (dmX) { 479 DMLabel subpointMap, subpointMapX; 480 PetscInt dim, dimX, pStart, pEnd, qStart, qEnd; 481 482 ierr = DMGetDefaultSection(dmX, §ion);CHKERRQ(ierr); 483 /* Here is where we check whether dmX is a submesh of dm */ 484 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 485 ierr = DMPlexGetDimension(dmX, &dimX);CHKERRQ(ierr); 486 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 487 ierr = DMPlexGetChart(dmX, &qStart, &qEnd);CHKERRQ(ierr); 488 ierr = DMPlexGetSubpointMap(dm, &subpointMap);CHKERRQ(ierr); 489 ierr = DMPlexGetSubpointMap(dmX, &subpointMapX);CHKERRQ(ierr); 490 if (((dim != dimX) || ((pEnd-pStart) < (qEnd-qStart))) && subpointMap && !subpointMapX) { 491 const PetscInt *ind; 492 IS subpointIS; 493 PetscInt n, q; 494 495 ierr = PetscPrintf(PETSC_COMM_SELF, "Making translation PetscSection\n");CHKERRQ(ierr); 496 ierr = PetscSectionGetChart(section, &qStart, &qEnd);CHKERRQ(ierr); 497 ierr = DMPlexCreateSubpointIS(dm, &subpointIS);CHKERRQ(ierr); 498 ierr = ISGetLocalSize(subpointIS, &n);CHKERRQ(ierr); 499 ierr = ISGetIndices(subpointIS, &ind);CHKERRQ(ierr); 500 ierr = PetscSectionCreate(comm, &newSection);CHKERRQ(ierr); 501 ierr = PetscSectionSetChart(newSection, pStart, pEnd);CHKERRQ(ierr); 502 for (q = qStart; q < qEnd; ++q) { 503 PetscInt dof, off, p; 504 505 ierr = PetscSectionGetDof(section, q, &dof);CHKERRQ(ierr); 506 if (dof) { 507 ierr = PetscFindInt(q, n, ind, &p);CHKERRQ(ierr); 508 if (p >= pStart) { 509 ierr = PetscSectionSetDof(newSection, p, dof);CHKERRQ(ierr); 510 ierr = PetscSectionGetOffset(section, q, &off);CHKERRQ(ierr); 511 ierr = PetscSectionSetOffset(newSection, p, off);CHKERRQ(ierr); 512 } 513 } 514 } 515 ierr = ISRestoreIndices(subpointIS, &ind);CHKERRQ(ierr); 516 ierr = ISDestroy(&subpointIS);CHKERRQ(ierr); 517 /* No need to setup section */ 518 section = newSection; 519 } 520 } else { 521 ierr = PetscObjectQuery(link->vec, "section", (PetscObject*) §ion);CHKERRQ(ierr); 522 if (!section) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Vector %s had no PetscSection composed with it", name); 523 } 524 if (!section) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Vector %s had no PetscSection composed with it", name); 525 ierr = PetscSectionCreateGlobalSection(section, dm->sf, PETSC_FALSE, &globalSection);CHKERRQ(ierr); 526 ierr = DMPlexVTKWriteField_ASCII(dm, section, globalSection, X, name, fp, enforceDof, PETSC_DETERMINE, 1.0);CHKERRQ(ierr); 527 ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); 528 if (newSection) {ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr);} 529 } 530 } 531 /* Cell Fields */ 532 if (hasCell) { 533 ierr = PetscFPrintf(comm, fp, "CELL_DATA %d\n", totCells);CHKERRQ(ierr); 534 for (link = vtk->link; link; link = link->next) { 535 Vec X = (Vec) link->vec; 536 DM dmX; 537 PetscSection section, globalSection; 538 const char *name; 539 PetscInt enforceDof = PETSC_DETERMINE; 540 541 if ((link->ft != PETSC_VTK_CELL_FIELD) && (link->ft != PETSC_VTK_CELL_VECTOR_FIELD)) continue; 542 if (link->ft == PETSC_VTK_CELL_VECTOR_FIELD) enforceDof = 3; 543 ierr = PetscObjectGetName(link->vec, &name);CHKERRQ(ierr); 544 ierr = VecGetDM(X, &dmX);CHKERRQ(ierr); 545 if (dmX) { 546 ierr = DMGetDefaultSection(dmX, §ion);CHKERRQ(ierr); 547 } else { 548 PetscContainer c; 549 550 ierr = PetscObjectQuery(link->vec, "section", (PetscObject*) &c);CHKERRQ(ierr); 551 if (!c) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Vector %s had no PetscSection composed with it", name); 552 ierr = PetscContainerGetPointer(c, (void**) §ion);CHKERRQ(ierr); 553 } 554 if (!section) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Vector %s had no PetscSection composed with it", name); 555 ierr = PetscSectionCreateGlobalSection(section, dm->sf, PETSC_FALSE, &globalSection);CHKERRQ(ierr); 556 ierr = DMPlexVTKWriteField_ASCII(dm, section, globalSection, X, name, fp, enforceDof, PETSC_DETERMINE, 1.0);CHKERRQ(ierr); 557 ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); 558 } 559 } 560 /* Cleanup */ 561 ierr = PetscSectionDestroy(&globalCoordSection);CHKERRQ(ierr); 562 ierr = PetscLayoutDestroy(&vLayout);CHKERRQ(ierr); 563 ierr = PetscFClose(comm, fp);CHKERRQ(ierr); 564 PetscFunctionReturn(0); 565 } 566 567 #undef __FUNCT__ 568 #define __FUNCT__ "DMPlexVTKWriteAll" 569 /*@C 570 DMPlexVTKWriteAll - Write a file containing all the fields that have been provided to the viewer 571 572 Collective 573 574 Input Arguments: 575 + odm - The DMPlex specifying the mesh, passed as a PetscObject 576 - viewer - viewer of type VTK 577 578 Level: developer 579 580 Note: 581 This function is a callback used by the VTK viewer to actually write the file. 582 The reason for this odd model is that the VTK file format does not provide any way to write one field at a time. 583 Instead, metadata for the entire file needs to be available up-front before you can start writing the file. 584 585 .seealso: PETSCVIEWERVTK 586 @*/ 587 PetscErrorCode DMPlexVTKWriteAll(PetscObject odm, PetscViewer viewer) 588 { 589 DM dm = (DM) odm; 590 PetscBool isvtk; 591 PetscErrorCode ierr; 592 593 PetscFunctionBegin; 594 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 595 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 596 ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 597 if (!isvtk) SETERRQ1(PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_INCOMP, "Cannot use viewer type %s", ((PetscObject)viewer)->type_name); 598 switch (viewer->format) { 599 case PETSC_VIEWER_ASCII_VTK: 600 ierr = DMPlexVTKWriteAll_ASCII(dm, viewer);CHKERRQ(ierr); 601 break; 602 case PETSC_VIEWER_VTK_VTU: 603 ierr = DMPlexVTKWriteAll_VTU(dm, viewer);CHKERRQ(ierr); 604 break; 605 default: SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No support for format '%s'", PetscViewerFormats[viewer->format]); 606 } 607 PetscFunctionReturn(0); 608 } 609