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