1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> 2552f7358SJed Brown #include <../src/sys/classes/viewer/impls/vtk/vtkvimpl.h> 3552f7358SJed Brown 4552f7358SJed Brown typedef struct { 5552f7358SJed Brown PetscInt nvertices; 6552f7358SJed Brown PetscInt ncells; 7552f7358SJed Brown PetscInt nconn; /* number of entries in cell->vertex connectivity array */ 8552f7358SJed Brown } PieceInfo; 9552f7358SJed Brown 10955d60d1SToby Isaac #if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL___FP16) 11955d60d1SToby Isaac /* output in float if single or half precision in memory */ 12552f7358SJed Brown static const char precision[] = "Float32"; 13955d60d1SToby Isaac typedef float PetscVTUReal; 14955d60d1SToby Isaac #define MPIU_VTUREAL MPI_FLOAT 15955d60d1SToby Isaac #elif defined(PETSC_USE_REAL_DOUBLE) || defined(PETSC_USE_REAL___FLOAT128) 16955d60d1SToby Isaac /* output in double if double or quad precision in memory */ 17552f7358SJed Brown static const char precision[] = "Float64"; 18955d60d1SToby Isaac typedef double PetscVTUReal; 19955d60d1SToby Isaac #define MPIU_VTUREAL MPI_DOUBLE 20552f7358SJed Brown #else 21552f7358SJed Brown static const char precision[] = "UnknownPrecision"; 22955d60d1SToby Isaac typedef PetscReal PetscVTUReal; 23955d60d1SToby Isaac #define MPIU_VTUREAL MPIU_REAL 24552f7358SJed Brown #endif 25552f7358SJed Brown 26d71ae5a4SJacob Faibussowitsch static PetscErrorCode TransferWrite(MPI_Comm comm, PetscViewer viewer, FILE *fp, PetscMPIInt srank, PetscMPIInt root, const void *send, void *recv, PetscMPIInt count, MPI_Datatype mpidatatype, PetscMPIInt tag) 27d71ae5a4SJacob Faibussowitsch { 28552f7358SJed Brown PetscMPIInt rank; 29552f7358SJed Brown 30552f7358SJed Brown PetscFunctionBegin; 319566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 32552f7358SJed Brown if (rank == srank && rank != root) { 339566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send((void *)send, count, mpidatatype, root, tag, comm)); 34552f7358SJed Brown } else if (rank == root) { 35552f7358SJed Brown const void *buffer; 36552f7358SJed Brown if (root == srank) { /* self */ 37552f7358SJed Brown buffer = send; 38552f7358SJed Brown } else { 39552f7358SJed Brown MPI_Status status; 40552f7358SJed Brown PetscMPIInt nrecv; 419566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(recv, count, mpidatatype, srank, tag, comm, &status)); 429566063dSJacob Faibussowitsch PetscCallMPI(MPI_Get_count(&status, mpidatatype, &nrecv)); 4308401ef6SPierre Jolivet PetscCheck(count == nrecv, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Array size mismatch"); 44552f7358SJed Brown buffer = recv; 45552f7358SJed Brown } 469566063dSJacob Faibussowitsch PetscCall(PetscViewerVTKFWrite(viewer, fp, buffer, count, mpidatatype)); 47552f7358SJed Brown } 483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 49552f7358SJed Brown } 50552f7358SJed Brown 51d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPlexGetVTKConnectivity(DM dm, PetscBool localized, PieceInfo *piece, PetscVTKInt **oconn, PetscVTKInt **ooffsets, PetscVTKType **otypes) 52d71ae5a4SJacob Faibussowitsch { 536858538eSMatthew G. Knepley PetscSection coordSection, cellCoordSection; 54552f7358SJed Brown PetscVTKInt *conn, *offsets; 55552f7358SJed Brown PetscVTKType *types; 562f029394SStefano Zampini PetscInt dim, vStart, vEnd, cStart, cEnd, pStart, pEnd, cellHeight, numLabelCells, hasLabel, c, v, countcell, countconn; 57552f7358SJed Brown 58552f7358SJed Brown PetscFunctionBegin; 599566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(piece->nconn, &conn, piece->ncells, &offsets, piece->ncells, &types)); 609566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateSection(dm, &coordSection)); 616858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinateSection(dm, &cellCoordSection)); 629566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 639566063dSJacob Faibussowitsch PetscCall(DMPlexGetChart(dm, &pStart, &pEnd)); 649566063dSJacob Faibussowitsch PetscCall(DMPlexGetVTKCellHeight(dm, &cellHeight)); 659566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd)); 669566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd)); 679566063dSJacob Faibussowitsch PetscCall(DMGetStratumSize(dm, "vtk", 1, &numLabelCells)); 68552f7358SJed Brown hasLabel = numLabelCells > 0 ? PETSC_TRUE : PETSC_FALSE; 69552f7358SJed Brown 70552f7358SJed Brown countcell = 0; 71552f7358SJed Brown countconn = 0; 72552f7358SJed Brown for (c = cStart; c < cEnd; ++c) { 7319003fb5SStefano Zampini PetscInt nverts, dof = 0, celltype, startoffset, nC = 0; 74552f7358SJed Brown 75552f7358SJed Brown if (hasLabel) { 76552f7358SJed Brown PetscInt value; 77552f7358SJed Brown 789566063dSJacob Faibussowitsch PetscCall(DMGetLabelValue(dm, "vtk", c, &value)); 79552f7358SJed Brown if (value != 1) continue; 80552f7358SJed Brown } 81552f7358SJed Brown startoffset = countconn; 826858538eSMatthew G. Knepley if (localized) PetscCall(PetscSectionGetDof(cellCoordSection, c, &dof)); 8319003fb5SStefano Zampini if (!dof) { 842e529ec8SStefano Zampini PetscInt *closure = NULL; 852e529ec8SStefano Zampini PetscInt closureSize; 862e529ec8SStefano Zampini 879566063dSJacob Faibussowitsch PetscCall(DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure)); 88552f7358SJed Brown for (v = 0; v < closureSize * 2; v += 2) { 89552f7358SJed Brown if ((closure[v] >= vStart) && (closure[v] < vEnd)) { 9019003fb5SStefano Zampini if (!localized) conn[countconn++] = closure[v] - vStart; 9119003fb5SStefano Zampini else conn[countconn++] = startoffset + nC; 92724b5320SMatthew G. Knepley ++nC; 93552f7358SJed Brown } 94552f7358SJed Brown } 959566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure)); 962e529ec8SStefano Zampini } else { 972e529ec8SStefano Zampini for (nC = 0; nC < dof / dim; nC++) conn[countconn++] = startoffset + nC; 982e529ec8SStefano Zampini } 9996ca5757SLisandro Dalcin 10096ca5757SLisandro Dalcin { 10196ca5757SLisandro Dalcin PetscInt n = PetscMin(nC, 8), s = countconn - nC, i, cone[8]; 10296ca5757SLisandro Dalcin for (i = 0; i < n; ++i) cone[i] = conn[s + i]; 1039566063dSJacob Faibussowitsch PetscCall(DMPlexReorderCell(dm, c, cone)); 10496ca5757SLisandro Dalcin for (i = 0; i < n; ++i) conn[s + i] = (int)cone[i]; 10596ca5757SLisandro Dalcin } 1068865f1eaSKarl Rupp 107552f7358SJed Brown offsets[countcell] = countconn; 1088865f1eaSKarl Rupp 109552f7358SJed Brown nverts = countconn - startoffset; 1109566063dSJacob Faibussowitsch PetscCall(DMPlexVTKGetCellType_Internal(dm, dim, nverts, &celltype)); 1118865f1eaSKarl Rupp 112552f7358SJed Brown types[countcell] = celltype; 113552f7358SJed Brown countcell++; 114552f7358SJed Brown } 11508401ef6SPierre Jolivet PetscCheck(countcell == piece->ncells, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent cell count"); 11608401ef6SPierre Jolivet PetscCheck(countconn == piece->nconn, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent connectivity count"); 117552f7358SJed Brown *oconn = conn; 118552f7358SJed Brown *ooffsets = offsets; 119552f7358SJed Brown *otypes = types; 1203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 121552f7358SJed Brown } 122552f7358SJed Brown 123552f7358SJed Brown /* 124552f7358SJed Brown Write all fields that have been provided to the viewer 125552f7358SJed Brown Multi-block XML format with binary appended data. 126552f7358SJed Brown */ 127d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexVTKWriteAll_VTU(DM dm, PetscViewer viewer) 128d71ae5a4SJacob Faibussowitsch { 129ce94432eSBarry Smith MPI_Comm comm; 1306858538eSMatthew G. Knepley PetscSection coordSection, cellCoordSection; 131552f7358SJed Brown PetscViewer_VTK *vtk = (PetscViewer_VTK *)viewer->data; 132552f7358SJed Brown PetscViewerVTKObjectLink link; 133552f7358SJed Brown FILE *fp; 134552f7358SJed Brown PetscMPIInt rank, size, tag; 1352f029394SStefano Zampini PetscInt dimEmbed, cellHeight, cStart, cEnd, vStart, vEnd, numLabelCells, hasLabel, c, v, r, i; 1362e529ec8SStefano Zampini PetscBool localized; 1370298fd71SBarry Smith PieceInfo piece, *gpiece = NULL; 1380298fd71SBarry Smith void *buffer = NULL; 13930815ce0SLisandro Dalcin const char *byte_order = PetscBinaryBigEndian() ? "BigEndian" : "LittleEndian"; 140955d60d1SToby Isaac PetscInt loops_per_scalar; 141552f7358SJed Brown 142552f7358SJed Brown PetscFunctionBegin; 1439566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 144552f7358SJed Brown #if defined(PETSC_USE_COMPLEX) 145955d60d1SToby Isaac loops_per_scalar = 2; 146955d60d1SToby Isaac #else 147955d60d1SToby Isaac loops_per_scalar = 1; 148552f7358SJed Brown #endif 1499566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 1509566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1519566063dSJacob Faibussowitsch PetscCall(PetscCommGetNewTag(comm, &tag)); 152552f7358SJed Brown 1539566063dSJacob Faibussowitsch PetscCall(PetscFOpen(comm, vtk->filename, "wb", &fp)); 1549566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fp, "<?xml version=\"1.0\"?>\n")); 1554a8c153fSJed Brown PetscCall(PetscFPrintf(comm, fp, "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"%s\" header_type=\"UInt64\">\n", byte_order)); 1569566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fp, " <UnstructuredGrid>\n")); 157552f7358SJed Brown 1589566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &dimEmbed)); 1599566063dSJacob Faibussowitsch PetscCall(DMPlexGetVTKCellHeight(dm, &cellHeight)); 1609566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd)); 1619566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd)); 1629566063dSJacob Faibussowitsch PetscCall(DMGetStratumSize(dm, "vtk", 1, &numLabelCells)); 1639566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocalized(dm, &localized)); 1649566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateSection(dm, &coordSection)); 1656858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinateSection(dm, &cellCoordSection)); 1668865f1eaSKarl Rupp 167552f7358SJed Brown hasLabel = numLabelCells > 0 ? PETSC_TRUE : PETSC_FALSE; 1682e529ec8SStefano Zampini piece.nvertices = 0; 169552f7358SJed Brown piece.ncells = 0; 170552f7358SJed Brown piece.nconn = 0; 1712e529ec8SStefano Zampini if (!localized) piece.nvertices = vEnd - vStart; 172552f7358SJed Brown for (c = cStart; c < cEnd; ++c) { 17319003fb5SStefano Zampini PetscInt dof = 0; 174552f7358SJed Brown if (hasLabel) { 175552f7358SJed Brown PetscInt value; 176552f7358SJed Brown 1779566063dSJacob Faibussowitsch PetscCall(DMGetLabelValue(dm, "vtk", c, &value)); 178552f7358SJed Brown if (value != 1) continue; 179552f7358SJed Brown } 1806858538eSMatthew G. Knepley if (localized) PetscCall(PetscSectionGetDof(cellCoordSection, c, &dof)); 18119003fb5SStefano Zampini if (!dof) { 1822e529ec8SStefano Zampini PetscInt *closure = NULL; 1832e529ec8SStefano Zampini PetscInt closureSize; 1842e529ec8SStefano Zampini 1859566063dSJacob Faibussowitsch PetscCall(DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure)); 186552f7358SJed Brown for (v = 0; v < closureSize * 2; v += 2) { 1872e529ec8SStefano Zampini if ((closure[v] >= vStart) && (closure[v] < vEnd)) { 1882e529ec8SStefano Zampini piece.nconn++; 18919003fb5SStefano Zampini if (localized) piece.nvertices++; 1902e529ec8SStefano Zampini } 191552f7358SJed Brown } 1929566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure)); 1932e529ec8SStefano Zampini } else { 1942e529ec8SStefano Zampini piece.nvertices += dof / dimEmbed; 1952e529ec8SStefano Zampini piece.nconn += dof / dimEmbed; 1962e529ec8SStefano Zampini } 197552f7358SJed Brown piece.ncells++; 198552f7358SJed Brown } 1999566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscMalloc1(size, &gpiece)); 2009566063dSJacob Faibussowitsch PetscCallMPI(MPI_Gather((PetscInt *)&piece, sizeof(piece) / sizeof(PetscInt), MPIU_INT, (PetscInt *)gpiece, sizeof(piece) / sizeof(PetscInt), MPIU_INT, 0, comm)); 201552f7358SJed Brown 202552f7358SJed Brown /* 203552f7358SJed Brown * Write file header 204552f7358SJed Brown */ 205dd400576SPatrick Sanan if (rank == 0) { 2060f2609c8SJed Brown PetscInt64 boffset = 0; 207552f7358SJed Brown 208552f7358SJed Brown for (r = 0; r < size; r++) { 20963a3b9bcSJacob Faibussowitsch PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " <Piece NumberOfPoints=\"%" PetscInt_FMT "\" NumberOfCells=\"%" PetscInt_FMT "\">\n", gpiece[r].nvertices, gpiece[r].ncells)); 210552f7358SJed Brown /* Coordinate positions */ 2119566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " <Points>\n")); 2120f2609c8SJed Brown PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " <DataArray type=\"%s\" Name=\"Position\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", precision, boffset)); 213*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].nvertices * 3 * sizeof(PetscVTUReal) + (gpiece[r].nvertices ? sizeof(PetscInt64) : 0); 2149566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " </Points>\n")); 215552f7358SJed Brown /* Cell connectivity */ 2169566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " <Cells>\n")); 2170f2609c8SJed Brown PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " <DataArray type=\"Int32\" Name=\"connectivity\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", boffset)); 218*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].nconn * sizeof(PetscVTKInt) + (gpiece[r].nconn ? sizeof(PetscInt64) : 0); 2190f2609c8SJed Brown PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " <DataArray type=\"Int32\" Name=\"offsets\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", boffset)); 220*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].ncells * sizeof(PetscVTKInt) + (gpiece[r].ncells ? sizeof(PetscInt64) : 0); 2210f2609c8SJed Brown PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " <DataArray type=\"UInt8\" Name=\"types\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", boffset)); 222*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].ncells * sizeof(unsigned char) + (gpiece[r].ncells ? sizeof(PetscInt64) : 0); 2239566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " </Cells>\n")); 224552f7358SJed Brown 225552f7358SJed Brown /* 226552f7358SJed Brown * Cell Data headers 227552f7358SJed Brown */ 2289566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " <CellData>\n")); 2290f2609c8SJed Brown PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " <DataArray type=\"Int32\" Name=\"Rank\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", boffset)); 230*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].ncells * sizeof(PetscVTKInt) + (gpiece[r].ncells ? sizeof(PetscInt64) : 0); 231552f7358SJed Brown /* all the vectors */ 232552f7358SJed Brown for (link = vtk->link; link; link = link->next) { 233552f7358SJed Brown Vec X = (Vec)link->vec; 234e630c359SToby Isaac DM dmX = NULL; 2356030a318SStefano Zampini PetscInt bs = 1, nfields, field; 236552f7358SJed Brown const char *vecname = ""; 237e630c359SToby Isaac PetscSection section; 238552f7358SJed Brown if ((link->ft != PETSC_VTK_CELL_FIELD) && (link->ft != PETSC_VTK_CELL_VECTOR_FIELD)) continue; 239552f7358SJed Brown 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. */ 2409566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)X, &vecname)); 241552f7358SJed Brown } 2429566063dSJacob Faibussowitsch PetscCall(VecGetDM(X, &dmX)); 243e630c359SToby Isaac if (!dmX) dmX = dm; 2449566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery(link->vec, "section", (PetscObject *)§ion)); 2459566063dSJacob Faibussowitsch if (!section) PetscCall(DMGetLocalSection(dmX, §ion)); 2469566063dSJacob Faibussowitsch if (cEnd > cStart) PetscCall(PetscSectionGetDof(section, cStart, &bs)); 2479566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(section, &nfields)); 248e630c359SToby Isaac field = 0; 249e630c359SToby Isaac if (link->field >= 0) { 250e630c359SToby Isaac field = link->field; 251e630c359SToby Isaac nfields = field + 1; 252e630c359SToby Isaac } 253e630c359SToby Isaac for (i = 0; field < (nfields ? nfields : 1); field++) { 2541cfafdd3SJed Brown PetscInt fbs, j; 255a00cdb45SToby Isaac PetscFV fv = NULL; 256a00cdb45SToby Isaac PetscObject f; 257a00cdb45SToby Isaac PetscClassId fClass; 2580298fd71SBarry Smith const char *fieldname = NULL; 2591cfafdd3SJed Brown char buf[256]; 260e630c359SToby Isaac PetscBool vector; 2617ded4cbaSJed Brown if (nfields) { /* We have user-defined fields/components */ 2629566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, cStart, field, &fbs)); 2639566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(section, field, &fieldname)); 2647ded4cbaSJed Brown } else fbs = bs; /* Say we have one field with 'bs' components */ 2659566063dSJacob Faibussowitsch PetscCall(DMGetField(dmX, field, NULL, &f)); 2669566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(f, &fClass)); 267ad540459SPierre Jolivet if (fClass == PETSCFV_CLASSID) fv = (PetscFV)f; 268e630c359SToby Isaac if (nfields && !fieldname) { 26963a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(buf, sizeof(buf), "CellField%" PetscInt_FMT, field)); 270552f7358SJed Brown fieldname = buf; 271552f7358SJed Brown } 272e630c359SToby Isaac vector = PETSC_FALSE; 273e630c359SToby Isaac if (link->ft == PETSC_VTK_CELL_VECTOR_FIELD) { 274e630c359SToby Isaac vector = PETSC_TRUE; 27563a3b9bcSJacob Faibussowitsch PetscCheck(fbs <= 3, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_SIZ, "Cell vector fields can have at most 3 components, %" PetscInt_FMT " given", fbs); 276e630c359SToby Isaac for (j = 0; j < fbs; j++) { 277e630c359SToby Isaac const char *compName = NULL; 278e630c359SToby Isaac if (fv) { 2799566063dSJacob Faibussowitsch PetscCall(PetscFVGetComponentName(fv, j, &compName)); 280e630c359SToby Isaac if (compName) break; 281e630c359SToby Isaac } 282e630c359SToby Isaac } 283e630c359SToby Isaac if (j < fbs) vector = PETSC_FALSE; 284e630c359SToby Isaac } 285e630c359SToby Isaac if (vector) { 286955d60d1SToby Isaac #if defined(PETSC_USE_COMPLEX) 2870f2609c8SJed Brown PetscCall(PetscFPrintf(comm, fp, " <DataArray type=\"%s\" Name=\"%s%s.Re\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", precision, vecname, fieldname, boffset)); 288*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].ncells * 3 * sizeof(PetscVTUReal) + (gpiece[r].ncells ? sizeof(PetscInt64) : 0); 2890f2609c8SJed Brown PetscCall(PetscFPrintf(comm, fp, " <DataArray type=\"%s\" Name=\"%s%s.Im\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", precision, vecname, fieldname, boffset)); 290*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].ncells * 3 * sizeof(PetscVTUReal) + (gpiece[r].ncells ? sizeof(PetscInt64) : 0); 291955d60d1SToby Isaac #else 2920f2609c8SJed Brown PetscCall(PetscFPrintf(comm, fp, " <DataArray type=\"%s\" Name=\"%s%s\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", precision, vecname, fieldname, boffset)); 293*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].ncells * 3 * sizeof(PetscVTUReal) + (gpiece[r].ncells ? sizeof(PetscInt64) : 0); 294955d60d1SToby Isaac #endif 295e630c359SToby Isaac i += fbs; 296e630c359SToby Isaac } else { 2971cfafdd3SJed Brown for (j = 0; j < fbs; j++) { 298a00cdb45SToby Isaac const char *compName = NULL; 299955d60d1SToby Isaac char finalname[256]; 30048a46eb9SPierre Jolivet if (fv) PetscCall(PetscFVGetComponentName(fv, j, &compName)); 301a00cdb45SToby Isaac if (compName) { 3029566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(finalname, 255, "%s%s.%s", vecname, fieldname, compName)); 3039371c9d4SSatish Balay } else if (fbs > 1) { 30463a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(finalname, 255, "%s%s.%" PetscInt_FMT, vecname, fieldname, j)); 305e630c359SToby Isaac } else { 3069566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(finalname, 255, "%s%s", vecname, fieldname)); 307a00cdb45SToby Isaac } 308955d60d1SToby Isaac #if defined(PETSC_USE_COMPLEX) 3090f2609c8SJed Brown PetscCall(PetscFPrintf(comm, fp, " <DataArray type=\"%s\" Name=\"%s.Re\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", precision, finalname, boffset)); 310*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].ncells * sizeof(PetscVTUReal) + (gpiece[r].ncells ? sizeof(PetscInt64) : 0); 3110f2609c8SJed Brown PetscCall(PetscFPrintf(comm, fp, " <DataArray type=\"%s\" Name=\"%s.Im\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", precision, finalname, boffset)); 312*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].ncells * sizeof(PetscVTUReal) + (gpiece[r].ncells ? sizeof(PetscInt64) : 0); 313955d60d1SToby Isaac #else 3140f2609c8SJed Brown PetscCall(PetscFPrintf(comm, fp, " <DataArray type=\"%s\" Name=\"%s\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", precision, finalname, boffset)); 315*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].ncells * sizeof(PetscVTUReal) + (gpiece[r].ncells ? sizeof(PetscInt64) : 0); 316955d60d1SToby Isaac #endif 3171cfafdd3SJed Brown i++; 318552f7358SJed Brown } 319552f7358SJed Brown } 320e630c359SToby Isaac } 32163a3b9bcSJacob Faibussowitsch //PetscCheck(i == bs,comm,PETSC_ERR_PLIB,"Total number of field components %" PetscInt_FMT " != block size %" PetscInt_FMT,i,bs); 3221cfafdd3SJed Brown } 3239566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " </CellData>\n")); 324552f7358SJed Brown 325552f7358SJed Brown /* 326552f7358SJed Brown * Point Data headers 327552f7358SJed Brown */ 3289566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " <PointData>\n")); 329552f7358SJed Brown for (link = vtk->link; link; link = link->next) { 330552f7358SJed Brown Vec X = (Vec)link->vec; 331e630c359SToby Isaac DM dmX; 3326030a318SStefano Zampini PetscInt bs = 1, nfields, field; 333552f7358SJed Brown const char *vecname = ""; 334e630c359SToby Isaac PetscSection section; 335552f7358SJed Brown if ((link->ft != PETSC_VTK_POINT_FIELD) && (link->ft != PETSC_VTK_POINT_VECTOR_FIELD)) continue; 336552f7358SJed Brown 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. */ 3379566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)X, &vecname)); 338552f7358SJed Brown } 3399566063dSJacob Faibussowitsch PetscCall(VecGetDM(X, &dmX)); 340e630c359SToby Isaac if (!dmX) dmX = dm; 3419566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery(link->vec, "section", (PetscObject *)§ion)); 3429566063dSJacob Faibussowitsch if (!section) PetscCall(DMGetLocalSection(dmX, §ion)); 3439566063dSJacob Faibussowitsch if (vEnd > vStart) PetscCall(PetscSectionGetDof(section, vStart, &bs)); 3449566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(section, &nfields)); 345e630c359SToby Isaac field = 0; 346e630c359SToby Isaac if (link->field >= 0) { 347e630c359SToby Isaac field = link->field; 348e630c359SToby Isaac nfields = field + 1; 349e630c359SToby Isaac } 350e630c359SToby Isaac for (i = 0; field < (nfields ? nfields : 1); field++) { 3511cfafdd3SJed Brown PetscInt fbs, j; 3521cfafdd3SJed Brown const char *fieldname = NULL; 3531cfafdd3SJed Brown char buf[256]; 3547ded4cbaSJed Brown if (nfields) { /* We have user-defined fields/components */ 3559566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, vStart, field, &fbs)); 3569566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(section, field, &fieldname)); 3577ded4cbaSJed Brown } else fbs = bs; /* Say we have one field with 'bs' components */ 358e630c359SToby Isaac if (nfields && !fieldname) { 35963a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(buf, sizeof(buf), "PointField%" PetscInt_FMT, field)); 3601cfafdd3SJed Brown fieldname = buf; 3611cfafdd3SJed Brown } 362e630c359SToby Isaac if (link->ft == PETSC_VTK_POINT_VECTOR_FIELD) { 36363a3b9bcSJacob Faibussowitsch PetscCheck(fbs <= 3, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_SIZ, "Point vector fields can have at most 3 components, %" PetscInt_FMT " given", fbs); 364955d60d1SToby Isaac #if defined(PETSC_USE_COMPLEX) 3650f2609c8SJed Brown PetscCall(PetscFPrintf(comm, fp, " <DataArray type=\"%s\" Name=\"%s%s.Re\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", precision, vecname, fieldname, boffset)); 366*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].nvertices * 3 * sizeof(PetscVTUReal) + (gpiece[r].nvertices ? sizeof(PetscInt64) : 0); 3670f2609c8SJed Brown PetscCall(PetscFPrintf(comm, fp, " <DataArray type=\"%s\" Name=\"%s%s.Im\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", precision, vecname, fieldname, boffset)); 368*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].nvertices * 3 * sizeof(PetscVTUReal) + (gpiece[r].nvertices ? sizeof(PetscInt64) : 0); 369955d60d1SToby Isaac #else 3700f2609c8SJed Brown PetscCall(PetscFPrintf(comm, fp, " <DataArray type=\"%s\" Name=\"%s%s\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", precision, vecname, fieldname, boffset)); 371*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].nvertices * 3 * sizeof(PetscVTUReal) + (gpiece[r].nvertices ? sizeof(PetscInt64) : 0); 372955d60d1SToby Isaac #endif 373e630c359SToby Isaac } else { 3741cfafdd3SJed Brown for (j = 0; j < fbs; j++) { 375b778fa18SValeria Barra const char *compName = NULL; 376955d60d1SToby Isaac char finalname[256]; 3779566063dSJacob Faibussowitsch PetscCall(PetscSectionGetComponentName(section, field, j, &compName)); 3789566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(finalname, 255, "%s%s.%s", vecname, fieldname, compName)); 379955d60d1SToby Isaac #if defined(PETSC_USE_COMPLEX) 3800f2609c8SJed Brown PetscCall(PetscFPrintf(comm, fp, " <DataArray type=\"%s\" Name=\"%s.Re\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", precision, finalname, boffset)); 381*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].nvertices * sizeof(PetscVTUReal) + (gpiece[r].nvertices ? sizeof(PetscInt64) : 0); 3820f2609c8SJed Brown PetscCall(PetscFPrintf(comm, fp, " <DataArray type=\"%s\" Name=\"%s.Im\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", precision, finalname, boffset)); 383*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].nvertices * sizeof(PetscVTUReal) + (gpiece[r].nvertices ? sizeof(PetscInt64) : 0); 384955d60d1SToby Isaac #else 3850f2609c8SJed Brown PetscCall(PetscFPrintf(comm, fp, " <DataArray type=\"%s\" Name=\"%s\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%" PetscInt64_FMT "\" />\n", precision, finalname, boffset)); 386*6f98e5d0SMatthew G. Knepley boffset += gpiece[r].nvertices * sizeof(PetscVTUReal) + (gpiece[r].nvertices ? sizeof(PetscInt64) : 0); 387955d60d1SToby Isaac #endif 388552f7358SJed Brown } 389552f7358SJed Brown } 3901cfafdd3SJed Brown } 391e630c359SToby Isaac } 3929566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " </PointData>\n")); 3939566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PETSC_COMM_SELF, fp, " </Piece>\n")); 394552f7358SJed Brown } 395552f7358SJed Brown } 396552f7358SJed Brown 3979566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fp, " </UnstructuredGrid>\n")); 3989566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fp, " <AppendedData encoding=\"raw\">\n")); 3999566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fp, "_")); 400552f7358SJed Brown 401dd400576SPatrick Sanan if (rank == 0) { 402552f7358SJed Brown PetscInt maxsize = 0; 403552f7358SJed Brown for (r = 0; r < size; r++) { 404955d60d1SToby Isaac maxsize = PetscMax(maxsize, (PetscInt)(gpiece[r].nvertices * 3 * sizeof(PetscVTUReal))); 405955d60d1SToby Isaac maxsize = PetscMax(maxsize, (PetscInt)(gpiece[r].ncells * 3 * sizeof(PetscVTUReal))); 406552f7358SJed Brown maxsize = PetscMax(maxsize, (PetscInt)(gpiece[r].nconn * sizeof(PetscVTKInt))); 407552f7358SJed Brown } 4089566063dSJacob Faibussowitsch PetscCall(PetscMalloc(maxsize, &buffer)); 409552f7358SJed Brown } 410552f7358SJed Brown for (r = 0; r < size; r++) { 411552f7358SJed Brown if (r == rank) { 412552f7358SJed Brown PetscInt nsend; 413552f7358SJed Brown { /* Position */ 4146858538eSMatthew G. Knepley const PetscScalar *x, *cx = NULL; 415955d60d1SToby Isaac PetscVTUReal *y = NULL; 4166858538eSMatthew G. Knepley Vec coords, cellCoords; 417955d60d1SToby Isaac PetscBool copy; 4182e529ec8SStefano Zampini 4199566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocal(dm, &coords)); 4209566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(coords, &x)); 4216858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinatesLocal(dm, &cellCoords)); 4226858538eSMatthew G. Knepley if (cellCoords) PetscCall(VecGetArrayRead(cellCoords, &cx)); 423955d60d1SToby Isaac #if defined(PETSC_USE_COMPLEX) 424955d60d1SToby Isaac copy = PETSC_TRUE; 425955d60d1SToby Isaac #else 426955d60d1SToby Isaac copy = (PetscBool)(dimEmbed != 3 || localized || (sizeof(PetscReal) != sizeof(PetscVTUReal))); 427955d60d1SToby Isaac #endif 428955d60d1SToby Isaac if (copy) { 4299566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(piece.nvertices * 3, &y)); 43019003fb5SStefano Zampini if (localized) { 43119003fb5SStefano Zampini PetscInt cnt; 43219003fb5SStefano Zampini for (c = cStart, cnt = 0; c < cEnd; c++) { 43319003fb5SStefano Zampini PetscInt off, dof; 43419003fb5SStefano Zampini 4356858538eSMatthew G. Knepley PetscCall(PetscSectionGetDof(cellCoordSection, c, &dof)); 43619003fb5SStefano Zampini if (!dof) { 43719003fb5SStefano Zampini PetscInt *closure = NULL; 43819003fb5SStefano Zampini PetscInt closureSize; 43919003fb5SStefano Zampini 4409566063dSJacob Faibussowitsch PetscCall(DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure)); 44119003fb5SStefano Zampini for (v = 0; v < closureSize * 2; v += 2) { 44219003fb5SStefano Zampini if ((closure[v] >= vStart) && (closure[v] < vEnd)) { 4439566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(coordSection, closure[v], &off)); 44419003fb5SStefano Zampini if (dimEmbed != 3) { 445955d60d1SToby Isaac y[cnt * 3 + 0] = (PetscVTUReal)PetscRealPart(x[off + 0]); 446955d60d1SToby Isaac y[cnt * 3 + 1] = (PetscVTUReal)((dimEmbed > 1) ? PetscRealPart(x[off + 1]) : 0.0); 447955d60d1SToby Isaac y[cnt * 3 + 2] = (PetscVTUReal)0.0; 44819003fb5SStefano Zampini } else { 449955d60d1SToby Isaac y[cnt * 3 + 0] = (PetscVTUReal)PetscRealPart(x[off + 0]); 450955d60d1SToby Isaac y[cnt * 3 + 1] = (PetscVTUReal)PetscRealPart(x[off + 1]); 451955d60d1SToby Isaac y[cnt * 3 + 2] = (PetscVTUReal)PetscRealPart(x[off + 2]); 45219003fb5SStefano Zampini } 45319003fb5SStefano Zampini cnt++; 45419003fb5SStefano Zampini } 45519003fb5SStefano Zampini } 4569566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure)); 45719003fb5SStefano Zampini } else { 4586858538eSMatthew G. Knepley PetscCall(PetscSectionGetOffset(cellCoordSection, c, &off)); 45919003fb5SStefano Zampini if (dimEmbed != 3) { 46019003fb5SStefano Zampini for (i = 0; i < dof / dimEmbed; i++) { 4616858538eSMatthew G. Knepley y[cnt * 3 + 0] = (PetscVTUReal)PetscRealPart(cx[off + i * dimEmbed + 0]); 4626858538eSMatthew G. Knepley y[cnt * 3 + 1] = (PetscVTUReal)((dimEmbed > 1) ? PetscRealPart(cx[off + i * dimEmbed + 1]) : 0.0); 463955d60d1SToby Isaac y[cnt * 3 + 2] = (PetscVTUReal)0.0; 46419003fb5SStefano Zampini cnt++; 46519003fb5SStefano Zampini } 46619003fb5SStefano Zampini } else { 467ad540459SPierre Jolivet for (i = 0; i < dof; i++) y[cnt * 3 + i] = (PetscVTUReal)PetscRealPart(cx[off + i]); 46819003fb5SStefano Zampini cnt += dof / dimEmbed; 46919003fb5SStefano Zampini } 47019003fb5SStefano Zampini } 47119003fb5SStefano Zampini } 47208401ef6SPierre Jolivet PetscCheck(cnt == piece.nvertices, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Count does not match"); 47319003fb5SStefano Zampini } else { 474552f7358SJed Brown for (i = 0; i < piece.nvertices; i++) { 475955d60d1SToby Isaac y[i * 3 + 0] = (PetscVTUReal)PetscRealPart(x[i * dimEmbed + 0]); 476955d60d1SToby Isaac y[i * 3 + 1] = (PetscVTUReal)((dimEmbed > 1) ? PetscRealPart(x[i * dimEmbed + 1]) : 0.); 477955d60d1SToby Isaac y[i * 3 + 2] = (PetscVTUReal)((dimEmbed > 2) ? PetscRealPart(x[i * dimEmbed + 2]) : 0.); 47819003fb5SStefano Zampini } 479552f7358SJed Brown } 480552f7358SJed Brown } 4812e529ec8SStefano Zampini nsend = piece.nvertices * 3; 4829566063dSJacob Faibussowitsch PetscCall(TransferWrite(comm, viewer, fp, r, 0, copy ? (const void *)y : (const void *)x, buffer, nsend, MPIU_VTUREAL, tag)); 4839566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 4849566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(coords, &x)); 4856858538eSMatthew G. Knepley if (cellCoords) PetscCall(VecRestoreArrayRead(cellCoords, &cx)); 486552f7358SJed Brown } 487552f7358SJed Brown { /* Connectivity, offsets, types */ 4883e869605SMatthew G. Knepley PetscVTKInt *connectivity = NULL, *offsets = NULL; 4893e869605SMatthew G. Knepley PetscVTKType *types = NULL; 4909566063dSJacob Faibussowitsch PetscCall(DMPlexGetVTKConnectivity(dm, localized, &piece, &connectivity, &offsets, &types)); 4919566063dSJacob Faibussowitsch PetscCall(TransferWrite(comm, viewer, fp, r, 0, connectivity, buffer, piece.nconn, MPI_INT, tag)); 4929566063dSJacob Faibussowitsch PetscCall(TransferWrite(comm, viewer, fp, r, 0, offsets, buffer, piece.ncells, MPI_INT, tag)); 4939566063dSJacob Faibussowitsch PetscCall(TransferWrite(comm, viewer, fp, r, 0, types, buffer, piece.ncells, MPI_CHAR, tag)); 4949566063dSJacob Faibussowitsch PetscCall(PetscFree3(connectivity, offsets, types)); 495552f7358SJed Brown } 496552f7358SJed Brown { /* Owners (cell data) */ 497552f7358SJed Brown PetscVTKInt *owners; 4989566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(piece.ncells, &owners)); 499552f7358SJed Brown for (i = 0; i < piece.ncells; i++) owners[i] = rank; 5009566063dSJacob Faibussowitsch PetscCall(TransferWrite(comm, viewer, fp, r, 0, owners, buffer, piece.ncells, MPI_INT, tag)); 5019566063dSJacob Faibussowitsch PetscCall(PetscFree(owners)); 502552f7358SJed Brown } 503552f7358SJed Brown /* Cell data */ 504552f7358SJed Brown for (link = vtk->link; link; link = link->next) { 505552f7358SJed Brown Vec X = (Vec)link->vec; 506e630c359SToby Isaac DM dmX; 507552f7358SJed Brown const PetscScalar *x; 508955d60d1SToby Isaac PetscVTUReal *y; 5096030a318SStefano Zampini PetscInt bs = 1, nfields, field; 510e630c359SToby Isaac PetscSection section = NULL; 511e630c359SToby Isaac 512552f7358SJed Brown if ((link->ft != PETSC_VTK_CELL_FIELD) && (link->ft != PETSC_VTK_CELL_VECTOR_FIELD)) continue; 5139566063dSJacob Faibussowitsch PetscCall(VecGetDM(X, &dmX)); 514e630c359SToby Isaac if (!dmX) dmX = dm; 5159566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery(link->vec, "section", (PetscObject *)§ion)); 5169566063dSJacob Faibussowitsch if (!section) PetscCall(DMGetLocalSection(dmX, §ion)); 5179566063dSJacob Faibussowitsch if (cEnd > cStart) PetscCall(PetscSectionGetDof(section, cStart, &bs)); 5189566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(section, &nfields)); 519e630c359SToby Isaac field = 0; 520e630c359SToby Isaac if (link->field >= 0) { 521e630c359SToby Isaac field = link->field; 522e630c359SToby Isaac nfields = field + 1; 523e630c359SToby Isaac } 5249566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x)); 5259566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(piece.ncells * 3, &y)); 526e630c359SToby Isaac for (i = 0; field < (nfields ? nfields : 1); field++) { 527e630c359SToby Isaac PetscInt fbs, j; 528e630c359SToby Isaac PetscFV fv = NULL; 529e630c359SToby Isaac PetscObject f; 530e630c359SToby Isaac PetscClassId fClass; 531e630c359SToby Isaac PetscBool vector; 5326030a318SStefano Zampini if (nfields && cEnd > cStart) { /* We have user-defined fields/components */ 5339566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, cStart, field, &fbs)); 534e630c359SToby Isaac } else fbs = bs; /* Say we have one field with 'bs' components */ 5359566063dSJacob Faibussowitsch PetscCall(DMGetField(dmX, field, NULL, &f)); 5369566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(f, &fClass)); 537ad540459SPierre Jolivet if (fClass == PETSCFV_CLASSID) fv = (PetscFV)f; 538e630c359SToby Isaac vector = PETSC_FALSE; 539e630c359SToby Isaac if (link->ft == PETSC_VTK_CELL_VECTOR_FIELD) { 540e630c359SToby Isaac vector = PETSC_TRUE; 541e630c359SToby Isaac for (j = 0; j < fbs; j++) { 542e630c359SToby Isaac const char *compName = NULL; 543e630c359SToby Isaac if (fv) { 5449566063dSJacob Faibussowitsch PetscCall(PetscFVGetComponentName(fv, j, &compName)); 545e630c359SToby Isaac if (compName) break; 546e630c359SToby Isaac } 547e630c359SToby Isaac } 548e630c359SToby Isaac if (j < fbs) vector = PETSC_FALSE; 549e630c359SToby Isaac } 550e630c359SToby Isaac if (vector) { 551955d60d1SToby Isaac PetscInt cnt, l; 552955d60d1SToby Isaac for (l = 0; l < loops_per_scalar; l++) { 553552f7358SJed Brown for (c = cStart, cnt = 0; c < cEnd; c++) { 554e630c359SToby Isaac const PetscScalar *xpoint; 555e630c359SToby Isaac PetscInt off, j; 556e630c359SToby Isaac 557552f7358SJed Brown if (hasLabel) { /* Ignore some cells */ 558552f7358SJed Brown PetscInt value; 5599566063dSJacob Faibussowitsch PetscCall(DMGetLabelValue(dmX, "vtk", c, &value)); 560552f7358SJed Brown if (value != 1) continue; 561552f7358SJed Brown } 562e630c359SToby Isaac if (nfields) { 5639566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldOffset(section, c, field, &off)); 564e630c359SToby Isaac } else { 5659566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(section, c, &off)); 566e630c359SToby Isaac } 567e630c359SToby Isaac xpoint = &x[off]; 568ad540459SPierre Jolivet for (j = 0; j < fbs; j++) y[cnt++] = (PetscVTUReal)(l ? PetscImaginaryPart(xpoint[j]) : PetscRealPart(xpoint[j])); 569e630c359SToby Isaac for (; j < 3; j++) y[cnt++] = 0.; 570e630c359SToby Isaac } 57108401ef6SPierre Jolivet PetscCheck(cnt == piece.ncells * 3, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Count does not match"); 5729566063dSJacob Faibussowitsch PetscCall(TransferWrite(comm, viewer, fp, r, 0, y, buffer, piece.ncells * 3, MPIU_VTUREAL, tag)); 573955d60d1SToby Isaac } 574e630c359SToby Isaac } else { 575e630c359SToby Isaac for (i = 0; i < fbs; i++) { 576955d60d1SToby Isaac PetscInt cnt, l; 577955d60d1SToby Isaac for (l = 0; l < loops_per_scalar; l++) { 578e630c359SToby Isaac for (c = cStart, cnt = 0; c < cEnd; c++) { 579e630c359SToby Isaac const PetscScalar *xpoint; 580e630c359SToby Isaac PetscInt off; 581e630c359SToby Isaac 582e630c359SToby Isaac if (hasLabel) { /* Ignore some cells */ 583e630c359SToby Isaac PetscInt value; 5849566063dSJacob Faibussowitsch PetscCall(DMGetLabelValue(dmX, "vtk", c, &value)); 585e630c359SToby Isaac if (value != 1) continue; 586e630c359SToby Isaac } 587e630c359SToby Isaac if (nfields) { 5889566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldOffset(section, c, field, &off)); 589e630c359SToby Isaac } else { 5909566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(section, c, &off)); 591e630c359SToby Isaac } 592e630c359SToby Isaac xpoint = &x[off]; 593955d60d1SToby Isaac y[cnt++] = (PetscVTUReal)(l ? PetscImaginaryPart(xpoint[i]) : PetscRealPart(xpoint[i])); 594552f7358SJed Brown } 59508401ef6SPierre Jolivet PetscCheck(cnt == piece.ncells, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Count does not match"); 5969566063dSJacob Faibussowitsch PetscCall(TransferWrite(comm, viewer, fp, r, 0, y, buffer, piece.ncells, MPIU_VTUREAL, tag)); 597955d60d1SToby Isaac } 598552f7358SJed Brown } 599e630c359SToby Isaac } 600e630c359SToby Isaac } 6019566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 6029566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x)); 603552f7358SJed Brown } 604e630c359SToby Isaac /* point data */ 605552f7358SJed Brown for (link = vtk->link; link; link = link->next) { 606552f7358SJed Brown Vec X = (Vec)link->vec; 607e630c359SToby Isaac DM dmX; 608552f7358SJed Brown const PetscScalar *x; 609955d60d1SToby Isaac PetscVTUReal *y; 6106030a318SStefano Zampini PetscInt bs = 1, nfields, field; 611e630c359SToby Isaac PetscSection section = NULL; 612e630c359SToby Isaac 613552f7358SJed Brown if ((link->ft != PETSC_VTK_POINT_FIELD) && (link->ft != PETSC_VTK_POINT_VECTOR_FIELD)) continue; 6149566063dSJacob Faibussowitsch PetscCall(VecGetDM(X, &dmX)); 615e630c359SToby Isaac if (!dmX) dmX = dm; 6169566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery(link->vec, "section", (PetscObject *)§ion)); 6179566063dSJacob Faibussowitsch if (!section) PetscCall(DMGetLocalSection(dmX, §ion)); 6189566063dSJacob Faibussowitsch if (vEnd > vStart) PetscCall(PetscSectionGetDof(section, vStart, &bs)); 6199566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(section, &nfields)); 620e630c359SToby Isaac field = 0; 621e630c359SToby Isaac if (link->field >= 0) { 622e630c359SToby Isaac field = link->field; 623e630c359SToby Isaac nfields = field + 1; 624e630c359SToby Isaac } 6259566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x)); 6269566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(piece.nvertices * 3, &y)); 627e630c359SToby Isaac for (i = 0; field < (nfields ? nfields : 1); field++) { 628e630c359SToby Isaac PetscInt fbs, j; 6296030a318SStefano Zampini if (nfields && vEnd > vStart) { /* We have user-defined fields/components */ 6309566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, vStart, field, &fbs)); 631e630c359SToby Isaac } else fbs = bs; /* Say we have one field with 'bs' components */ 632e630c359SToby Isaac if (link->ft == PETSC_VTK_POINT_VECTOR_FIELD) { 633955d60d1SToby Isaac PetscInt cnt, l; 634955d60d1SToby Isaac for (l = 0; l < loops_per_scalar; l++) { 6352e529ec8SStefano Zampini if (!localized) { 636552f7358SJed Brown for (v = vStart, cnt = 0; v < vEnd; v++) { 637e630c359SToby Isaac PetscInt off; 638e630c359SToby Isaac const PetscScalar *xpoint; 639e630c359SToby Isaac 640e630c359SToby Isaac if (nfields) { 6419566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldOffset(section, v, field, &off)); 642e630c359SToby Isaac } else { 6439566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(section, v, &off)); 644e630c359SToby Isaac } 645e630c359SToby Isaac xpoint = &x[off]; 646ad540459SPierre Jolivet for (j = 0; j < fbs; j++) y[cnt++] = (PetscVTUReal)(l ? PetscImaginaryPart(xpoint[j]) : PetscRealPart(xpoint[j])); 647e630c359SToby Isaac for (; j < 3; j++) y[cnt++] = 0.; 648e630c359SToby Isaac } 649e630c359SToby Isaac } else { 650e630c359SToby Isaac for (c = cStart, cnt = 0; c < cEnd; c++) { 651e630c359SToby Isaac PetscInt *closure = NULL; 652e630c359SToby Isaac PetscInt closureSize, off; 653e630c359SToby Isaac 6549566063dSJacob Faibussowitsch PetscCall(DMPlexGetTransitiveClosure(dmX, c, PETSC_TRUE, &closureSize, &closure)); 655e630c359SToby Isaac for (v = 0, off = 0; v < closureSize * 2; v += 2) { 656e630c359SToby Isaac if ((closure[v] >= vStart) && (closure[v] < vEnd)) { 657e630c359SToby Isaac PetscInt voff; 658e630c359SToby Isaac const PetscScalar *xpoint; 659e630c359SToby Isaac 660e630c359SToby Isaac if (nfields) { 6619566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldOffset(section, closure[v], field, &voff)); 662e630c359SToby Isaac } else { 6639566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(section, closure[v], &voff)); 664e630c359SToby Isaac } 665e630c359SToby Isaac xpoint = &x[voff]; 666ad540459SPierre Jolivet for (j = 0; j < fbs; j++) y[cnt + off++] = (PetscVTUReal)(l ? PetscImaginaryPart(xpoint[j]) : PetscRealPart(xpoint[j])); 667e630c359SToby Isaac for (; j < 3; j++) y[cnt + off++] = 0.; 668e630c359SToby Isaac } 669e630c359SToby Isaac } 670e630c359SToby Isaac cnt += off; 6719566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreTransitiveClosure(dmX, c, PETSC_TRUE, &closureSize, &closure)); 672e630c359SToby Isaac } 673e630c359SToby Isaac } 67408401ef6SPierre Jolivet PetscCheck(cnt == piece.nvertices * 3, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Count does not match"); 6759566063dSJacob Faibussowitsch PetscCall(TransferWrite(comm, viewer, fp, r, 0, y, buffer, piece.nvertices * 3, MPIU_VTUREAL, tag)); 676955d60d1SToby Isaac } 677e630c359SToby Isaac } else { 678e630c359SToby Isaac for (i = 0; i < fbs; i++) { 679955d60d1SToby Isaac PetscInt cnt, l; 680955d60d1SToby Isaac for (l = 0; l < loops_per_scalar; l++) { 681e630c359SToby Isaac if (!localized) { 682e630c359SToby Isaac for (v = vStart, cnt = 0; v < vEnd; v++) { 683e630c359SToby Isaac PetscInt off; 684e630c359SToby Isaac const PetscScalar *xpoint; 685e630c359SToby Isaac 686e630c359SToby Isaac if (nfields) { 6879566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldOffset(section, v, field, &off)); 688e630c359SToby Isaac } else { 6899566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(section, v, &off)); 690e630c359SToby Isaac } 691e630c359SToby Isaac xpoint = &x[off]; 692955d60d1SToby Isaac y[cnt++] = (PetscVTUReal)(l ? PetscImaginaryPart(xpoint[i]) : PetscRealPart(xpoint[i])); 693552f7358SJed Brown } 6942e529ec8SStefano Zampini } else { 6952e529ec8SStefano Zampini for (c = cStart, cnt = 0; c < cEnd; c++) { 6962e529ec8SStefano Zampini PetscInt *closure = NULL; 6972e529ec8SStefano Zampini PetscInt closureSize, off; 6982e529ec8SStefano Zampini 6999566063dSJacob Faibussowitsch PetscCall(DMPlexGetTransitiveClosure(dmX, c, PETSC_TRUE, &closureSize, &closure)); 7002e529ec8SStefano Zampini for (v = 0, off = 0; v < closureSize * 2; v += 2) { 7012e529ec8SStefano Zampini if ((closure[v] >= vStart) && (closure[v] < vEnd)) { 702e630c359SToby Isaac PetscInt voff; 703e630c359SToby Isaac const PetscScalar *xpoint; 7042e529ec8SStefano Zampini 705e630c359SToby Isaac if (nfields) { 7069566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldOffset(section, closure[v], field, &voff)); 707e630c359SToby Isaac } else { 7089566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(section, closure[v], &voff)); 709e630c359SToby Isaac } 710e630c359SToby Isaac xpoint = &x[voff]; 711955d60d1SToby Isaac y[cnt + off++] = (l ? PetscImaginaryPart(xpoint[i]) : PetscRealPart(xpoint[i])); 7122e529ec8SStefano Zampini } 7132e529ec8SStefano Zampini } 7149bda96f6SStefano Zampini cnt += off; 7159566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreTransitiveClosure(dmX, c, PETSC_TRUE, &closureSize, &closure)); 7162e529ec8SStefano Zampini } 7172e529ec8SStefano Zampini } 71808401ef6SPierre Jolivet PetscCheck(cnt == piece.nvertices, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Count does not match"); 7199566063dSJacob Faibussowitsch PetscCall(TransferWrite(comm, viewer, fp, r, 0, y, buffer, piece.nvertices, MPIU_VTUREAL, tag)); 720955d60d1SToby Isaac } 721552f7358SJed Brown } 722e630c359SToby Isaac } 723e630c359SToby Isaac } 7249566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 7259566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x)); 726552f7358SJed Brown } 727dd400576SPatrick Sanan } else if (rank == 0) { 728955d60d1SToby Isaac PetscInt l; 729955d60d1SToby Isaac 7309566063dSJacob Faibussowitsch PetscCall(TransferWrite(comm, viewer, fp, r, 0, NULL, buffer, gpiece[r].nvertices * 3, MPIU_VTUREAL, tag)); /* positions */ 7319566063dSJacob Faibussowitsch PetscCall(TransferWrite(comm, viewer, fp, r, 0, NULL, buffer, gpiece[r].nconn, MPI_INT, tag)); /* connectivity */ 7329566063dSJacob Faibussowitsch PetscCall(TransferWrite(comm, viewer, fp, r, 0, NULL, buffer, gpiece[r].ncells, MPI_INT, tag)); /* offsets */ 7339566063dSJacob Faibussowitsch PetscCall(TransferWrite(comm, viewer, fp, r, 0, NULL, buffer, gpiece[r].ncells, MPI_CHAR, tag)); /* types */ 7349566063dSJacob Faibussowitsch PetscCall(TransferWrite(comm, viewer, fp, r, 0, NULL, buffer, gpiece[r].ncells, MPI_INT, tag)); /* owner rank (cells) */ 735552f7358SJed Brown /* all cell data */ 736552f7358SJed Brown for (link = vtk->link; link; link = link->next) { 737e630c359SToby Isaac Vec X = (Vec)link->vec; 7386030a318SStefano Zampini PetscInt bs = 1, nfields, field; 739e630c359SToby Isaac DM dmX; 740e630c359SToby Isaac PetscSection section = NULL; 741e630c359SToby Isaac 742552f7358SJed Brown if ((link->ft != PETSC_VTK_CELL_FIELD) && (link->ft != PETSC_VTK_CELL_VECTOR_FIELD)) continue; 7439566063dSJacob Faibussowitsch PetscCall(VecGetDM(X, &dmX)); 744e630c359SToby Isaac if (!dmX) dmX = dm; 7459566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery(link->vec, "section", (PetscObject *)§ion)); 7469566063dSJacob Faibussowitsch if (!section) PetscCall(DMGetLocalSection(dmX, §ion)); 7479566063dSJacob Faibussowitsch if (cEnd > cStart) PetscCall(PetscSectionGetDof(section, cStart, &bs)); 7489566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(section, &nfields)); 749e630c359SToby Isaac field = 0; 750e630c359SToby Isaac if (link->field >= 0) { 751e630c359SToby Isaac field = link->field; 752e630c359SToby Isaac nfields = field + 1; 753e630c359SToby Isaac } 754e630c359SToby Isaac for (i = 0; field < (nfields ? nfields : 1); field++) { 755e630c359SToby Isaac PetscInt fbs, j; 756e630c359SToby Isaac PetscFV fv = NULL; 757e630c359SToby Isaac PetscObject f; 758e630c359SToby Isaac PetscClassId fClass; 759e630c359SToby Isaac PetscBool vector; 7606030a318SStefano Zampini if (nfields && cEnd > cStart) { /* We have user-defined fields/components */ 7619566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, cStart, field, &fbs)); 762e630c359SToby Isaac } else fbs = bs; /* Say we have one field with 'bs' components */ 7639566063dSJacob Faibussowitsch PetscCall(DMGetField(dmX, field, NULL, &f)); 7649566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(f, &fClass)); 765ad540459SPierre Jolivet if (fClass == PETSCFV_CLASSID) fv = (PetscFV)f; 766e630c359SToby Isaac vector = PETSC_FALSE; 767e630c359SToby Isaac if (link->ft == PETSC_VTK_CELL_VECTOR_FIELD) { 768e630c359SToby Isaac vector = PETSC_TRUE; 769e630c359SToby Isaac for (j = 0; j < fbs; j++) { 770e630c359SToby Isaac const char *compName = NULL; 771e630c359SToby Isaac if (fv) { 7729566063dSJacob Faibussowitsch PetscCall(PetscFVGetComponentName(fv, j, &compName)); 773e630c359SToby Isaac if (compName) break; 774e630c359SToby Isaac } 775e630c359SToby Isaac } 776e630c359SToby Isaac if (j < fbs) vector = PETSC_FALSE; 777e630c359SToby Isaac } 778e630c359SToby Isaac if (vector) { 77948a46eb9SPierre Jolivet for (l = 0; l < loops_per_scalar; l++) PetscCall(TransferWrite(comm, viewer, fp, r, 0, NULL, buffer, gpiece[r].ncells * 3, MPIU_VTUREAL, tag)); 780e630c359SToby Isaac } else { 781e630c359SToby Isaac for (i = 0; i < fbs; i++) { 78248a46eb9SPierre Jolivet for (l = 0; l < loops_per_scalar; l++) PetscCall(TransferWrite(comm, viewer, fp, r, 0, NULL, buffer, gpiece[r].ncells, MPIU_VTUREAL, tag)); 783552f7358SJed Brown } 784552f7358SJed Brown } 785e630c359SToby Isaac } 786e630c359SToby Isaac } 787552f7358SJed Brown /* all point data */ 788552f7358SJed Brown for (link = vtk->link; link; link = link->next) { 789e630c359SToby Isaac Vec X = (Vec)link->vec; 790e630c359SToby Isaac DM dmX; 7916030a318SStefano Zampini PetscInt bs = 1, nfields, field; 792e630c359SToby Isaac PetscSection section = NULL; 793e630c359SToby Isaac 794552f7358SJed Brown if ((link->ft != PETSC_VTK_POINT_FIELD) && (link->ft != PETSC_VTK_POINT_VECTOR_FIELD)) continue; 7959566063dSJacob Faibussowitsch PetscCall(VecGetDM(X, &dmX)); 796e630c359SToby Isaac if (!dmX) dmX = dm; 7979566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery(link->vec, "section", (PetscObject *)§ion)); 7989566063dSJacob Faibussowitsch if (!section) PetscCall(DMGetLocalSection(dmX, §ion)); 7999566063dSJacob Faibussowitsch if (vEnd > vStart) PetscCall(PetscSectionGetDof(section, vStart, &bs)); 8009566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(section, &nfields)); 801e630c359SToby Isaac field = 0; 802e630c359SToby Isaac if (link->field >= 0) { 803e630c359SToby Isaac field = link->field; 804e630c359SToby Isaac nfields = field + 1; 805e630c359SToby Isaac } 806e630c359SToby Isaac for (i = 0; field < (nfields ? nfields : 1); field++) { 807e630c359SToby Isaac PetscInt fbs; 8086030a318SStefano Zampini if (nfields && vEnd > vStart) { /* We have user-defined fields/components */ 8099566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, vStart, field, &fbs)); 810e630c359SToby Isaac } else fbs = bs; /* Say we have one field with 'bs' components */ 811e630c359SToby Isaac if (link->ft == PETSC_VTK_POINT_VECTOR_FIELD) { 81248a46eb9SPierre Jolivet for (l = 0; l < loops_per_scalar; l++) PetscCall(TransferWrite(comm, viewer, fp, r, 0, NULL, buffer, gpiece[r].nvertices * 3, MPIU_VTUREAL, tag)); 813e630c359SToby Isaac } else { 814e630c359SToby Isaac for (i = 0; i < fbs; i++) { 81548a46eb9SPierre Jolivet for (l = 0; l < loops_per_scalar; l++) PetscCall(TransferWrite(comm, viewer, fp, r, 0, NULL, buffer, gpiece[r].nvertices, MPIU_VTUREAL, tag)); 816552f7358SJed Brown } 817552f7358SJed Brown } 818552f7358SJed Brown } 819552f7358SJed Brown } 820e630c359SToby Isaac } 821e630c359SToby Isaac } 8229566063dSJacob Faibussowitsch PetscCall(PetscFree(gpiece)); 8239566063dSJacob Faibussowitsch PetscCall(PetscFree(buffer)); 8249566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fp, "\n </AppendedData>\n")); 8259566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fp, "</VTKFile>\n")); 8269566063dSJacob Faibussowitsch PetscCall(PetscFClose(comm, fp)); 8273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 828552f7358SJed Brown } 829