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