1f9720913SMatthew G. Knepley #define PETSCDM_DLL 2f9720913SMatthew G. Knepley #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 3f9720913SMatthew G. Knepley 4f9720913SMatthew G. Knepley /*@C 5f9720913SMatthew G. Knepley DMPlexCreatePLYFromFile - Create a DMPlex mesh from a PLY file. 6f9720913SMatthew G. Knepley 7f9720913SMatthew G. Knepley + comm - The MPI communicator 8f9720913SMatthew G. Knepley . filename - Name of the .med file 9f9720913SMatthew G. Knepley - interpolate - Create faces and edges in the mesh 10f9720913SMatthew G. Knepley 11f9720913SMatthew G. Knepley Output Parameter: 12f9720913SMatthew G. Knepley . dm - The DM object representing the mesh 13f9720913SMatthew G. Knepley 14f9720913SMatthew G. Knepley Note: https://en.wikipedia.org/wiki/PLY_(file_format) 15f9720913SMatthew G. Knepley 16f9720913SMatthew G. Knepley Level: beginner 17f9720913SMatthew G. Knepley 18f9720913SMatthew G. Knepley .seealso: DMPlexCreateFromFile(), DMPlexCreateMedFromFile(), DMPlexCreateGmsh(), DMPlexCreate() 19f9720913SMatthew G. Knepley @*/ 20f9720913SMatthew G. Knepley PetscErrorCode DMPlexCreatePLYFromFile(MPI_Comm comm, const char filename[], PetscBool interpolate, DM *dm) 21f9720913SMatthew G. Knepley { 22f9720913SMatthew G. Knepley PetscViewer viewer; 23f9720913SMatthew G. Knepley Vec coordinates; 24f9720913SMatthew G. Knepley PetscSection coordSection; 25f9720913SMatthew G. Knepley PetscScalar *coords; 26f9720913SMatthew G. Knepley char line[PETSC_MAX_PATH_LEN], ntype[16], itype[16], name[1024], vtype[16]; 27f9720913SMatthew G. Knepley PetscBool match, byteSwap = PETSC_FALSE; 2864b21ff4SMatthew G. Knepley PetscInt dim = 2, cdim = 3, Nvp = 0, coordSize, xi = -1, yi = -1, zi = -1, v, c, p; 29f9720913SMatthew G. Knepley PetscMPIInt rank; 30f9720913SMatthew G. Knepley int snum, Nv, Nc; 31f9720913SMatthew G. Knepley PetscErrorCode ierr; 32f9720913SMatthew G. Knepley 33f9720913SMatthew G. Knepley PetscFunctionBegin; 34ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 35f9720913SMatthew G. Knepley ierr = PetscViewerCreate(comm, &viewer);CHKERRQ(ierr); 36f9720913SMatthew G. Knepley ierr = PetscViewerSetType(viewer, PETSCVIEWERBINARY);CHKERRQ(ierr); 37f9720913SMatthew G. Knepley ierr = PetscViewerFileSetMode(viewer, FILE_MODE_READ);CHKERRQ(ierr); 38f9720913SMatthew G. Knepley ierr = PetscViewerFileSetName(viewer, filename);CHKERRQ(ierr); 39dd400576SPatrick Sanan if (rank == 0) { 40f9720913SMatthew G. Knepley PetscBool isAscii, isBinaryBig, isBinaryLittle; 41f9720913SMatthew G. Knepley 42f9720913SMatthew G. Knepley /* Check for PLY file */ 43f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 44f9720913SMatthew G. Knepley ierr = PetscStrncmp(line, "ply", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 45*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!match,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid PLY file"); 46f9720913SMatthew G. Knepley /* Check PLY format */ 47f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 48f9720913SMatthew G. Knepley ierr = PetscStrncmp(line, "format", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 49*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!match,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid PLY file"); 50f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 51f9720913SMatthew G. Knepley ierr = PetscStrncmp(line, "ascii", PETSC_MAX_PATH_LEN, &isAscii);CHKERRQ(ierr); 52f9720913SMatthew G. Knepley ierr = PetscStrncmp(line, "binary_big_endian", PETSC_MAX_PATH_LEN, &isBinaryBig);CHKERRQ(ierr); 53f9720913SMatthew G. Knepley ierr = PetscStrncmp(line, "binary_little_endian", PETSC_MAX_PATH_LEN, &isBinaryLittle);CHKERRQ(ierr); 54*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(isAscii,PETSC_COMM_SELF, PETSC_ERR_SUP, "PLY ascii format not yet supported"); 55f9720913SMatthew G. Knepley else if (isBinaryLittle) byteSwap = PETSC_TRUE; 56f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 57f9720913SMatthew G. Knepley ierr = PetscStrncmp(line, "1.0", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 58*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!match,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid version of PLY file, %s", line); 59f9720913SMatthew G. Knepley /* Ignore comments */ 60f9720913SMatthew G. Knepley match = PETSC_TRUE; 61f9720913SMatthew G. Knepley while (match) { 62f9720913SMatthew G. Knepley char buf = '\0'; 63f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 64f9720913SMatthew G. Knepley ierr = PetscStrncmp(line, "comment", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 65f9720913SMatthew G. Knepley if (match) while (buf != '\n') {ierr = PetscViewerRead(viewer, &buf, 1, NULL, PETSC_CHAR);CHKERRQ(ierr);} 66f9720913SMatthew G. Knepley } 67f9720913SMatthew G. Knepley /* Read vertex information */ 68f9720913SMatthew G. Knepley ierr = PetscStrncmp(line, "element", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 69*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!match,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse PLY file header: %s", line); 70f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 71f9720913SMatthew G. Knepley ierr = PetscStrncmp(line, "vertex", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 72*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!match,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse PLY file header: %s", line); 73f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 74f9720913SMatthew G. Knepley snum = sscanf(line, "%d", &Nv); 75*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != 1,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse PLY file header: %s", line); 76f9720913SMatthew G. Knepley match = PETSC_TRUE; 77f9720913SMatthew G. Knepley while (match) { 78f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 79f9720913SMatthew G. Knepley ierr = PetscStrncmp(line, "property", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 80f9720913SMatthew G. Knepley if (match) { 81f9720913SMatthew G. Knepley PetscBool matchB; 82f9720913SMatthew G. Knepley 83f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 2, NULL, PETSC_STRING);CHKERRQ(ierr); 84*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(Nvp >= 16,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot handle more than 16 property statements in PLY file header: %s", line); 85f9720913SMatthew G. Knepley snum = sscanf(line, "%s %s", ntype, name); 86*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != 2,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse PLY file header: %s", line); 87f9720913SMatthew G. Knepley ierr = PetscStrncmp(ntype, "float32", 16, &matchB);CHKERRQ(ierr); 88f9720913SMatthew G. Knepley if (matchB) { 89f9720913SMatthew G. Knepley vtype[Nvp] = 'f'; 90f9720913SMatthew G. Knepley } else { 91f9720913SMatthew G. Knepley ierr = PetscStrncmp(ntype, "int32", 16, &matchB);CHKERRQ(ierr); 92f9720913SMatthew G. Knepley if (matchB) { 93f9720913SMatthew G. Knepley vtype[Nvp] = 'd'; 94f9720913SMatthew G. Knepley } else { 95f9720913SMatthew G. Knepley ierr = PetscStrncmp(ntype, "uint8", 16, &matchB);CHKERRQ(ierr); 96f9720913SMatthew G. Knepley if (matchB) { 97f9720913SMatthew G. Knepley vtype[Nvp] = 'c'; 9898921bdaSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse type in PLY file header: %s", line); 99f9720913SMatthew G. Knepley } 100f9720913SMatthew G. Knepley } 101f9720913SMatthew G. Knepley ierr = PetscStrncmp(name, "x", 16, &matchB);CHKERRQ(ierr); 102f9720913SMatthew G. Knepley if (matchB) {xi = Nvp;} 103f9720913SMatthew G. Knepley ierr = PetscStrncmp(name, "y", 16, &matchB);CHKERRQ(ierr); 104f9720913SMatthew G. Knepley if (matchB) {yi = Nvp;} 105f9720913SMatthew G. Knepley ierr = PetscStrncmp(name, "z", 16, &matchB);CHKERRQ(ierr); 106f9720913SMatthew G. Knepley if (matchB) {zi = Nvp;} 107f9720913SMatthew G. Knepley ++Nvp; 108f9720913SMatthew G. Knepley } 109f9720913SMatthew G. Knepley } 110f9720913SMatthew G. Knepley /* Read cell information */ 111f9720913SMatthew G. Knepley ierr = PetscStrncmp(line, "element", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 112*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!match,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse PLY file header: %s", line); 113f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 114f9720913SMatthew G. Knepley ierr = PetscStrncmp(line, "face", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 115*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!match,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse PLY file header: %s", line); 116f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 117f9720913SMatthew G. Knepley snum = sscanf(line, "%d", &Nc); 118*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != 1,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse PLY file header: %s", line); 119f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 5, NULL, PETSC_STRING);CHKERRQ(ierr); 120f9720913SMatthew G. Knepley snum = sscanf(line, "property list %s %s %s", ntype, itype, name); 121*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(snum != 3,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse PLY file header: %s", line); 122f9720913SMatthew G. Knepley ierr = PetscStrncmp(ntype, "uint8", 1024, &match);CHKERRQ(ierr); 123*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!match,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid size type in PLY file header: %s", line); 124f9720913SMatthew G. Knepley ierr = PetscStrncmp(name, "vertex_indices", 1024, &match);CHKERRQ(ierr); 125*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!match,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid property in PLY file header: %s", line); 126f9720913SMatthew G. Knepley /* Header should terminate */ 127f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 128f9720913SMatthew G. Knepley ierr = PetscStrncmp(line, "end_header", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 129*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!match,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid PLY file: %s", line); 13025ce1634SJed Brown } else { 13125ce1634SJed Brown Nc = Nv = 0; 132f9720913SMatthew G. Knepley } 133f9720913SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 134f9720913SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 135f9720913SMatthew G. Knepley ierr = DMPlexSetChart(*dm, 0, Nc+Nv);CHKERRQ(ierr); 136f9720913SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 137f9720913SMatthew G. Knepley ierr = DMSetCoordinateDim(*dm, cdim);CHKERRQ(ierr); 138f9720913SMatthew G. Knepley /* Read coordinates */ 139f9720913SMatthew G. Knepley ierr = DMGetCoordinateSection(*dm, &coordSection);CHKERRQ(ierr); 140f9720913SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 141f9720913SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, cdim);CHKERRQ(ierr); 142f9720913SMatthew G. Knepley ierr = PetscSectionSetChart(coordSection, Nc, Nc + Nv);CHKERRQ(ierr); 143f9720913SMatthew G. Knepley for (v = Nc; v < Nc+Nv; ++v) { 144f9720913SMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, cdim);CHKERRQ(ierr); 145f9720913SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, cdim);CHKERRQ(ierr); 146f9720913SMatthew G. Knepley } 147f9720913SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 148f9720913SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 149f9720913SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 150f9720913SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 151f9720913SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 152f9720913SMatthew G. Knepley ierr = VecSetBlockSize(coordinates, cdim);CHKERRQ(ierr); 153f9720913SMatthew G. Knepley ierr = VecSetType(coordinates, VECSTANDARD);CHKERRQ(ierr); 154f9720913SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 155dd400576SPatrick Sanan if (rank == 0) { 156f9720913SMatthew G. Knepley float rbuf[1]; 157f9720913SMatthew G. Knepley int ibuf[1]; 158f9720913SMatthew G. Knepley 159f9720913SMatthew G. Knepley for (v = 0; v < Nv; ++v) { 160f9720913SMatthew G. Knepley for (p = 0; p < Nvp; ++p) { 161f9720913SMatthew G. Knepley if (vtype[p] == 'f') { 162f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, &rbuf, 1, NULL, PETSC_FLOAT);CHKERRQ(ierr); 16360d4fc61SSatish Balay if (byteSwap) {ierr = PetscByteSwap(&rbuf, PETSC_FLOAT, 1);CHKERRQ(ierr);} 164f9720913SMatthew G. Knepley if (p == xi) coords[v*cdim+0] = rbuf[0]; 165f9720913SMatthew G. Knepley else if (p == yi) coords[v*cdim+1] = rbuf[0]; 166f9720913SMatthew G. Knepley else if (p == zi) coords[v*cdim+2] = rbuf[0]; 167f9720913SMatthew G. Knepley } else if (vtype[p] == 'd') { 168f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, &ibuf, 1, NULL, PETSC_INT);CHKERRQ(ierr); 16960d4fc61SSatish Balay if (byteSwap) {ierr = PetscByteSwap(&ibuf, PETSC_INT, 1);CHKERRQ(ierr);} 170f9720913SMatthew G. Knepley } else if (vtype[p] == 'c') { 171f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, &ibuf, 1, NULL, PETSC_CHAR);CHKERRQ(ierr); 172f9720913SMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid vertex property type in PLY file"); 173f9720913SMatthew G. Knepley } 174f9720913SMatthew G. Knepley } 175f9720913SMatthew G. Knepley } 176f9720913SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 177f9720913SMatthew G. Knepley ierr = DMSetCoordinatesLocal(*dm, coordinates);CHKERRQ(ierr); 178f9720913SMatthew G. Knepley ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 179f9720913SMatthew G. Knepley /* Read topology */ 180dd400576SPatrick Sanan if (rank == 0) { 181f9720913SMatthew G. Knepley char ibuf[1]; 182f9720913SMatthew G. Knepley PetscInt vbuf[16], corners; 183f9720913SMatthew G. Knepley 184f9720913SMatthew G. Knepley /* Assume same cells */ 185f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, &ibuf, 1, NULL, PETSC_CHAR);CHKERRQ(ierr); 186f9720913SMatthew G. Knepley corners = ibuf[0]; 187f9720913SMatthew G. Knepley for (c = 0; c < Nc; ++c) {ierr = DMPlexSetConeSize(*dm, c, corners);CHKERRQ(ierr);} 188f9720913SMatthew G. Knepley ierr = DMSetUp(*dm);CHKERRQ(ierr); 189f9720913SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 190f9720913SMatthew G. Knepley if (c > 0) { 191f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, &ibuf, 1, NULL, PETSC_CHAR);CHKERRQ(ierr); 192f9720913SMatthew G. Knepley } 193*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(ibuf[0] != corners,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "All cells must have the same number of vertices in PLY file: %D != %D", ibuf[0], corners); 194f9720913SMatthew G. Knepley ierr = PetscViewerRead(viewer, &vbuf, ibuf[0], NULL, PETSC_INT);CHKERRQ(ierr); 19560d4fc61SSatish Balay if (byteSwap) {ierr = PetscByteSwap(&vbuf, PETSC_INT, ibuf[0]);CHKERRQ(ierr);} 196f9720913SMatthew G. Knepley for (v = 0; v < ibuf[0]; ++v) vbuf[v] += Nc; 197f9720913SMatthew G. Knepley ierr = DMPlexSetCone(*dm, c, vbuf);CHKERRQ(ierr); 198f9720913SMatthew G. Knepley } 199f9720913SMatthew G. Knepley } 200f9720913SMatthew G. Knepley ierr = DMPlexSymmetrize(*dm);CHKERRQ(ierr); 201f9720913SMatthew G. Knepley ierr = DMPlexStratify(*dm);CHKERRQ(ierr); 202f9720913SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 203f9720913SMatthew G. Knepley if (interpolate) { 2045fd9971aSMatthew G. Knepley DM idm; 205f9720913SMatthew G. Knepley 206f9720913SMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 207f9720913SMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 208f9720913SMatthew G. Knepley *dm = idm; 209f9720913SMatthew G. Knepley } 210f9720913SMatthew G. Knepley PetscFunctionReturn(0); 211f9720913SMatthew G. Knepley } 212