static PetscErrorCode DMPlexGetVTKConnectivity(DM dm,PieceInfo *piece,PetscVTKInt **oconn,PetscVTKInt **ooffsets,PetscVTKType **otypes) { PetscErrorCode ierr; PetscVTKInt *conn,*offsets; PetscVTKType *types; PetscInt dim,vStart,vEnd,cStart,cEnd,pStart,pEnd,cellHeight,cMax,numLabelCells,hasLabel,c,v,countcell,countconn; PetscFunctionBegin; ierr = PetscMalloc3(piece->nconn,PetscVTKInt,&conn,piece->ncells,PetscVTKInt,&offsets,piece->ncells,PetscVTKType,&types);CHKERRQ(ierr); ierr = DMPlexGetDimension(dm,&dim);CHKERRQ(ierr); ierr = DMPlexGetChart(dm,&pStart,&pEnd);CHKERRQ(ierr); ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); if (cMax >= 0) cEnd = PetscMin(cEnd, cMax); ierr = DMPlexGetStratumSize(dm, "vtk", 1, &numLabelCells);CHKERRQ(ierr); hasLabel = numLabelCells > 0 ? PETSC_TRUE : PETSC_FALSE; countcell = 0; countconn = 0; for (c = cStart; c < cEnd; ++c) { PetscInt *closure = NULL; PetscInt closureSize,nverts,celltype,startoffset,nC=0; if (hasLabel) { PetscInt value; ierr = DMPlexGetLabelValue(dm, "vtk", c, &value);CHKERRQ(ierr); if (value != 1) continue; } startoffset = countconn; ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); for (v = 0; v < closureSize*2; v += 2) { if ((closure[v] >= vStart) && (closure[v] < vEnd)) { conn[countconn++] = closure[v] - vStart; ++nC; } } ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); ierr = DMPlexInvertCell(dim, nC, &conn[countconn-nC]);CHKERRQ(ierr); offsets[countcell] = countconn; nverts = countconn - startoffset; ierr = DMPlexVTKGetCellType(dm,dim,nverts,&celltype);CHKERRQ(ierr); types[countcell] = celltype; countcell++; } if (countcell != piece->ncells) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Inconsistent cell count"); if (countconn != piece->nconn) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Inconsistent connectivity count"); *oconn = conn; *ooffsets = offsets; *otypes = types; PetscFunctionReturn(0); }
PetscErrorCode DMPlexVTKWritePartition_ASCII(DM dm, FILE *fp) { MPI_Comm comm; PetscInt numCells = 0, cellHeight; PetscInt numLabelCells, cMax, cStart, cEnd, c; PetscMPIInt numProcs, rank, proc, tag; PetscBool hasLabel; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); ierr = PetscCommGetNewTag(comm, &tag);CHKERRQ(ierr); ierr = MPI_Comm_size(comm, &numProcs);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); if (cMax >= 0) cEnd = PetscMin(cEnd, cMax); ierr = DMPlexGetStratumSize(dm, "vtk", 1, &numLabelCells);CHKERRQ(ierr); hasLabel = numLabelCells > 0 ? PETSC_TRUE : PETSC_FALSE; for (c = cStart; c < cEnd; ++c) { if (hasLabel) { PetscInt value; ierr = DMPlexGetLabelValue(dm, "vtk", c, &value);CHKERRQ(ierr); if (value != 1) continue; } ++numCells; } if (!rank) { for (c = 0; c < numCells; ++c) {ierr = PetscFPrintf(comm, fp, "%d\n", rank);CHKERRQ(ierr);} for (proc = 1; proc < numProcs; ++proc) { MPI_Status status; ierr = MPI_Recv(&numCells, 1, MPIU_INT, proc, tag, comm, &status);CHKERRQ(ierr); for (c = 0; c < numCells; ++c) {ierr = PetscFPrintf(comm, fp, "%d\n", proc);CHKERRQ(ierr);} } } else { ierr = MPI_Send(&numCells, 1, MPIU_INT, 0, tag, comm);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode DMPlexVTKWriteCells_ASCII(DM dm, FILE *fp, PetscInt *totalCells) { MPI_Comm comm; DMLabel label; IS globalVertexNumbers = NULL; const PetscInt *gvertex; PetscInt dim; PetscInt numCorners = 0, totCorners = 0, maxCorners, *corners; PetscInt numCells = 0, totCells = 0, maxCells, cellHeight; PetscInt numLabelCells, maxLabelCells, cMax, cStart, cEnd, c, vStart, vEnd, v; PetscMPIInt numProcs, rank, proc, tag; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); ierr = PetscCommGetNewTag(comm, &tag);CHKERRQ(ierr); ierr = MPI_Comm_size(comm, &numProcs);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); if (cMax >= 0) cEnd = PetscMin(cEnd, cMax); ierr = DMPlexGetLabel(dm, "vtk", &label);CHKERRQ(ierr); ierr = DMPlexGetStratumSize(dm, "vtk", 1, &numLabelCells);CHKERRQ(ierr); ierr = MPI_Allreduce(&numLabelCells, &maxLabelCells, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); if (!maxLabelCells) label = NULL; for (c = cStart; c < cEnd; ++c) { PetscInt *closure = NULL; PetscInt closureSize, value; if (label) { ierr = DMLabelGetValue(label, c, &value);CHKERRQ(ierr); if (value != 1) continue; } ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); for (v = 0; v < closureSize*2; v += 2) { if ((closure[v] >= vStart) && (closure[v] < vEnd)) ++numCorners; } ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); ++numCells; } maxCells = numCells; ierr = MPI_Reduce(&numCells, &totCells, 1, MPIU_INT, MPI_SUM, 0, comm);CHKERRQ(ierr); ierr = MPI_Reduce(&numCells, &maxCells, 1, MPIU_INT, MPI_MAX, 0, comm);CHKERRQ(ierr); ierr = MPI_Reduce(&numCorners, &totCorners, 1, MPIU_INT, MPI_SUM, 0, comm);CHKERRQ(ierr); ierr = MPI_Reduce(&numCorners, &maxCorners, 1, MPIU_INT, MPI_MAX, 0, comm);CHKERRQ(ierr); ierr = DMPlexGetVertexNumbering(dm, &globalVertexNumbers);CHKERRQ(ierr); ierr = ISGetIndices(globalVertexNumbers, &gvertex);CHKERRQ(ierr); ierr = PetscMalloc1(maxCells, &corners);CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "CELLS %d %d\n", totCells, totCorners+totCells);CHKERRQ(ierr); if (!rank) { PetscInt *remoteVertices; int *vertices; ierr = PetscMalloc1(maxCorners, &vertices);CHKERRQ(ierr); for (c = cStart, numCells = 0; c < cEnd; ++c) { PetscInt *closure = NULL; PetscInt closureSize, value, nC = 0; if (label) { ierr = DMLabelGetValue(label, c, &value);CHKERRQ(ierr); if (value != 1) continue; } ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); for (v = 0; v < closureSize*2; v += 2) { if ((closure[v] >= vStart) && (closure[v] < vEnd)) { const PetscInt gv = gvertex[closure[v] - vStart]; vertices[nC++] = gv < 0 ? -(gv+1) : gv; } } ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); corners[numCells++] = nC; ierr = PetscFPrintf(comm, fp, "%d ", nC);CHKERRQ(ierr); ierr = DMPlexInvertCell(dim, nC, vertices);CHKERRQ(ierr); for (v = 0; v < nC; ++v) { ierr = PetscFPrintf(comm, fp, " %d", vertices[v]);CHKERRQ(ierr); } ierr = PetscFPrintf(comm, fp, "\n");CHKERRQ(ierr); } if (numProcs > 1) {ierr = PetscMalloc1(maxCorners+maxCells, &remoteVertices);CHKERRQ(ierr);} for (proc = 1; proc < numProcs; ++proc) { MPI_Status status; ierr = MPI_Recv(&numCorners, 1, MPIU_INT, proc, tag, comm, &status);CHKERRQ(ierr); ierr = MPI_Recv(remoteVertices, numCorners, MPIU_INT, proc, tag, comm, &status);CHKERRQ(ierr); for (c = 0; c < numCorners;) { PetscInt nC = remoteVertices[c++]; for (v = 0; v < nC; ++v, ++c) { vertices[v] = remoteVertices[c]; } ierr = DMPlexInvertCell(dim, nC, vertices);CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "%d ", nC);CHKERRQ(ierr); for (v = 0; v < nC; ++v) { ierr = PetscFPrintf(comm, fp, " %d", vertices[v]);CHKERRQ(ierr); } ierr = PetscFPrintf(comm, fp, "\n");CHKERRQ(ierr); } } if (numProcs > 1) {ierr = PetscFree(remoteVertices);CHKERRQ(ierr);} ierr = PetscFree(vertices);CHKERRQ(ierr); } else { PetscInt *localVertices, numSend = numCells+numCorners, k = 0; ierr = PetscMalloc1(numSend, &localVertices);CHKERRQ(ierr); for (c = cStart, numCells = 0; c < cEnd; ++c) { PetscInt *closure = NULL; PetscInt closureSize, value, nC = 0; if (label) { ierr = DMLabelGetValue(label, c, &value);CHKERRQ(ierr); if (value != 1) continue; } ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); for (v = 0; v < closureSize*2; v += 2) { if ((closure[v] >= vStart) && (closure[v] < vEnd)) { const PetscInt gv = gvertex[closure[v] - vStart]; closure[nC++] = gv < 0 ? -(gv+1) : gv; } } corners[numCells++] = nC; localVertices[k++] = nC; for (v = 0; v < nC; ++v, ++k) { localVertices[k] = closure[v]; } ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); } if (k != numSend) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Invalid number of vertices to send %d should be %d", k, numSend); ierr = MPI_Send(&numSend, 1, MPIU_INT, 0, tag, comm);CHKERRQ(ierr); ierr = MPI_Send(localVertices, numSend, MPIU_INT, 0, tag, comm);CHKERRQ(ierr); ierr = PetscFree(localVertices);CHKERRQ(ierr); } ierr = ISRestoreIndices(globalVertexNumbers, &gvertex);CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "CELL_TYPES %d\n", totCells);CHKERRQ(ierr); if (!rank) { PetscInt cellType; for (c = 0; c < numCells; ++c) { ierr = DMPlexVTKGetCellType(dm, dim, corners[c], &cellType);CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "%d\n", cellType);CHKERRQ(ierr); } for (proc = 1; proc < numProcs; ++proc) { MPI_Status status; ierr = MPI_Recv(&numCells, 1, MPIU_INT, proc, tag, comm, &status);CHKERRQ(ierr); ierr = MPI_Recv(corners, numCells, MPIU_INT, proc, tag, comm, &status);CHKERRQ(ierr); for (c = 0; c < numCells; ++c) { ierr = DMPlexVTKGetCellType(dm, dim, corners[c], &cellType);CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "%d\n", cellType);CHKERRQ(ierr); } } } else { ierr = MPI_Send(&numCells, 1, MPIU_INT, 0, tag, comm);CHKERRQ(ierr); ierr = MPI_Send(corners, numCells, MPIU_INT, 0, tag, comm);CHKERRQ(ierr); } ierr = PetscFree(corners);CHKERRQ(ierr); *totalCells = totCells; PetscFunctionReturn(0); }
PetscErrorCode DMPlexVTKWriteSection_ASCII(DM dm, PetscSection section, PetscSection globalSection, Vec v, FILE *fp, PetscInt enforceDof, PetscInt precision, PetscReal scale) { MPI_Comm comm; const MPI_Datatype mpiType = MPIU_SCALAR; PetscScalar *array; PetscInt numDof = 0, maxDof; PetscInt numLabelCells, cellHeight, cMax, cStart, cEnd, numLabelVertices, vMax, vStart, vEnd, pStart, pEnd, p; PetscMPIInt numProcs, rank, proc, tag; PetscBool hasLabel; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); PetscValidHeaderSpecific(dm,DM_CLASSID,1); PetscValidHeaderSpecific(v,VEC_CLASSID,4); if (precision < 0) precision = 6; ierr = PetscCommGetNewTag(comm, &tag);CHKERRQ(ierr); ierr = MPI_Comm_size(comm, &numProcs);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); /* VTK only wants the values at cells or vertices */ ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, &vMax);CHKERRQ(ierr); if (cMax >= 0) cEnd = PetscMin(cEnd, cMax); if (vMax >= 0) vEnd = PetscMin(vEnd, vMax); pStart = PetscMax(PetscMin(cStart, vStart), pStart); pEnd = PetscMin(PetscMax(cEnd, vEnd), pEnd); ierr = DMPlexGetStratumSize(dm, "vtk", 1, &numLabelCells);CHKERRQ(ierr); ierr = DMPlexGetStratumSize(dm, "vtk", 2, &numLabelVertices);CHKERRQ(ierr); hasLabel = numLabelCells > 0 || numLabelVertices > 0 ? PETSC_TRUE : PETSC_FALSE; for (p = pStart; p < pEnd; ++p) { /* Reject points not either cells or vertices */ if (((p < cStart) || (p >= cEnd)) && ((p < vStart) || (p >= vEnd))) continue; if (hasLabel) { PetscInt value; if (((p >= cStart) && (p < cEnd) && numLabelCells) || ((p >= vStart) && (p < vEnd) && numLabelVertices)) { ierr = DMPlexGetLabelValue(dm, "vtk", p, &value);CHKERRQ(ierr); if (value != 1) continue; } } ierr = PetscSectionGetDof(section, p, &numDof);CHKERRQ(ierr); if (numDof) break; } ierr = MPI_Allreduce(&numDof, &maxDof, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); enforceDof = PetscMax(enforceDof, maxDof); ierr = VecGetArray(v, &array);CHKERRQ(ierr); if (!rank) { char formatString[8]; ierr = PetscSNPrintf(formatString, 8, "%%.%de", precision);CHKERRQ(ierr); for (p = pStart; p < pEnd; ++p) { /* Here we lose a way to filter points by keeping them out of the Numbering */ PetscInt dof, off, goff, d; /* Reject points not either cells or vertices */ if (((p < cStart) || (p >= cEnd)) && ((p < vStart) || (p >= vEnd))) continue; if (hasLabel) { PetscInt value; if (((p >= cStart) && (p < cEnd) && numLabelCells) || ((p >= vStart) && (p < vEnd) && numLabelVertices)) { ierr = DMPlexGetLabelValue(dm, "vtk", p, &value);CHKERRQ(ierr); if (value != 1) continue; } } ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); ierr = PetscSectionGetOffset(section, p, &off);CHKERRQ(ierr); ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr); if (dof && goff >= 0) { for (d = 0; d < dof; d++) { if (d > 0) { ierr = PetscFPrintf(comm, fp, " ");CHKERRQ(ierr); } ierr = PetscFPrintf(comm, fp, formatString, PetscRealPart(array[off+d])*scale);CHKERRQ(ierr); } for (d = dof; d < enforceDof; d++) { ierr = PetscFPrintf(comm, fp, " 0.0");CHKERRQ(ierr); } ierr = PetscFPrintf(comm, fp, "\n");CHKERRQ(ierr); } } for (proc = 1; proc < numProcs; ++proc) { PetscScalar *remoteValues; PetscInt size = 0, d; MPI_Status status; ierr = MPI_Recv(&size, 1, MPIU_INT, proc, tag, comm, &status);CHKERRQ(ierr); ierr = PetscMalloc1(size, &remoteValues);CHKERRQ(ierr); ierr = MPI_Recv(remoteValues, size, mpiType, proc, tag, comm, &status);CHKERRQ(ierr); for (p = 0; p < size/maxDof; ++p) { for (d = 0; d < maxDof; ++d) { if (d > 0) { ierr = PetscFPrintf(comm, fp, " ");CHKERRQ(ierr); } ierr = PetscFPrintf(comm, fp, formatString, PetscRealPart(remoteValues[p*maxDof+d])*scale);CHKERRQ(ierr); } for (d = maxDof; d < enforceDof; ++d) { ierr = PetscFPrintf(comm, fp, " 0.0");CHKERRQ(ierr); } ierr = PetscFPrintf(comm, fp, "\n");CHKERRQ(ierr); } ierr = PetscFree(remoteValues);CHKERRQ(ierr); } } else { PetscScalar *localValues; PetscInt size, k = 0; ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); ierr = PetscMalloc1(size, &localValues);CHKERRQ(ierr); for (p = pStart; p < pEnd; ++p) { PetscInt dof, off, goff, d; /* Reject points not either cells or vertices */ if (((p < cStart) || (p >= cEnd)) && ((p < vStart) || (p >= vEnd))) continue; if (hasLabel) { PetscInt value; if (((p >= cStart) && (p < cEnd) && numLabelCells) || ((p >= vStart) && (p < vEnd) && numLabelVertices)) { ierr = DMPlexGetLabelValue(dm, "vtk", p, &value);CHKERRQ(ierr); if (value != 1) continue; } } ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr); ierr = PetscSectionGetOffset(section, p, &off);CHKERRQ(ierr); ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr); if (goff >= 0) { for (d = 0; d < dof; ++d) { localValues[k++] = array[off+d]; } } } ierr = MPI_Send(&k, 1, MPIU_INT, 0, tag, comm);CHKERRQ(ierr); ierr = MPI_Send(localValues, k, mpiType, 0, tag, comm);CHKERRQ(ierr); ierr = PetscFree(localValues);CHKERRQ(ierr); } ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Write all fields that have been provided to the viewer Multi-block XML format with binary appended data. */ PetscErrorCode DMPlexVTKWriteAll_VTU(DM dm,PetscViewer viewer) { MPI_Comm comm; PetscViewer_VTK *vtk = (PetscViewer_VTK*)viewer->data; PetscViewerVTKObjectLink link; FILE *fp; PetscMPIInt rank,size,tag; PetscErrorCode ierr; PetscInt dim,cellHeight,cStart,cEnd,vStart,vEnd,cMax,numLabelCells,hasLabel,c,v,r,i; PieceInfo piece,*gpiece = NULL; void *buffer = NULL; PetscFunctionBegin; ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); #if defined(PETSC_USE_COMPLEX) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Complex values not supported"); #endif ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); tag = ((PetscObject)viewer)->tag; ierr = PetscFOpen(comm,vtk->filename,"wb",&fp);CHKERRQ(ierr); ierr = PetscFPrintf(comm,fp,"<?xml version=\"1.0\"?>\n");CHKERRQ(ierr); #if defined(PETSC_WORDS_BIGENDIAN) ierr = PetscFPrintf(comm,fp,"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"BigEndian\">\n");CHKERRQ(ierr); #else ierr = PetscFPrintf(comm,fp,"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n");CHKERRQ(ierr); #endif ierr = PetscFPrintf(comm,fp," <UnstructuredGrid>\n");CHKERRQ(ierr); ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); if (cMax >= 0) cEnd = PetscMin(cEnd, cMax); ierr = DMPlexGetStratumSize(dm, "vtk", 1, &numLabelCells);CHKERRQ(ierr); hasLabel = numLabelCells > 0 ? PETSC_TRUE : PETSC_FALSE; piece.nvertices = vEnd - vStart; piece.ncells = 0; piece.nconn = 0; for (c = cStart; c < cEnd; ++c) { PetscInt *closure = NULL; PetscInt closureSize; if (hasLabel) { PetscInt value; ierr = DMPlexGetLabelValue(dm, "vtk", c, &value);CHKERRQ(ierr); if (value != 1) continue; } ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); for (v = 0; v < closureSize*2; v += 2) { if ((closure[v] >= vStart) && (closure[v] < vEnd)) piece.nconn++; } ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); piece.ncells++; } if (!rank) {ierr = PetscMalloc(size*sizeof(piece),&gpiece);CHKERRQ(ierr);} ierr = MPI_Gather((PetscInt*)&piece,sizeof(piece)/sizeof(PetscInt),MPIU_INT,(PetscInt*)gpiece,sizeof(piece)/sizeof(PetscInt),MPIU_INT,0,comm);CHKERRQ(ierr); /* * Write file header */ if (!rank) { PetscInt boffset = 0; for (r=0; r<size; r++) { ierr = PetscFPrintf(PETSC_COMM_SELF,fp," <Piece NumberOfPoints=\"%D\" NumberOfCells=\"%D\">\n",gpiece[r].nvertices,gpiece[r].ncells);CHKERRQ(ierr); /* Coordinate positions */ ierr = PetscFPrintf(PETSC_COMM_SELF,fp," <Points>\n");CHKERRQ(ierr); ierr = PetscFPrintf(PETSC_COMM_SELF,fp," <DataArray type=\"%s\" Name=\"Position\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%D\" />\n",precision,boffset);CHKERRQ(ierr); boffset += gpiece[r].nvertices*3*sizeof(PetscScalar) + sizeof(int); ierr = PetscFPrintf(PETSC_COMM_SELF,fp," </Points>\n");CHKERRQ(ierr); /* Cell connectivity */ ierr = PetscFPrintf(PETSC_COMM_SELF,fp," <Cells>\n");CHKERRQ(ierr); ierr = PetscFPrintf(PETSC_COMM_SELF,fp," <DataArray type=\"Int32\" Name=\"connectivity\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%D\" />\n",boffset);CHKERRQ(ierr); boffset += gpiece[r].nconn*sizeof(PetscInt) + sizeof(int); ierr = PetscFPrintf(PETSC_COMM_SELF,fp," <DataArray type=\"Int32\" Name=\"offsets\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%D\" />\n",boffset);CHKERRQ(ierr); boffset += gpiece[r].ncells*sizeof(PetscInt) + sizeof(int); ierr = PetscFPrintf(PETSC_COMM_SELF,fp," <DataArray type=\"UInt8\" Name=\"types\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%D\" />\n",boffset);CHKERRQ(ierr); boffset += gpiece[r].ncells*sizeof(unsigned char) + sizeof(int); ierr = PetscFPrintf(PETSC_COMM_SELF,fp," </Cells>\n");CHKERRQ(ierr); /* * Cell Data headers */ ierr = PetscFPrintf(PETSC_COMM_SELF,fp," <CellData>\n");CHKERRQ(ierr); ierr = PetscFPrintf(PETSC_COMM_SELF,fp," <DataArray type=\"Int32\" Name=\"Rank\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%D\" />\n",boffset);CHKERRQ(ierr); boffset += gpiece[r].ncells*sizeof(int) + sizeof(int); /* all the vectors */ for (link=vtk->link; link; link=link->next) { Vec X = (Vec)link->vec; PetscInt bs,nfields,field; const char *vecname = ""; if ((link->ft != PETSC_VTK_CELL_FIELD) && (link->ft != PETSC_VTK_CELL_VECTOR_FIELD)) continue; if (((PetscObject)X)->name || link != vtk->link) { /* If the object is already named, use it. If it is past the first link, name it to disambiguate. */ ierr = PetscObjectGetName((PetscObject)X,&vecname);CHKERRQ(ierr); } ierr = PetscSectionGetDof(dm->defaultSection,cStart,&bs);CHKERRQ(ierr); ierr = PetscSectionGetNumFields(dm->defaultSection,&nfields);CHKERRQ(ierr); for (field=0,i=0; field<(nfields?nfields:1); field++) { PetscInt fbs,j; const char *fieldname = NULL; char buf[256]; if (nfields) { /* We have user-defined fields/components */ ierr = PetscSectionGetFieldDof(dm->defaultSection,cStart,field,&fbs);CHKERRQ(ierr); ierr = PetscSectionGetFieldName(dm->defaultSection,field,&fieldname);CHKERRQ(ierr); } else fbs = bs; /* Say we have one field with 'bs' components */ if (!fieldname) { ierr = PetscSNPrintf(buf,sizeof(buf),"CellField%D",field);CHKERRQ(ierr); fieldname = buf; } for (j=0; j<fbs; j++) { ierr = PetscFPrintf(comm,fp," <DataArray type=\"%s\" Name=\"%s%s.%D\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%D\" />\n",precision,vecname,fieldname,j,boffset);CHKERRQ(ierr); boffset += gpiece[r].ncells*sizeof(PetscScalar) + sizeof(int); i++; } } if (i != bs) SETERRQ2(comm,PETSC_ERR_PLIB,"Total number of field components %D != block size %D",i,bs); } ierr = PetscFPrintf(PETSC_COMM_SELF,fp," </CellData>\n");CHKERRQ(ierr); /* * Point Data headers */ ierr = PetscFPrintf(PETSC_COMM_SELF,fp," <PointData>\n");CHKERRQ(ierr); for (link=vtk->link; link; link=link->next) { Vec X = (Vec)link->vec; PetscInt bs,nfields,field; const char *vecname = ""; if ((link->ft != PETSC_VTK_POINT_FIELD) && (link->ft != PETSC_VTK_POINT_VECTOR_FIELD)) continue; if (((PetscObject)X)->name || link != vtk->link) { /* If the object is already named, use it. If it is past the first link, name it to disambiguate. */ ierr = PetscObjectGetName((PetscObject)X,&vecname);CHKERRQ(ierr); } ierr = PetscSectionGetDof(dm->defaultSection,vStart,&bs);CHKERRQ(ierr); ierr = PetscSectionGetNumFields(dm->defaultSection,&nfields);CHKERRQ(ierr); for (field=0,i=0; field<(nfields?nfields:1); field++) { PetscInt fbs,j; const char *fieldname = NULL; char buf[256]; if (nfields) { /* We have user-defined fields/components */ ierr = PetscSectionGetFieldDof(dm->defaultSection,vStart,field,&fbs);CHKERRQ(ierr); ierr = PetscSectionGetFieldName(dm->defaultSection,field,&fieldname);CHKERRQ(ierr); } else fbs = bs; /* Say we have one field with 'bs' components */ if (!fieldname) { ierr = PetscSNPrintf(buf,sizeof(buf),"PointField%D",field);CHKERRQ(ierr); fieldname = buf; } for (j=0; j<fbs; j++) { ierr = PetscFPrintf(comm,fp," <DataArray type=\"%s\" Name=\"%s%s.%D\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%D\" />\n",precision,vecname,fieldname,j,boffset);CHKERRQ(ierr); boffset += gpiece[r].nvertices*sizeof(PetscScalar) + sizeof(int); } } } ierr = PetscFPrintf(PETSC_COMM_SELF,fp," </PointData>\n");CHKERRQ(ierr); ierr = PetscFPrintf(PETSC_COMM_SELF,fp," </Piece>\n");CHKERRQ(ierr); } } ierr = PetscFPrintf(comm,fp," </UnstructuredGrid>\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm,fp," <AppendedData encoding=\"raw\">\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm,fp,"_");CHKERRQ(ierr); if (!rank) { PetscInt maxsize = 0; for (r=0; r<size; r++) { maxsize = PetscMax(maxsize, (PetscInt) (gpiece[r].nvertices*3*sizeof(PetscScalar))); maxsize = PetscMax(maxsize, (PetscInt) (gpiece[r].ncells*sizeof(PetscScalar))); maxsize = PetscMax(maxsize, (PetscInt) (gpiece[r].nconn*sizeof(PetscVTKInt))); } ierr = PetscMalloc(maxsize,&buffer);CHKERRQ(ierr); } for (r=0; r<size; r++) { if (r == rank) { PetscInt nsend; { /* Position */ const PetscScalar *x; PetscScalar *y = NULL; Vec coords; nsend = piece.nvertices*3; ierr = DMGetCoordinatesLocal(dm,&coords);CHKERRQ(ierr); ierr = VecGetArrayRead(coords,&x);CHKERRQ(ierr); if (dim != 3) { ierr = PetscMalloc(piece.nvertices*3*sizeof(PetscScalar),&y);CHKERRQ(ierr); for (i=0; i<piece.nvertices; i++) { y[i*3+0] = x[i*dim+0]; y[i*3+1] = (dim > 1) ? x[i*dim+1] : 0; y[i*3+2] = 0; } } ierr = TransferWrite(viewer,fp,r,0,y ? y : x,buffer,nsend,PETSC_SCALAR,tag);CHKERRQ(ierr); ierr = PetscFree(y);CHKERRQ(ierr); ierr = VecRestoreArrayRead(coords,&x);CHKERRQ(ierr); } { /* Connectivity, offsets, types */ PetscVTKInt *connectivity = NULL,*offsets; PetscVTKType *types; ierr = DMPlexGetVTKConnectivity(dm,&piece,&connectivity,&offsets,&types);CHKERRQ(ierr); ierr = TransferWrite(viewer,fp,r,0,connectivity,buffer,piece.nconn,PETSC_INT32,tag);CHKERRQ(ierr); ierr = TransferWrite(viewer,fp,r,0,offsets,buffer,piece.ncells,PETSC_INT32,tag);CHKERRQ(ierr); ierr = TransferWrite(viewer,fp,r,0,types,buffer,piece.ncells,PETSC_UINT8,tag);CHKERRQ(ierr); ierr = PetscFree3(connectivity,offsets,types);CHKERRQ(ierr); } { /* Owners (cell data) */ PetscVTKInt *owners; ierr = PetscMalloc(piece.ncells*sizeof(PetscVTKInt),&owners);CHKERRQ(ierr); for (i=0; i<piece.ncells; i++) owners[i] = rank; ierr = TransferWrite(viewer,fp,r,0,owners,buffer,piece.ncells,PETSC_INT32,tag);CHKERRQ(ierr); ierr = PetscFree(owners);CHKERRQ(ierr); } /* Cell data */ for (link=vtk->link; link; link=link->next) { Vec X = (Vec)link->vec; const PetscScalar *x; PetscScalar *y; PetscInt bs; if ((link->ft != PETSC_VTK_CELL_FIELD) && (link->ft != PETSC_VTK_CELL_VECTOR_FIELD)) continue; ierr = PetscSectionGetDof(dm->defaultSection,cStart,&bs);CHKERRQ(ierr); ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); ierr = PetscMalloc(piece.ncells*sizeof(PetscScalar),&y);CHKERRQ(ierr); for (i=0; i<bs; i++) { PetscInt cnt; for (c=cStart,cnt=0; c<cEnd; c++) { const PetscScalar *xpoint; if (hasLabel) { /* Ignore some cells */ PetscInt value; ierr = DMPlexGetLabelValue(dm, "vtk", c, &value);CHKERRQ(ierr); if (value != 1) continue; } ierr = DMPlexPointLocalRead(dm,c,x,&xpoint);CHKERRQ(ierr); y[cnt++] = xpoint[i]; } if (cnt != piece.ncells) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Count does not match"); ierr = TransferWrite(viewer,fp,r,0,y,buffer,piece.ncells,PETSC_SCALAR,tag);CHKERRQ(ierr); } ierr = PetscFree(y);CHKERRQ(ierr); ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); } for (link=vtk->link; link; link=link->next) { Vec X = (Vec)link->vec; const PetscScalar *x; PetscScalar *y; PetscInt bs; if ((link->ft != PETSC_VTK_POINT_FIELD) && (link->ft != PETSC_VTK_POINT_VECTOR_FIELD)) continue; ierr = PetscSectionGetDof(dm->defaultSection,vStart,&bs);CHKERRQ(ierr); ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); ierr = PetscMalloc(piece.nvertices*sizeof(PetscScalar),&y);CHKERRQ(ierr); for (i=0; i<bs; i++) { PetscInt cnt; for (v=vStart,cnt=0; v<vEnd; v++) { const PetscScalar *xpoint; ierr = DMPlexPointLocalRead(dm,v,x,&xpoint);CHKERRQ(ierr); y[cnt++] = xpoint[i]; } if (cnt != piece.nvertices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Count does not match"); ierr = TransferWrite(viewer,fp,r,0,y,buffer,piece.nvertices,PETSC_SCALAR,tag);CHKERRQ(ierr); } ierr = PetscFree(y);CHKERRQ(ierr); ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); } } else if (!rank) { ierr = TransferWrite(viewer,fp,r,0,NULL,buffer,gpiece[r].nvertices*3,PETSC_SCALAR,tag);CHKERRQ(ierr); /* positions */ ierr = TransferWrite(viewer,fp,r,0,NULL,buffer,gpiece[r].nconn,PETSC_INT32,tag);CHKERRQ(ierr); /* connectivity */ ierr = TransferWrite(viewer,fp,r,0,NULL,buffer,gpiece[r].ncells,PETSC_INT32,tag);CHKERRQ(ierr); /* offsets */ ierr = TransferWrite(viewer,fp,r,0,NULL,buffer,gpiece[r].ncells,PETSC_UINT8,tag);CHKERRQ(ierr); /* types */ ierr = TransferWrite(viewer,fp,r,0,NULL,buffer,gpiece[r].ncells,PETSC_INT32,tag);CHKERRQ(ierr); /* owner rank (cells) */ /* all cell data */ for (link=vtk->link; link; link=link->next) { PetscInt bs; if ((link->ft != PETSC_VTK_CELL_FIELD) && (link->ft != PETSC_VTK_CELL_VECTOR_FIELD)) continue; ierr = PetscSectionGetDof(dm->defaultSection,cStart,&bs);CHKERRQ(ierr); for (i=0; i<bs; i++) { ierr = TransferWrite(viewer,fp,r,0,NULL,buffer,gpiece[r].ncells,PETSC_SCALAR,tag);CHKERRQ(ierr); } } /* all point data */ for (link=vtk->link; link; link=link->next) { PetscInt bs; if ((link->ft != PETSC_VTK_POINT_FIELD) && (link->ft != PETSC_VTK_POINT_VECTOR_FIELD)) continue; ierr = PetscSectionGetDof(dm->defaultSection,vStart,&bs);CHKERRQ(ierr); for (i=0; i<bs; i++) { ierr = TransferWrite(viewer,fp,r,0,NULL,buffer,gpiece[r].nvertices,PETSC_SCALAR,tag);CHKERRQ(ierr); } } } } ierr = PetscFree(gpiece);CHKERRQ(ierr); ierr = PetscFree(buffer);CHKERRQ(ierr); ierr = PetscFPrintf(comm,fp,"\n </AppendedData>\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm,fp,"</VTKFile>\n");CHKERRQ(ierr); PetscFunctionReturn(0); }