1331830f3SMatthew G. Knepley #define PETSCDM_DLL 2af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 3730356f6SLisandro Dalcin #include <petsc/private/hashmapi.h> 4331830f3SMatthew G. Knepley 57d282ae0SMichael Lange /*@C 67d282ae0SMichael Lange DMPlexCreateGmshFromFile - Create a DMPlex mesh from a Gmsh file 77d282ae0SMichael Lange 87d282ae0SMichael Lange + comm - The MPI communicator 97d282ae0SMichael Lange . filename - Name of the Gmsh file 107d282ae0SMichael Lange - interpolate - Create faces and edges in the mesh 117d282ae0SMichael Lange 127d282ae0SMichael Lange Output Parameter: 137d282ae0SMichael Lange . dm - The DM object representing the mesh 147d282ae0SMichael Lange 157d282ae0SMichael Lange Level: beginner 167d282ae0SMichael Lange 177d282ae0SMichael Lange .seealso: DMPlexCreateFromFile(), DMPlexCreateGmsh(), DMPlexCreate() 187d282ae0SMichael Lange @*/ 197d282ae0SMichael Lange PetscErrorCode DMPlexCreateGmshFromFile(MPI_Comm comm, const char filename[], PetscBool interpolate, DM *dm) 207d282ae0SMichael Lange { 2111c56cb0SLisandro Dalcin PetscViewer viewer; 22abc86ac4SMichael Lange PetscMPIInt rank; 2311c56cb0SLisandro Dalcin int fileType; 247d282ae0SMichael Lange PetscViewerType vtype; 257d282ae0SMichael Lange PetscErrorCode ierr; 267d282ae0SMichael Lange 277d282ae0SMichael Lange PetscFunctionBegin; 28abc86ac4SMichael Lange ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 2911c56cb0SLisandro Dalcin 307d282ae0SMichael Lange /* Determine Gmsh file type (ASCII or binary) from file header */ 3111c56cb0SLisandro Dalcin if (!rank) { 3211c56cb0SLisandro Dalcin PetscViewer vheader; 3311c56cb0SLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 3411c56cb0SLisandro Dalcin PetscBool match; 3511c56cb0SLisandro Dalcin int snum; 3611c56cb0SLisandro Dalcin float version; 3711c56cb0SLisandro Dalcin 3811c56cb0SLisandro Dalcin ierr = PetscViewerCreate(PETSC_COMM_SELF, &vheader);CHKERRQ(ierr); 397d282ae0SMichael Lange ierr = PetscViewerSetType(vheader, PETSCVIEWERASCII);CHKERRQ(ierr); 407d282ae0SMichael Lange ierr = PetscViewerFileSetMode(vheader, FILE_MODE_READ);CHKERRQ(ierr); 417d282ae0SMichael Lange ierr = PetscViewerFileSetName(vheader, filename);CHKERRQ(ierr); 427d282ae0SMichael Lange /* Read only the first two lines of the Gmsh file */ 43060da220SMatthew G. Knepley ierr = PetscViewerRead(vheader, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 4411c56cb0SLisandro Dalcin ierr = PetscStrncmp(line, "$MeshFormat", sizeof(line), &match);CHKERRQ(ierr); 457d282ae0SMichael Lange if (!match) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 46060da220SMatthew G. Knepley ierr = PetscViewerRead(vheader, line, 2, NULL, PETSC_STRING);CHKERRQ(ierr); 4711c56cb0SLisandro Dalcin snum = sscanf(line, "%f %d", &version, &fileType); 48f6ac7a6aSMichael Lange if (snum != 2) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse Gmsh file header: %s", line); 49698a79b9SLisandro Dalcin if (version < 2.2) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Gmsh file version %3.1f must be at least 2.2", (double)version); 50698a79b9SLisandro Dalcin if ((int)version == 3) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Gmsh file version %3.1f not supported", (double)version); 51698a79b9SLisandro Dalcin if (version > 4.1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Gmsh file version %3.1f must be at most 4.1", (double)version); 5211c56cb0SLisandro Dalcin ierr = PetscViewerDestroy(&vheader);CHKERRQ(ierr); 53abc86ac4SMichael Lange } 5411c56cb0SLisandro Dalcin ierr = MPI_Bcast(&fileType, 1, MPI_INT, 0, comm);CHKERRQ(ierr); 5511c56cb0SLisandro Dalcin vtype = (fileType == 0) ? PETSCVIEWERASCII : PETSCVIEWERBINARY; 5611c56cb0SLisandro Dalcin 577d282ae0SMichael Lange /* Create appropriate viewer and build plex */ 587d282ae0SMichael Lange ierr = PetscViewerCreate(comm, &viewer);CHKERRQ(ierr); 597d282ae0SMichael Lange ierr = PetscViewerSetType(viewer, vtype);CHKERRQ(ierr); 607d282ae0SMichael Lange ierr = PetscViewerFileSetMode(viewer, FILE_MODE_READ);CHKERRQ(ierr); 617d282ae0SMichael Lange ierr = PetscViewerFileSetName(viewer, filename);CHKERRQ(ierr); 627d282ae0SMichael Lange ierr = DMPlexCreateGmsh(comm, viewer, interpolate, dm);CHKERRQ(ierr); 637d282ae0SMichael Lange ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 647d282ae0SMichael Lange PetscFunctionReturn(0); 657d282ae0SMichael Lange } 667d282ae0SMichael Lange 67de78e4feSLisandro Dalcin typedef struct { 68698a79b9SLisandro Dalcin PetscViewer viewer; 69698a79b9SLisandro Dalcin int fileFormat; 70698a79b9SLisandro Dalcin int dataSize; 71698a79b9SLisandro Dalcin PetscBool binary; 72698a79b9SLisandro Dalcin PetscBool byteSwap; 73698a79b9SLisandro Dalcin size_t wlen; 74698a79b9SLisandro Dalcin void *wbuf; 75698a79b9SLisandro Dalcin size_t slen; 76698a79b9SLisandro Dalcin void *sbuf; 77698a79b9SLisandro Dalcin } GmshFile; 78de78e4feSLisandro Dalcin 79698a79b9SLisandro Dalcin static PetscErrorCode GmshBufferGet(GmshFile *gmsh, size_t count, size_t eltsize, void *buf) 80de78e4feSLisandro Dalcin { 81de78e4feSLisandro Dalcin size_t size = count * eltsize; 8211c56cb0SLisandro Dalcin PetscErrorCode ierr; 8311c56cb0SLisandro Dalcin 8411c56cb0SLisandro Dalcin PetscFunctionBegin; 85698a79b9SLisandro Dalcin if (gmsh->wlen < size) { 86698a79b9SLisandro Dalcin ierr = PetscFree(gmsh->wbuf);CHKERRQ(ierr); 87698a79b9SLisandro Dalcin ierr = PetscMalloc(size, &gmsh->wbuf);CHKERRQ(ierr); 88698a79b9SLisandro Dalcin gmsh->wlen = size; 89de78e4feSLisandro Dalcin } 90698a79b9SLisandro Dalcin *(void**)buf = size ? gmsh->wbuf : NULL; 91de78e4feSLisandro Dalcin PetscFunctionReturn(0); 92de78e4feSLisandro Dalcin } 93de78e4feSLisandro Dalcin 94698a79b9SLisandro Dalcin static PetscErrorCode GmshBufferSizeGet(GmshFile *gmsh, size_t count, void *buf) 95698a79b9SLisandro Dalcin { 96698a79b9SLisandro Dalcin size_t dataSize = (size_t)gmsh->dataSize; 97698a79b9SLisandro Dalcin size_t size = count * dataSize; 98698a79b9SLisandro Dalcin PetscErrorCode ierr; 99698a79b9SLisandro Dalcin 100698a79b9SLisandro Dalcin PetscFunctionBegin; 101698a79b9SLisandro Dalcin if (gmsh->slen < size) { 102698a79b9SLisandro Dalcin ierr = PetscFree(gmsh->sbuf);CHKERRQ(ierr); 103698a79b9SLisandro Dalcin ierr = PetscMalloc(size, &gmsh->sbuf);CHKERRQ(ierr); 104698a79b9SLisandro Dalcin gmsh->slen = size; 105698a79b9SLisandro Dalcin } 106698a79b9SLisandro Dalcin *(void**)buf = size ? gmsh->sbuf : NULL; 107698a79b9SLisandro Dalcin PetscFunctionReturn(0); 108698a79b9SLisandro Dalcin } 109698a79b9SLisandro Dalcin 110698a79b9SLisandro Dalcin static PetscErrorCode GmshRead(GmshFile *gmsh, void *buf, PetscInt count, PetscDataType dtype) 111de78e4feSLisandro Dalcin { 112de78e4feSLisandro Dalcin PetscErrorCode ierr; 113de78e4feSLisandro Dalcin PetscFunctionBegin; 114698a79b9SLisandro Dalcin ierr = PetscViewerRead(gmsh->viewer, buf, count, NULL, dtype);CHKERRQ(ierr); 115698a79b9SLisandro Dalcin if (gmsh->byteSwap) {ierr = PetscByteSwap(buf, dtype, count);CHKERRQ(ierr);} 116698a79b9SLisandro Dalcin PetscFunctionReturn(0); 117698a79b9SLisandro Dalcin } 118698a79b9SLisandro Dalcin 119698a79b9SLisandro Dalcin static PetscErrorCode GmshReadString(GmshFile *gmsh, char *buf, PetscInt count) 120698a79b9SLisandro Dalcin { 121698a79b9SLisandro Dalcin PetscErrorCode ierr; 122698a79b9SLisandro Dalcin PetscFunctionBegin; 123698a79b9SLisandro Dalcin ierr = PetscViewerRead(gmsh->viewer, buf, count, NULL, PETSC_STRING);CHKERRQ(ierr); 124698a79b9SLisandro Dalcin PetscFunctionReturn(0); 125698a79b9SLisandro Dalcin } 126698a79b9SLisandro Dalcin 127698a79b9SLisandro Dalcin static PetscErrorCode GmshReadSize(GmshFile *gmsh, PetscInt *buf, PetscInt count) 128698a79b9SLisandro Dalcin { 129698a79b9SLisandro Dalcin PetscInt i; 130698a79b9SLisandro Dalcin size_t dataSize = (size_t)gmsh->dataSize; 131698a79b9SLisandro Dalcin PetscErrorCode ierr; 132698a79b9SLisandro Dalcin 133698a79b9SLisandro Dalcin PetscFunctionBegin; 134698a79b9SLisandro Dalcin if (dataSize == sizeof(PetscInt)) { 135698a79b9SLisandro Dalcin ierr = GmshRead(gmsh, buf, count, PETSC_INT);CHKERRQ(ierr); 136698a79b9SLisandro Dalcin } else if (dataSize == sizeof(int)) { 137698a79b9SLisandro Dalcin int *ibuf = NULL; 138698a79b9SLisandro Dalcin ierr = GmshBufferSizeGet(gmsh, count, &ibuf); 139698a79b9SLisandro Dalcin ierr = GmshRead(gmsh, ibuf, count, PETSC_ENUM);CHKERRQ(ierr); 140698a79b9SLisandro Dalcin for (i = 0; i < count; ++i) buf[i] = (PetscInt)ibuf[i]; 141698a79b9SLisandro Dalcin } else if (dataSize == sizeof(long)) { 142698a79b9SLisandro Dalcin long *ibuf = NULL; 143698a79b9SLisandro Dalcin ierr = GmshBufferSizeGet(gmsh, count, &ibuf); 144698a79b9SLisandro Dalcin ierr = GmshRead(gmsh, ibuf, count, PETSC_LONG);CHKERRQ(ierr); 145698a79b9SLisandro Dalcin for (i = 0; i < count; ++i) buf[i] = (PetscInt)ibuf[i]; 146698a79b9SLisandro Dalcin } else if (dataSize == sizeof(PetscInt64)) { 147698a79b9SLisandro Dalcin PetscInt64 *ibuf = NULL; 148698a79b9SLisandro Dalcin ierr = GmshBufferSizeGet(gmsh, count, &ibuf); 149698a79b9SLisandro Dalcin ierr = GmshRead(gmsh, ibuf, count, PETSC_INT64);CHKERRQ(ierr); 150698a79b9SLisandro Dalcin for (i = 0; i < count; ++i) buf[i] = (PetscInt)ibuf[i]; 151698a79b9SLisandro Dalcin } 152698a79b9SLisandro Dalcin PetscFunctionReturn(0); 153698a79b9SLisandro Dalcin } 154698a79b9SLisandro Dalcin 155698a79b9SLisandro Dalcin static PetscErrorCode GmshReadInt(GmshFile *gmsh, int *buf, PetscInt count) 156698a79b9SLisandro Dalcin { 157698a79b9SLisandro Dalcin PetscErrorCode ierr; 158698a79b9SLisandro Dalcin PetscFunctionBegin; 159698a79b9SLisandro Dalcin ierr = GmshRead(gmsh, buf, count, PETSC_ENUM);CHKERRQ(ierr); 160698a79b9SLisandro Dalcin PetscFunctionReturn(0); 161698a79b9SLisandro Dalcin } 162698a79b9SLisandro Dalcin 163698a79b9SLisandro Dalcin static PetscErrorCode GmshReadDouble(GmshFile *gmsh, double *buf, PetscInt count) 164698a79b9SLisandro Dalcin { 165698a79b9SLisandro Dalcin PetscErrorCode ierr; 166698a79b9SLisandro Dalcin PetscFunctionBegin; 167698a79b9SLisandro Dalcin ierr = GmshRead(gmsh, buf, count, PETSC_DOUBLE);CHKERRQ(ierr); 168de78e4feSLisandro Dalcin PetscFunctionReturn(0); 169de78e4feSLisandro Dalcin } 170de78e4feSLisandro Dalcin 171de78e4feSLisandro Dalcin typedef struct { 172de78e4feSLisandro Dalcin PetscInt id; /* Entity number */ 173698a79b9SLisandro Dalcin PetscInt dim; /* Entity dimension */ 174de78e4feSLisandro Dalcin double bbox[6]; /* Bounding box */ 175de78e4feSLisandro Dalcin PetscInt numTags; /* Size of tag array */ 176de78e4feSLisandro Dalcin int tags[4]; /* Tag array */ 177de78e4feSLisandro Dalcin } GmshEntity; 178de78e4feSLisandro Dalcin 179de78e4feSLisandro Dalcin typedef struct { 180730356f6SLisandro Dalcin GmshEntity *entity[4]; 181730356f6SLisandro Dalcin PetscHMapI entityMap[4]; 182730356f6SLisandro Dalcin } GmshEntities; 183730356f6SLisandro Dalcin 184698a79b9SLisandro Dalcin static PetscErrorCode GmshEntitiesCreate(PetscInt count[4], GmshEntities **entities) 185730356f6SLisandro Dalcin { 186730356f6SLisandro Dalcin PetscInt dim; 187730356f6SLisandro Dalcin PetscErrorCode ierr; 188730356f6SLisandro Dalcin 189730356f6SLisandro Dalcin PetscFunctionBegin; 190730356f6SLisandro Dalcin ierr = PetscNew(entities);CHKERRQ(ierr); 191730356f6SLisandro Dalcin for (dim = 0; dim < 4; ++dim) { 192730356f6SLisandro Dalcin ierr = PetscCalloc1(count[dim], &(*entities)->entity[dim]);CHKERRQ(ierr); 193730356f6SLisandro Dalcin ierr = PetscHMapICreate(&(*entities)->entityMap[dim]);CHKERRQ(ierr); 194730356f6SLisandro Dalcin } 195730356f6SLisandro Dalcin PetscFunctionReturn(0); 196730356f6SLisandro Dalcin } 197730356f6SLisandro Dalcin 198730356f6SLisandro Dalcin static PetscErrorCode GmshEntitiesAdd(GmshEntities *entities, PetscInt index, PetscInt dim, PetscInt eid, GmshEntity** entity) 199730356f6SLisandro Dalcin { 200730356f6SLisandro Dalcin PetscErrorCode ierr; 201730356f6SLisandro Dalcin PetscFunctionBegin; 202730356f6SLisandro Dalcin ierr = PetscHMapISet(entities->entityMap[dim], eid, index);CHKERRQ(ierr); 203730356f6SLisandro Dalcin entities->entity[dim][index].dim = dim; 204730356f6SLisandro Dalcin entities->entity[dim][index].id = eid; 205730356f6SLisandro Dalcin if (entity) *entity = &entities->entity[dim][index]; 206730356f6SLisandro Dalcin PetscFunctionReturn(0); 207730356f6SLisandro Dalcin } 208730356f6SLisandro Dalcin 209730356f6SLisandro Dalcin static PetscErrorCode GmshEntitiesGet(GmshEntities *entities, PetscInt dim, PetscInt eid, GmshEntity** entity) 210730356f6SLisandro Dalcin { 211730356f6SLisandro Dalcin PetscInt index; 212730356f6SLisandro Dalcin PetscErrorCode ierr; 213730356f6SLisandro Dalcin 214730356f6SLisandro Dalcin PetscFunctionBegin; 215730356f6SLisandro Dalcin ierr = PetscHMapIGet(entities->entityMap[dim], eid, &index);CHKERRQ(ierr); 216730356f6SLisandro Dalcin *entity = &entities->entity[dim][index]; 217730356f6SLisandro Dalcin PetscFunctionReturn(0); 218730356f6SLisandro Dalcin } 219730356f6SLisandro Dalcin 220730356f6SLisandro Dalcin static PetscErrorCode GmshEntitiesDestroy(GmshEntities **entities) 221730356f6SLisandro Dalcin { 222730356f6SLisandro Dalcin PetscInt dim; 223730356f6SLisandro Dalcin PetscErrorCode ierr; 224730356f6SLisandro Dalcin 225730356f6SLisandro Dalcin PetscFunctionBegin; 226730356f6SLisandro Dalcin if (!*entities) PetscFunctionReturn(0); 227730356f6SLisandro Dalcin for (dim = 0; dim < 4; ++dim) { 228730356f6SLisandro Dalcin ierr = PetscFree((*entities)->entity[dim]);CHKERRQ(ierr); 229730356f6SLisandro Dalcin ierr = PetscHMapIDestroy(&(*entities)->entityMap[dim]);CHKERRQ(ierr); 230730356f6SLisandro Dalcin } 231730356f6SLisandro Dalcin ierr = PetscFree((*entities));CHKERRQ(ierr); 232730356f6SLisandro Dalcin PetscFunctionReturn(0); 233730356f6SLisandro Dalcin } 234730356f6SLisandro Dalcin 235730356f6SLisandro Dalcin typedef struct { 236698a79b9SLisandro Dalcin PetscInt id; /* Entity number */ 237de78e4feSLisandro Dalcin PetscInt dim; /* Entity dimension */ 238de78e4feSLisandro Dalcin PetscInt cellType; /* Cell type */ 239de78e4feSLisandro Dalcin PetscInt numNodes; /* Size of node array */ 240698a79b9SLisandro Dalcin PetscInt nodes[8]; /* Node array */ 241de78e4feSLisandro Dalcin PetscInt numTags; /* Size of tag array */ 242de78e4feSLisandro Dalcin int tags[4]; /* Tag array */ 243de78e4feSLisandro Dalcin } GmshElement; 244de78e4feSLisandro Dalcin 245698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadNodes_v22(GmshFile *gmsh, int shift, PetscInt *numVertices, double **gmsh_nodes) 246de78e4feSLisandro Dalcin { 247698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 248698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 249de78e4feSLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 250698a79b9SLisandro Dalcin int v, num, nid, snum; 251698a79b9SLisandro Dalcin double *coordinates; 252de78e4feSLisandro Dalcin PetscErrorCode ierr; 253de78e4feSLisandro Dalcin 254de78e4feSLisandro Dalcin PetscFunctionBegin; 255de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 256698a79b9SLisandro Dalcin snum = sscanf(line, "%d", &num); 257de78e4feSLisandro Dalcin if (snum != 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 258698a79b9SLisandro Dalcin ierr = PetscMalloc1(num*3, &coordinates);CHKERRQ(ierr); 259698a79b9SLisandro Dalcin *numVertices = num; 260698a79b9SLisandro Dalcin *gmsh_nodes = coordinates; 261698a79b9SLisandro Dalcin for (v = 0; v < num; ++v) { 262698a79b9SLisandro Dalcin double *xyz = coordinates + v*3; 26311c56cb0SLisandro Dalcin ierr = PetscViewerRead(viewer, &nid, 1, NULL, PETSC_ENUM);CHKERRQ(ierr); 26411c56cb0SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&nid, PETSC_ENUM, 1);CHKERRQ(ierr);} 26511c56cb0SLisandro Dalcin if (nid != v+shift) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unexpected node number %d should be %d", nid, v+shift); 26611c56cb0SLisandro Dalcin ierr = PetscViewerRead(viewer, xyz, 3, NULL, PETSC_DOUBLE);CHKERRQ(ierr); 26711c56cb0SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(xyz, PETSC_DOUBLE, 3);CHKERRQ(ierr);} 26811c56cb0SLisandro Dalcin } 26911c56cb0SLisandro Dalcin PetscFunctionReturn(0); 27011c56cb0SLisandro Dalcin } 27111c56cb0SLisandro Dalcin 272de78e4feSLisandro Dalcin /* Gmsh elements can be of any dimension/co-dimension, so we need to traverse the 273de78e4feSLisandro Dalcin file contents multiple times to figure out the true number of cells and facets 274de78e4feSLisandro Dalcin in the given mesh. To make this more efficient we read the file contents only 275de78e4feSLisandro Dalcin once and store them in memory, while determining the true number of cells. */ 276698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadElements_v22(GmshFile* gmsh, PETSC_UNUSED int shift, PetscInt *numCells, GmshElement **gmsh_elems) 27711c56cb0SLisandro Dalcin { 278698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 279698a79b9SLisandro Dalcin PetscBool binary = gmsh->binary; 280698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 281de78e4feSLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 282df032b82SMatthew G. Knepley GmshElement *elements; 283698a79b9SLisandro Dalcin int i, c, p, num, ibuf[1+4+512], snum; 28411c56cb0SLisandro Dalcin int cellType, dim, numNodes, numNodesIgnore, numElem, numTags; 285df032b82SMatthew G. Knepley PetscErrorCode ierr; 286df032b82SMatthew G. Knepley 287df032b82SMatthew G. Knepley PetscFunctionBegin; 288de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr);; 289698a79b9SLisandro Dalcin snum = sscanf(line, "%d", &num); 290de78e4feSLisandro Dalcin if (snum != 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 291698a79b9SLisandro Dalcin ierr = PetscMalloc1(num, &elements);CHKERRQ(ierr); 292698a79b9SLisandro Dalcin *numCells = num; 293698a79b9SLisandro Dalcin *gmsh_elems = elements; 294698a79b9SLisandro Dalcin for (c = 0; c < num;) { 29511c56cb0SLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, 3, NULL, PETSC_ENUM);CHKERRQ(ierr); 29611c56cb0SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, 3);CHKERRQ(ierr);} 297df032b82SMatthew G. Knepley if (binary) { 298df032b82SMatthew G. Knepley cellType = ibuf[0]; 299df032b82SMatthew G. Knepley numElem = ibuf[1]; 300df032b82SMatthew G. Knepley numTags = ibuf[2]; 301df032b82SMatthew G. Knepley } else { 302df032b82SMatthew G. Knepley elements[c].id = ibuf[0]; 303df032b82SMatthew G. Knepley cellType = ibuf[1]; 304df032b82SMatthew G. Knepley numTags = ibuf[2]; 305df032b82SMatthew G. Knepley numElem = 1; 306df032b82SMatthew G. Knepley } 307bf6ba3a3SMatthew G. Knepley /* http://gmsh.info/doc/texinfo/gmsh.html#MSH-ASCII-file-format */ 308bf6ba3a3SMatthew G. Knepley numNodesIgnore = 0; 309df032b82SMatthew G. Knepley switch (cellType) { 310df032b82SMatthew G. Knepley case 1: /* 2-node line */ 311df032b82SMatthew G. Knepley dim = 1; 312df032b82SMatthew G. Knepley numNodes = 2; 313df032b82SMatthew G. Knepley break; 314df032b82SMatthew G. Knepley case 2: /* 3-node triangle */ 315df032b82SMatthew G. Knepley dim = 2; 316df032b82SMatthew G. Knepley numNodes = 3; 317df032b82SMatthew G. Knepley break; 318df032b82SMatthew G. Knepley case 3: /* 4-node quadrangle */ 319df032b82SMatthew G. Knepley dim = 2; 320df032b82SMatthew G. Knepley numNodes = 4; 321df032b82SMatthew G. Knepley break; 322df032b82SMatthew G. Knepley case 4: /* 4-node tetrahedron */ 323df032b82SMatthew G. Knepley dim = 3; 324df032b82SMatthew G. Knepley numNodes = 4; 325df032b82SMatthew G. Knepley break; 326df032b82SMatthew G. Knepley case 5: /* 8-node hexahedron */ 327df032b82SMatthew G. Knepley dim = 3; 328df032b82SMatthew G. Knepley numNodes = 8; 329df032b82SMatthew G. Knepley break; 330dea2a3c7SStefano Zampini case 6: /* 6-node wedge */ 331dea2a3c7SStefano Zampini dim = 3; 332dea2a3c7SStefano Zampini numNodes = 6; 333dea2a3c7SStefano Zampini break; 334bf6ba3a3SMatthew G. Knepley case 8: /* 3-node 2nd order line */ 335bf6ba3a3SMatthew G. Knepley dim = 1; 336bf6ba3a3SMatthew G. Knepley numNodes = 2; 337bf6ba3a3SMatthew G. Knepley numNodesIgnore = 1; 338bf6ba3a3SMatthew G. Knepley break; 339bf6ba3a3SMatthew G. Knepley case 9: /* 6-node 2nd order triangle */ 340bf6ba3a3SMatthew G. Knepley dim = 2; 341bf6ba3a3SMatthew G. Knepley numNodes = 3; 342bf6ba3a3SMatthew G. Knepley numNodesIgnore = 3; 343bf6ba3a3SMatthew G. Knepley break; 344dea2a3c7SStefano Zampini case 13: /* 18-node 2nd wedge */ 345dea2a3c7SStefano Zampini dim = 3; 346dea2a3c7SStefano Zampini numNodes = 6; 347dea2a3c7SStefano Zampini numNodesIgnore = 12; 348dea2a3c7SStefano Zampini break; 349df032b82SMatthew G. Knepley case 15: /* 1-node vertex */ 350df032b82SMatthew G. Knepley dim = 0; 351df032b82SMatthew G. Knepley numNodes = 1; 352df032b82SMatthew G. Knepley break; 353bf6ba3a3SMatthew G. Knepley case 7: /* 5-node pyramid */ 354bf6ba3a3SMatthew G. Knepley case 10: /* 9-node 2nd order quadrangle */ 355bf6ba3a3SMatthew G. Knepley case 11: /* 10-node 2nd order tetrahedron */ 356bf6ba3a3SMatthew G. Knepley case 12: /* 27-node 2nd order hexhedron */ 357bf6ba3a3SMatthew G. Knepley case 14: /* 14-node 2nd order pyramid */ 358df032b82SMatthew G. Knepley default: 359df032b82SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported Gmsh element type %d", cellType); 360df032b82SMatthew G. Knepley } 361df032b82SMatthew G. Knepley if (binary) { 36211c56cb0SLisandro Dalcin const int nint = 1 + numTags + numNodes + numNodesIgnore; 36311c56cb0SLisandro Dalcin /* Loop over element blocks */ 364df032b82SMatthew G. Knepley for (i = 0; i < numElem; ++i, ++c) { 36511c56cb0SLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, nint, NULL, PETSC_ENUM);CHKERRQ(ierr); 36611c56cb0SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, nint);CHKERRQ(ierr);} 367df032b82SMatthew G. Knepley elements[c].dim = dim; 368df032b82SMatthew G. Knepley elements[c].numNodes = numNodes; 369df032b82SMatthew G. Knepley elements[c].numTags = numTags; 370df032b82SMatthew G. Knepley elements[c].id = ibuf[0]; 371dea2a3c7SStefano Zampini elements[c].cellType = cellType; 372df032b82SMatthew G. Knepley for (p = 0; p < numTags; p++) elements[c].tags[p] = ibuf[1 + p]; 373df032b82SMatthew G. Knepley for (p = 0; p < numNodes; p++) elements[c].nodes[p] = ibuf[1 + numTags + p]; 374df032b82SMatthew G. Knepley } 375df032b82SMatthew G. Knepley } else { 376698a79b9SLisandro Dalcin const int nint = numTags + numNodes + numNodesIgnore; 377df032b82SMatthew G. Knepley elements[c].dim = dim; 378df032b82SMatthew G. Knepley elements[c].numNodes = numNodes; 379df032b82SMatthew G. Knepley elements[c].numTags = numTags; 380dea2a3c7SStefano Zampini elements[c].cellType = cellType; 381698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, nint, NULL, PETSC_ENUM);CHKERRQ(ierr); 382698a79b9SLisandro Dalcin for (p = 0; p < numTags; p++) elements[c].tags[p] = ibuf[p]; 383698a79b9SLisandro Dalcin for (p = 0; p < numNodes; p++) elements[c].nodes[p] = ibuf[numTags + p]; 384df032b82SMatthew G. Knepley c++; 385df032b82SMatthew G. Knepley } 386df032b82SMatthew G. Knepley } 387df032b82SMatthew G. Knepley PetscFunctionReturn(0); 388df032b82SMatthew G. Knepley } 3897d282ae0SMichael Lange 390de78e4feSLisandro Dalcin /* 391de78e4feSLisandro Dalcin $Entities 392de78e4feSLisandro Dalcin numPoints(unsigned long) numCurves(unsigned long) 393de78e4feSLisandro Dalcin numSurfaces(unsigned long) numVolumes(unsigned long) 394de78e4feSLisandro Dalcin // points 395de78e4feSLisandro Dalcin tag(int) boxMinX(double) boxMinY(double) boxMinZ(double) 396de78e4feSLisandro Dalcin boxMaxX(double) boxMaxY(double) boxMaxZ(double) 397de78e4feSLisandro Dalcin numPhysicals(unsigned long) phyisicalTag[...](int) 398de78e4feSLisandro Dalcin ... 399de78e4feSLisandro Dalcin // curves 400de78e4feSLisandro Dalcin tag(int) boxMinX(double) boxMinY(double) boxMinZ(double) 401de78e4feSLisandro Dalcin boxMaxX(double) boxMaxY(double) boxMaxZ(double) 402de78e4feSLisandro Dalcin numPhysicals(unsigned long) physicalTag[...](int) 403de78e4feSLisandro Dalcin numBREPVert(unsigned long) tagBREPVert[...](int) 404de78e4feSLisandro Dalcin ... 405de78e4feSLisandro Dalcin // surfaces 406de78e4feSLisandro Dalcin tag(int) boxMinX(double) boxMinY(double) boxMinZ(double) 407de78e4feSLisandro Dalcin boxMaxX(double) boxMaxY(double) boxMaxZ(double) 408de78e4feSLisandro Dalcin numPhysicals(unsigned long) physicalTag[...](int) 409de78e4feSLisandro Dalcin numBREPCurve(unsigned long) tagBREPCurve[...](int) 410de78e4feSLisandro Dalcin ... 411de78e4feSLisandro Dalcin // volumes 412de78e4feSLisandro Dalcin tag(int) boxMinX(double) boxMinY(double) boxMinZ(double) 413de78e4feSLisandro Dalcin boxMaxX(double) boxMaxY(double) boxMaxZ(double) 414de78e4feSLisandro Dalcin numPhysicals(unsigned long) physicalTag[...](int) 415de78e4feSLisandro Dalcin numBREPSurfaces(unsigned long) tagBREPSurfaces[...](int) 416de78e4feSLisandro Dalcin ... 417de78e4feSLisandro Dalcin $EndEntities 418de78e4feSLisandro Dalcin */ 419698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadEntities_v40(GmshFile *gmsh, GmshEntities **entities) 420de78e4feSLisandro Dalcin { 421698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 422698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 423698a79b9SLisandro Dalcin long index, num, lbuf[4]; 424730356f6SLisandro Dalcin int dim, eid, numTags, *ibuf, t; 425698a79b9SLisandro Dalcin PetscInt count[4], i; 426a5ba3d71SLisandro Dalcin GmshEntity *entity = NULL; 427de78e4feSLisandro Dalcin PetscErrorCode ierr; 428de78e4feSLisandro Dalcin 429de78e4feSLisandro Dalcin PetscFunctionBegin; 430698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, lbuf, 4, NULL, PETSC_LONG);CHKERRQ(ierr); 431698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(lbuf, PETSC_LONG, 4);CHKERRQ(ierr);} 432698a79b9SLisandro Dalcin for (i = 0; i < 4; ++i) count[i] = lbuf[i]; 433730356f6SLisandro Dalcin ierr = GmshEntitiesCreate(count, entities);CHKERRQ(ierr); 434de78e4feSLisandro Dalcin for (dim = 0; dim < 4; ++dim) { 435730356f6SLisandro Dalcin for (index = 0; index < count[dim]; ++index) { 436730356f6SLisandro Dalcin ierr = PetscViewerRead(viewer, &eid, 1, NULL, PETSC_ENUM);CHKERRQ(ierr); 437730356f6SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&eid, PETSC_ENUM, 1);CHKERRQ(ierr);} 438730356f6SLisandro Dalcin ierr = GmshEntitiesAdd(*entities, (PetscInt)index, dim, eid, &entity);CHKERRQ(ierr); 439de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, entity->bbox, 6, NULL, PETSC_DOUBLE);CHKERRQ(ierr); 440de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(entity->bbox, PETSC_DOUBLE, 6);CHKERRQ(ierr);} 441de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &num, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 442de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&num, PETSC_LONG, 1);CHKERRQ(ierr);} 443698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, num, sizeof(int), &ibuf);CHKERRQ(ierr); 444de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, num, NULL, PETSC_ENUM);CHKERRQ(ierr); 445730356f6SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, num);CHKERRQ(ierr);} 446de78e4feSLisandro Dalcin entity->numTags = numTags = (int) PetscMin(num, 4); 447de78e4feSLisandro Dalcin for (t = 0; t < numTags; ++t) entity->tags[t] = ibuf[t]; 448de78e4feSLisandro Dalcin if (dim == 0) continue; 449de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &num, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 450de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&num, PETSC_LONG, 1);CHKERRQ(ierr);} 451698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, num, sizeof(int), &ibuf);CHKERRQ(ierr); 452de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, num, NULL, PETSC_ENUM);CHKERRQ(ierr); 453730356f6SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, num);CHKERRQ(ierr);} 454de78e4feSLisandro Dalcin } 455de78e4feSLisandro Dalcin } 456de78e4feSLisandro Dalcin PetscFunctionReturn(0); 457de78e4feSLisandro Dalcin } 458de78e4feSLisandro Dalcin 459de78e4feSLisandro Dalcin /* 460de78e4feSLisandro Dalcin $Nodes 461de78e4feSLisandro Dalcin numEntityBlocks(unsigned long) numNodes(unsigned long) 462de78e4feSLisandro Dalcin tagEntity(int) dimEntity(int) typeNode(int) numNodes(unsigned long) 463de78e4feSLisandro Dalcin tag(int) x(double) y(double) z(double) 464de78e4feSLisandro Dalcin ... 465de78e4feSLisandro Dalcin ... 466de78e4feSLisandro Dalcin $EndNodes 467de78e4feSLisandro Dalcin */ 468698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadNodes_v40(GmshFile *gmsh, int shift, PetscInt *numVertices, double **gmsh_nodes) 469de78e4feSLisandro Dalcin { 470698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 471698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 472de78e4feSLisandro Dalcin long block, node, v, numEntityBlocks, numTotalNodes, numNodes; 473de78e4feSLisandro Dalcin int info[3], nid; 474de78e4feSLisandro Dalcin double *coordinates; 475de78e4feSLisandro Dalcin char *cbuf; 476de78e4feSLisandro Dalcin PetscErrorCode ierr; 477de78e4feSLisandro Dalcin 478de78e4feSLisandro Dalcin PetscFunctionBegin; 479de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numEntityBlocks, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 480de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numEntityBlocks, PETSC_LONG, 1);CHKERRQ(ierr);} 481de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numTotalNodes, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 482de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numTotalNodes, PETSC_LONG, 1);CHKERRQ(ierr);} 483de78e4feSLisandro Dalcin ierr = PetscMalloc1(numTotalNodes*3, &coordinates);CHKERRQ(ierr); 484698a79b9SLisandro Dalcin *numVertices = numTotalNodes; 485de78e4feSLisandro Dalcin *gmsh_nodes = coordinates; 486de78e4feSLisandro Dalcin for (v = 0, block = 0; block < numEntityBlocks; ++block) { 487de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, info, 3, NULL, PETSC_ENUM);CHKERRQ(ierr); 488de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numNodes, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 489de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numNodes, PETSC_LONG, 1);CHKERRQ(ierr);} 490698a79b9SLisandro Dalcin if (gmsh->binary) { 491de78e4feSLisandro Dalcin int nbytes = sizeof(int) + 3*sizeof(double); 492698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numNodes, nbytes, &cbuf);CHKERRQ(ierr); 493de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, cbuf, numNodes*nbytes, NULL, PETSC_CHAR);CHKERRQ(ierr); 494de78e4feSLisandro Dalcin for (node = 0; node < numNodes; ++node, ++v) { 495de78e4feSLisandro Dalcin char *cnid = cbuf + node*nbytes, *cxyz = cnid + sizeof(int); 496de78e4feSLisandro Dalcin double *xyz = coordinates + v*3; 497de78e4feSLisandro Dalcin #if !defined(PETSC_WORDS_BIGENDIAN) 498de78e4feSLisandro Dalcin ierr = PetscByteSwap(cnid, PETSC_ENUM, 1);CHKERRQ(ierr); 499de78e4feSLisandro Dalcin ierr = PetscByteSwap(cxyz, PETSC_DOUBLE, 3);CHKERRQ(ierr); 500de78e4feSLisandro Dalcin #endif 501de78e4feSLisandro Dalcin ierr = PetscMemcpy(&nid, cnid, sizeof(int));CHKERRQ(ierr); 502de78e4feSLisandro Dalcin ierr = PetscMemcpy(xyz, cxyz, 3*sizeof(double));CHKERRQ(ierr); 503de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&nid, PETSC_ENUM, 1);CHKERRQ(ierr);} 504de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(xyz, PETSC_DOUBLE, 3);CHKERRQ(ierr);} 505de78e4feSLisandro Dalcin if (nid != v+shift) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unexpected node number %d should be %d", nid, v+shift); 506de78e4feSLisandro Dalcin } 507de78e4feSLisandro Dalcin } else { 508de78e4feSLisandro Dalcin for (node = 0; node < numNodes; ++node, ++v) { 509de78e4feSLisandro Dalcin double *xyz = coordinates + v*3; 510de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &nid, 1, NULL, PETSC_ENUM);CHKERRQ(ierr); 511de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&nid, PETSC_ENUM, 1);CHKERRQ(ierr);} 512de78e4feSLisandro Dalcin if (nid != v+shift) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unexpected node number %d should be %d", nid, v+shift); 513de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, xyz, 3, NULL, PETSC_DOUBLE);CHKERRQ(ierr); 514de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(xyz, PETSC_DOUBLE, 3);CHKERRQ(ierr);} 515de78e4feSLisandro Dalcin } 516de78e4feSLisandro Dalcin } 517de78e4feSLisandro Dalcin } 518de78e4feSLisandro Dalcin PetscFunctionReturn(0); 519de78e4feSLisandro Dalcin } 520de78e4feSLisandro Dalcin 521de78e4feSLisandro Dalcin /* 522de78e4feSLisandro Dalcin $Elements 523de78e4feSLisandro Dalcin numEntityBlocks(unsigned long) numElements(unsigned long) 524de78e4feSLisandro Dalcin tagEntity(int) dimEntity(int) typeEle(int) numElements(unsigned long) 525de78e4feSLisandro Dalcin tag(int) numVert[...](int) 526de78e4feSLisandro Dalcin ... 527de78e4feSLisandro Dalcin ... 528de78e4feSLisandro Dalcin $EndElements 529de78e4feSLisandro Dalcin */ 530698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadElements_v40(GmshFile *gmsh, PETSC_UNUSED int shift, GmshEntities *entities, PetscInt *numCells, GmshElement **gmsh_elems) 531de78e4feSLisandro Dalcin { 532698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 533698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 534de78e4feSLisandro Dalcin long c, block, numEntityBlocks, numTotalElements, elem, numElements; 535de78e4feSLisandro Dalcin int p, info[3], *ibuf = NULL; 536de78e4feSLisandro Dalcin int eid, dim, numTags, *tags, cellType, numNodes; 537a5ba3d71SLisandro Dalcin GmshEntity *entity = NULL; 538de78e4feSLisandro Dalcin GmshElement *elements; 539de78e4feSLisandro Dalcin PetscErrorCode ierr; 540de78e4feSLisandro Dalcin 541de78e4feSLisandro Dalcin PetscFunctionBegin; 542de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numEntityBlocks, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 543de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numEntityBlocks, PETSC_LONG, 1);CHKERRQ(ierr);} 544de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numTotalElements, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 545de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numTotalElements, PETSC_LONG, 1);CHKERRQ(ierr);} 546de78e4feSLisandro Dalcin ierr = PetscCalloc1(numTotalElements, &elements);CHKERRQ(ierr); 547698a79b9SLisandro Dalcin *numCells = numTotalElements; 548de78e4feSLisandro Dalcin *gmsh_elems = elements; 549de78e4feSLisandro Dalcin for (c = 0, block = 0; block < numEntityBlocks; ++block) { 550de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, info, 3, NULL, PETSC_ENUM);CHKERRQ(ierr); 551de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(info, PETSC_ENUM, 3);CHKERRQ(ierr);} 552de78e4feSLisandro Dalcin eid = info[0]; dim = info[1]; cellType = info[2]; 553730356f6SLisandro Dalcin ierr = GmshEntitiesGet(entities, dim, eid, &entity);CHKERRQ(ierr); 554730356f6SLisandro Dalcin numTags = entity->numTags; 555730356f6SLisandro Dalcin tags = entity->tags; 556de78e4feSLisandro Dalcin switch (cellType) { 557de78e4feSLisandro Dalcin case 1: /* 2-node line */ 558de78e4feSLisandro Dalcin numNodes = 2; 559de78e4feSLisandro Dalcin break; 560de78e4feSLisandro Dalcin case 2: /* 3-node triangle */ 561698a79b9SLisandro Dalcin numNodes = 3; 562698a79b9SLisandro Dalcin break; 563de78e4feSLisandro Dalcin case 3: /* 4-node quadrangle */ 564de78e4feSLisandro Dalcin numNodes = 4; 565de78e4feSLisandro Dalcin break; 566de78e4feSLisandro Dalcin case 4: /* 4-node tetrahedron */ 567de78e4feSLisandro Dalcin numNodes = 4; 568de78e4feSLisandro Dalcin break; 569de78e4feSLisandro Dalcin case 5: /* 8-node hexahedron */ 570de78e4feSLisandro Dalcin numNodes = 8; 571de78e4feSLisandro Dalcin break; 572de78e4feSLisandro Dalcin case 6: /* 6-node wedge */ 573de78e4feSLisandro Dalcin numNodes = 6; 574de78e4feSLisandro Dalcin break; 575de78e4feSLisandro Dalcin case 15: /* 1-node vertex */ 576de78e4feSLisandro Dalcin numNodes = 1; 577de78e4feSLisandro Dalcin break; 578de78e4feSLisandro Dalcin default: 579de78e4feSLisandro Dalcin SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported Gmsh element type %d", cellType); 580de78e4feSLisandro Dalcin } 581de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numElements, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 582de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numElements, PETSC_LONG, 1);CHKERRQ(ierr);} 583698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, (1+numNodes)*numElements, sizeof(int), &ibuf);CHKERRQ(ierr); 584de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, (1+numNodes)*numElements, NULL, PETSC_ENUM);CHKERRQ(ierr); 585de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, (1+numNodes)*numElements);CHKERRQ(ierr);} 586de78e4feSLisandro Dalcin for (elem = 0; elem < numElements; ++elem, ++c) { 587de78e4feSLisandro Dalcin int *id = ibuf + elem*(1+numNodes), *nodes = id + 1; 588de78e4feSLisandro Dalcin GmshElement *element = elements + c; 589de78e4feSLisandro Dalcin element->dim = dim; 590de78e4feSLisandro Dalcin element->cellType = cellType; 591de78e4feSLisandro Dalcin element->numNodes = numNodes; 592de78e4feSLisandro Dalcin element->numTags = numTags; 593de78e4feSLisandro Dalcin element->id = id[0]; 594de78e4feSLisandro Dalcin for (p = 0; p < numNodes; p++) element->nodes[p] = nodes[p]; 595de78e4feSLisandro Dalcin for (p = 0; p < numTags; p++) element->tags[p] = tags[p]; 596de78e4feSLisandro Dalcin } 597de78e4feSLisandro Dalcin } 598698a79b9SLisandro Dalcin PetscFunctionReturn(0); 599698a79b9SLisandro Dalcin } 600698a79b9SLisandro Dalcin 601698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadPeriodic_v40(GmshFile *gmsh, int shift, PetscInt slaveMap[], PetscBT bt) 602698a79b9SLisandro Dalcin { 603698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 604698a79b9SLisandro Dalcin int fileFormat = gmsh->fileFormat; 605698a79b9SLisandro Dalcin PetscBool binary = gmsh->binary; 606698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 607698a79b9SLisandro Dalcin int numPeriodic, snum, i; 608698a79b9SLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 609698a79b9SLisandro Dalcin PetscErrorCode ierr; 610698a79b9SLisandro Dalcin 611698a79b9SLisandro Dalcin PetscFunctionBegin; 612698a79b9SLisandro Dalcin if (fileFormat == 22 || !binary) { 613698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 614698a79b9SLisandro Dalcin snum = sscanf(line, "%d", &numPeriodic); 615698a79b9SLisandro Dalcin if (snum != 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 616698a79b9SLisandro Dalcin } else { 617698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, &numPeriodic, 1, NULL, PETSC_ENUM);CHKERRQ(ierr); 618698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numPeriodic, PETSC_ENUM, 1);CHKERRQ(ierr);} 619698a79b9SLisandro Dalcin } 620698a79b9SLisandro Dalcin for (i = 0; i < numPeriodic; i++) { 621698a79b9SLisandro Dalcin int ibuf[3], slaveDim = -1, slaveTag = -1, masterTag = -1, slaveNode, masterNode; 622698a79b9SLisandro Dalcin long j, nNodes; 623698a79b9SLisandro Dalcin double affine[16]; 624698a79b9SLisandro Dalcin 625698a79b9SLisandro Dalcin if (fileFormat == 22 || !binary) { 626698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 3, NULL, PETSC_STRING);CHKERRQ(ierr); 627698a79b9SLisandro Dalcin snum = sscanf(line, "%d %d %d", &slaveDim, &slaveTag, &masterTag); 628698a79b9SLisandro Dalcin if (snum != 3) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 629698a79b9SLisandro Dalcin } else { 630698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, 3, NULL, PETSC_ENUM);CHKERRQ(ierr); 631698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, 3);CHKERRQ(ierr);} 632698a79b9SLisandro Dalcin slaveDim = ibuf[0]; slaveTag = ibuf[1]; masterTag = ibuf[2]; 633698a79b9SLisandro Dalcin } 634698a79b9SLisandro Dalcin (void)slaveDim; (void)slaveTag; (void)masterTag; /* unused */ 635698a79b9SLisandro Dalcin 636698a79b9SLisandro Dalcin if (fileFormat == 22 || !binary) { 637698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 638698a79b9SLisandro Dalcin snum = sscanf(line, "%ld", &nNodes); 639698a79b9SLisandro Dalcin if (snum != 1) { /* discard tranformation and try again */ 640698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, -PETSC_MAX_PATH_LEN, NULL, PETSC_STRING);CHKERRQ(ierr); 641698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 642698a79b9SLisandro Dalcin snum = sscanf(line, "%ld", &nNodes); 643698a79b9SLisandro Dalcin if (snum != 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 644698a79b9SLisandro Dalcin } 645698a79b9SLisandro Dalcin } else { 646698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, &nNodes, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 647698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&nNodes, PETSC_LONG, 1);CHKERRQ(ierr);} 648698a79b9SLisandro Dalcin if (nNodes == -1) { /* discard tranformation and try again */ 649698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, affine, 16, NULL, PETSC_DOUBLE);CHKERRQ(ierr); 650698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, &nNodes, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 651698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&nNodes, PETSC_LONG, 1);CHKERRQ(ierr);} 652698a79b9SLisandro Dalcin } 653698a79b9SLisandro Dalcin } 654698a79b9SLisandro Dalcin 655698a79b9SLisandro Dalcin for (j = 0; j < nNodes; j++) { 656698a79b9SLisandro Dalcin if (fileFormat == 22 || !binary) { 657698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 2, NULL, PETSC_STRING);CHKERRQ(ierr); 658698a79b9SLisandro Dalcin snum = sscanf(line, "%d %d", &slaveNode, &masterNode); 659698a79b9SLisandro Dalcin if (snum != 2) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 660698a79b9SLisandro Dalcin } else { 661698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, 2, NULL, PETSC_ENUM);CHKERRQ(ierr); 662698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, 2);CHKERRQ(ierr);} 663698a79b9SLisandro Dalcin slaveNode = ibuf[0]; masterNode = ibuf[1]; 664698a79b9SLisandro Dalcin } 665698a79b9SLisandro Dalcin slaveMap[slaveNode - shift] = masterNode - shift; 666698a79b9SLisandro Dalcin ierr = PetscBTSet(bt, slaveNode - shift);CHKERRQ(ierr); 667698a79b9SLisandro Dalcin ierr = PetscBTSet(bt, masterNode - shift);CHKERRQ(ierr); 668698a79b9SLisandro Dalcin } 669698a79b9SLisandro Dalcin } 670698a79b9SLisandro Dalcin PetscFunctionReturn(0); 671698a79b9SLisandro Dalcin } 672698a79b9SLisandro Dalcin 673698a79b9SLisandro Dalcin /* 674698a79b9SLisandro Dalcin $Entities 675698a79b9SLisandro Dalcin numPoints(size_t) numCurves(size_t) 676698a79b9SLisandro Dalcin numSurfaces(size_t) numVolumes(size_t) 677698a79b9SLisandro Dalcin pointTag(int) X(double) Y(double) Z(double) 678698a79b9SLisandro Dalcin numPhysicalTags(size_t) physicalTag(int) ... 679698a79b9SLisandro Dalcin ... 680698a79b9SLisandro Dalcin curveTag(int) minX(double) minY(double) minZ(double) 681698a79b9SLisandro Dalcin maxX(double) maxY(double) maxZ(double) 682698a79b9SLisandro Dalcin numPhysicalTags(size_t) physicalTag(int) ... 683698a79b9SLisandro Dalcin numBoundingPoints(size_t) pointTag(int) ... 684698a79b9SLisandro Dalcin ... 685698a79b9SLisandro Dalcin surfaceTag(int) minX(double) minY(double) minZ(double) 686698a79b9SLisandro Dalcin maxX(double) maxY(double) maxZ(double) 687698a79b9SLisandro Dalcin numPhysicalTags(size_t) physicalTag(int) ... 688698a79b9SLisandro Dalcin numBoundingCurves(size_t) curveTag(int) ... 689698a79b9SLisandro Dalcin ... 690698a79b9SLisandro Dalcin volumeTag(int) minX(double) minY(double) minZ(double) 691698a79b9SLisandro Dalcin maxX(double) maxY(double) maxZ(double) 692698a79b9SLisandro Dalcin numPhysicalTags(size_t) physicalTag(int) ... 693698a79b9SLisandro Dalcin numBoundngSurfaces(size_t) surfaceTag(int) ... 694698a79b9SLisandro Dalcin ... 695698a79b9SLisandro Dalcin $EndEntities 696698a79b9SLisandro Dalcin */ 697698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadEntities_v41(GmshFile *gmsh, GmshEntities **entities) 698698a79b9SLisandro Dalcin { 699698a79b9SLisandro Dalcin PetscInt count[4], index, numTags, i; 700698a79b9SLisandro Dalcin int dim, eid, *tags = NULL; 701698a79b9SLisandro Dalcin GmshEntity *entity = NULL; 702698a79b9SLisandro Dalcin PetscErrorCode ierr; 703698a79b9SLisandro Dalcin 704698a79b9SLisandro Dalcin PetscFunctionBegin; 705698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, count, 4);CHKERRQ(ierr); 706698a79b9SLisandro Dalcin ierr = GmshEntitiesCreate(count, entities);CHKERRQ(ierr); 707698a79b9SLisandro Dalcin for (dim = 0; dim < 4; ++dim) { 708698a79b9SLisandro Dalcin for (index = 0; index < count[dim]; ++index) { 709698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, &eid, 1);CHKERRQ(ierr); 710698a79b9SLisandro Dalcin ierr = GmshEntitiesAdd(*entities, (PetscInt)index, dim, eid, &entity);CHKERRQ(ierr); 711698a79b9SLisandro Dalcin ierr = GmshReadDouble(gmsh, entity->bbox, (dim == 0) ? 3 : 6);CHKERRQ(ierr); 712698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numTags, 1);CHKERRQ(ierr); 713698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numTags, sizeof(int), &tags);CHKERRQ(ierr); 714698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, tags, numTags);CHKERRQ(ierr); 715698a79b9SLisandro Dalcin entity->numTags = PetscMin(numTags, 4); 716698a79b9SLisandro Dalcin for (i = 0; i < entity->numTags; ++i) entity->tags[i] = tags[i]; 717698a79b9SLisandro Dalcin if (dim == 0) continue; 718698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numTags, 1);CHKERRQ(ierr); 719698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numTags, sizeof(int), &tags);CHKERRQ(ierr); 720698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, tags, numTags);CHKERRQ(ierr); 721698a79b9SLisandro Dalcin } 722698a79b9SLisandro Dalcin } 723698a79b9SLisandro Dalcin PetscFunctionReturn(0); 724698a79b9SLisandro Dalcin } 725698a79b9SLisandro Dalcin 726698a79b9SLisandro Dalcin /* 727698a79b9SLisandro Dalcin $Nodes 728698a79b9SLisandro Dalcin numEntityBlocks(size_t) numNodes(size_t) 729698a79b9SLisandro Dalcin minNodeTag(size_t) maxNodeTag(size_t) 730698a79b9SLisandro Dalcin entityDim(int) entityTag(int) parametric(int; 0 or 1) numNodesBlock(size_t) 731698a79b9SLisandro Dalcin nodeTag(size_t) 732698a79b9SLisandro Dalcin ... 733698a79b9SLisandro Dalcin x(double) y(double) z(double) 734698a79b9SLisandro Dalcin < u(double; if parametric and entityDim = 1 or entityDim = 2) > 735698a79b9SLisandro Dalcin < v(double; if parametric and entityDim = 2) > 736698a79b9SLisandro Dalcin ... 737698a79b9SLisandro Dalcin ... 738698a79b9SLisandro Dalcin $EndNodes 739698a79b9SLisandro Dalcin */ 740698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadNodes_v41(GmshFile *gmsh, int shift, PetscInt *numVertices, double **gmsh_nodes) 741698a79b9SLisandro Dalcin { 742698a79b9SLisandro Dalcin int info[3]; 743698a79b9SLisandro Dalcin PetscInt sizes[4], numEntityBlocks, numNodes, numNodesBlock = 0, *nodeTag = NULL, block, node, i; 744698a79b9SLisandro Dalcin double *coordinates; 745698a79b9SLisandro Dalcin PetscErrorCode ierr; 746698a79b9SLisandro Dalcin 747698a79b9SLisandro Dalcin PetscFunctionBegin; 748698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, sizes, 4);CHKERRQ(ierr); 749698a79b9SLisandro Dalcin numEntityBlocks = sizes[0]; numNodes = sizes[1]; 750698a79b9SLisandro Dalcin ierr = PetscMalloc1(numNodes*3, &coordinates);CHKERRQ(ierr); 751698a79b9SLisandro Dalcin *numVertices = numNodes; 752698a79b9SLisandro Dalcin *gmsh_nodes = coordinates; 753698a79b9SLisandro Dalcin for (block = 0, node = 0; block < numEntityBlocks; ++block, node += numNodesBlock) { 754698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, info, 3);CHKERRQ(ierr); 755698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numNodesBlock, 1);CHKERRQ(ierr); 756698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numNodesBlock, sizeof(PetscInt), &nodeTag);CHKERRQ(ierr); 757698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, nodeTag, numNodesBlock);CHKERRQ(ierr); 758698a79b9SLisandro Dalcin for (i = 0; i < numNodesBlock; ++i) if (nodeTag[i] != node+i+shift) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unexpected node number %d should be %d", nodeTag[i], node+i+shift); 759698a79b9SLisandro Dalcin if (info[2] != 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Parametric coordinates not supported"); 760698a79b9SLisandro Dalcin ierr = GmshReadDouble(gmsh, coordinates+node*3, numNodesBlock*3);CHKERRQ(ierr); 761698a79b9SLisandro Dalcin } 762698a79b9SLisandro Dalcin PetscFunctionReturn(0); 763698a79b9SLisandro Dalcin } 764698a79b9SLisandro Dalcin 765698a79b9SLisandro Dalcin /* 766698a79b9SLisandro Dalcin $Elements 767698a79b9SLisandro Dalcin numEntityBlocks(size_t) numElements(size_t) 768698a79b9SLisandro Dalcin minElementTag(size_t) maxElementTag(size_t) 769698a79b9SLisandro Dalcin entityDim(int) entityTag(int) elementType(int; see below) numElementsBlock(size_t) 770698a79b9SLisandro Dalcin elementTag(size_t) nodeTag(size_t) ... 771698a79b9SLisandro Dalcin ... 772698a79b9SLisandro Dalcin ... 773698a79b9SLisandro Dalcin $EndElements 774698a79b9SLisandro Dalcin */ 775698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadElements_v41(GmshFile *gmsh, PETSC_UNUSED int shift, GmshEntities *entities, PetscInt *numCells, GmshElement **gmsh_elems) 776698a79b9SLisandro Dalcin { 777698a79b9SLisandro Dalcin int info[3], eid, dim, cellType, *tags; 778698a79b9SLisandro Dalcin PetscInt sizes[4], *ibuf = NULL, numEntityBlocks, numElements, numBlockElements, numNodes, numTags, block, elem, c, p; 779698a79b9SLisandro Dalcin GmshEntity *entity = NULL; 780698a79b9SLisandro Dalcin GmshElement *elements; 781698a79b9SLisandro Dalcin PetscErrorCode ierr; 782698a79b9SLisandro Dalcin 783698a79b9SLisandro Dalcin PetscFunctionBegin; 784698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, sizes, 4);CHKERRQ(ierr); 785698a79b9SLisandro Dalcin numEntityBlocks = sizes[0]; numElements = sizes[1]; 786698a79b9SLisandro Dalcin ierr = PetscCalloc1(numElements, &elements);CHKERRQ(ierr); 787698a79b9SLisandro Dalcin *numCells = numElements; 788698a79b9SLisandro Dalcin *gmsh_elems = elements; 789698a79b9SLisandro Dalcin for (c = 0, block = 0; block < numEntityBlocks; ++block) { 790698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, info, 3);CHKERRQ(ierr); 791698a79b9SLisandro Dalcin dim = info[0]; eid = info[1]; cellType = info[2]; 792698a79b9SLisandro Dalcin ierr = GmshEntitiesGet(entities, dim, eid, &entity);CHKERRQ(ierr); 793698a79b9SLisandro Dalcin numTags = entity->numTags; 794698a79b9SLisandro Dalcin tags = entity->tags; 795698a79b9SLisandro Dalcin switch (cellType) { 796698a79b9SLisandro Dalcin case 1: /* 2-node line */ 797698a79b9SLisandro Dalcin numNodes = 2; 798698a79b9SLisandro Dalcin break; 799698a79b9SLisandro Dalcin case 2: /* 3-node triangle */ 800698a79b9SLisandro Dalcin numNodes = 3; 801698a79b9SLisandro Dalcin break; 802698a79b9SLisandro Dalcin case 3: /* 4-node quadrangle */ 803698a79b9SLisandro Dalcin numNodes = 4; 804698a79b9SLisandro Dalcin break; 805698a79b9SLisandro Dalcin case 4: /* 4-node tetrahedron */ 806698a79b9SLisandro Dalcin numNodes = 4; 807698a79b9SLisandro Dalcin break; 808698a79b9SLisandro Dalcin case 5: /* 8-node hexahedron */ 809698a79b9SLisandro Dalcin numNodes = 8; 810698a79b9SLisandro Dalcin break; 811698a79b9SLisandro Dalcin case 6: /* 6-node wedge */ 812698a79b9SLisandro Dalcin numNodes = 6; 813698a79b9SLisandro Dalcin break; 814698a79b9SLisandro Dalcin case 15: /* 1-node vertex */ 815698a79b9SLisandro Dalcin numNodes = 1; 816698a79b9SLisandro Dalcin break; 817698a79b9SLisandro Dalcin default: 818698a79b9SLisandro Dalcin SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported Gmsh element type %d", cellType); 819698a79b9SLisandro Dalcin } 820698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numBlockElements, 1);CHKERRQ(ierr); 821698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, (1+numNodes)*numBlockElements, sizeof(PetscInt), &ibuf);CHKERRQ(ierr); 822698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, ibuf, (1+numNodes)*numBlockElements);CHKERRQ(ierr); 823698a79b9SLisandro Dalcin for (elem = 0; elem < numBlockElements; ++elem, ++c) { 824698a79b9SLisandro Dalcin GmshElement *element = elements + c; 825698a79b9SLisandro Dalcin PetscInt *id = ibuf + elem*(1+numNodes), *nodes = id + 1; 826698a79b9SLisandro Dalcin element->id = id[0]; 827698a79b9SLisandro Dalcin element->dim = dim; 828698a79b9SLisandro Dalcin element->cellType = cellType; 829698a79b9SLisandro Dalcin element->numNodes = numNodes; 830698a79b9SLisandro Dalcin element->numTags = numTags; 831698a79b9SLisandro Dalcin for (p = 0; p < numNodes; p++) element->nodes[p] = nodes[p]; 832698a79b9SLisandro Dalcin for (p = 0; p < numTags; p++) element->tags[p] = tags[p]; 833698a79b9SLisandro Dalcin } 834698a79b9SLisandro Dalcin } 835698a79b9SLisandro Dalcin PetscFunctionReturn(0); 836698a79b9SLisandro Dalcin } 837698a79b9SLisandro Dalcin 838698a79b9SLisandro Dalcin /* 839698a79b9SLisandro Dalcin $Periodic 840698a79b9SLisandro Dalcin numPeriodicLinks(size_t) 841698a79b9SLisandro Dalcin entityDim(int) entityTag(int) entityTagMaster(int) 842698a79b9SLisandro Dalcin numAffine(size_t) value(double) ... 843698a79b9SLisandro Dalcin numCorrespondingNodes(size_t) 844698a79b9SLisandro Dalcin nodeTag(size_t) nodeTagMaster(size_t) 845698a79b9SLisandro Dalcin ... 846698a79b9SLisandro Dalcin ... 847698a79b9SLisandro Dalcin $EndPeriodic 848698a79b9SLisandro Dalcin */ 849698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadPeriodic_v41(GmshFile *gmsh, int shift, PetscInt slaveMap[], PetscBT bt) 850698a79b9SLisandro Dalcin { 851698a79b9SLisandro Dalcin int info[3]; 852698a79b9SLisandro Dalcin PetscInt numPeriodicLinks, numAffine, numCorrespondingNodes, *nodeTags = NULL, link, node; 853698a79b9SLisandro Dalcin double dbuf[16]; 854698a79b9SLisandro Dalcin PetscErrorCode ierr; 855698a79b9SLisandro Dalcin 856698a79b9SLisandro Dalcin PetscFunctionBegin; 857698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numPeriodicLinks, 1);CHKERRQ(ierr); 858698a79b9SLisandro Dalcin for (link = 0; link < numPeriodicLinks; ++link) { 859698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, info, 3);CHKERRQ(ierr); 860698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numAffine, 1);CHKERRQ(ierr); 861698a79b9SLisandro Dalcin ierr = GmshReadDouble(gmsh, dbuf, numAffine);CHKERRQ(ierr); 862698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numCorrespondingNodes, 1);CHKERRQ(ierr); 863698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numCorrespondingNodes, sizeof(PetscInt), &nodeTags);CHKERRQ(ierr); 864698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, nodeTags, numCorrespondingNodes*2);CHKERRQ(ierr); 865698a79b9SLisandro Dalcin for (node = 0; node < numCorrespondingNodes; ++node) { 866698a79b9SLisandro Dalcin PetscInt slaveNode = nodeTags[node*2+0] - shift; 867698a79b9SLisandro Dalcin PetscInt masterNode = nodeTags[node*2+1] - shift; 868698a79b9SLisandro Dalcin slaveMap[slaveNode] = masterNode; 869698a79b9SLisandro Dalcin ierr = PetscBTSet(bt, slaveNode);CHKERRQ(ierr); 870698a79b9SLisandro Dalcin ierr = PetscBTSet(bt, masterNode);CHKERRQ(ierr); 871698a79b9SLisandro Dalcin } 872698a79b9SLisandro Dalcin } 873698a79b9SLisandro Dalcin PetscFunctionReturn(0); 874698a79b9SLisandro Dalcin } 875698a79b9SLisandro Dalcin 876698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadMeshFormat(GmshFile *gmsh) 877698a79b9SLisandro Dalcin { 878698a79b9SLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 879698a79b9SLisandro Dalcin int snum, fileType, fileFormat, dataSize, checkEndian; 880698a79b9SLisandro Dalcin float version; 881698a79b9SLisandro Dalcin PetscErrorCode ierr; 882698a79b9SLisandro Dalcin 883698a79b9SLisandro Dalcin PetscFunctionBegin; 884698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 3);CHKERRQ(ierr); 885698a79b9SLisandro Dalcin snum = sscanf(line, "%f %d %d", &version, &fileType, &dataSize); 886698a79b9SLisandro Dalcin if (snum != 3) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse Gmsh file header: %s", line); 887698a79b9SLisandro Dalcin if (version < 2.2) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Gmsh file version %3.1f must be at least 2.2", (double)version); 888698a79b9SLisandro Dalcin if ((int)version == 3) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Gmsh file version %3.1f not supported", (double)version); 889698a79b9SLisandro Dalcin if (version > 4.1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Gmsh file version %3.1f must be at most 4.1", (double)version); 890698a79b9SLisandro Dalcin if (gmsh->binary && !fileType) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Viewer is binary but Gmsh file is ASCII"); 891698a79b9SLisandro Dalcin if (!gmsh->binary && fileType) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Viewer is ASCII but Gmsh file is binary"); 892698a79b9SLisandro Dalcin fileFormat = (int)(version*10); /* XXX Should use (int)roundf(version*10) ? */ 893698a79b9SLisandro Dalcin if (fileFormat <= 40 && dataSize != sizeof(double)) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Data size %d is not valid for a Gmsh file", dataSize); 894698a79b9SLisandro Dalcin if (fileFormat >= 41 && dataSize != sizeof(int) && dataSize != sizeof(PetscInt64)) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Data size %d is not valid for a Gmsh file", dataSize); 895698a79b9SLisandro Dalcin gmsh->fileFormat = fileFormat; 896698a79b9SLisandro Dalcin gmsh->dataSize = dataSize; 897698a79b9SLisandro Dalcin gmsh->byteSwap = PETSC_FALSE; 898698a79b9SLisandro Dalcin if (gmsh->binary) { 899698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, &checkEndian, 1);CHKERRQ(ierr); 900698a79b9SLisandro Dalcin if (checkEndian != 1) { 901698a79b9SLisandro Dalcin ierr = PetscByteSwap(&checkEndian, PETSC_ENUM, 1);CHKERRQ(ierr); 902698a79b9SLisandro Dalcin if (checkEndian != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to detect endianness in Gmsh file header: %s", line); 903698a79b9SLisandro Dalcin gmsh->byteSwap = PETSC_TRUE; 904698a79b9SLisandro Dalcin } 905698a79b9SLisandro Dalcin } 906698a79b9SLisandro Dalcin PetscFunctionReturn(0); 907698a79b9SLisandro Dalcin } 908698a79b9SLisandro Dalcin 909*1f643af3SLisandro Dalcin /* 910*1f643af3SLisandro Dalcin PhysicalNames 911*1f643af3SLisandro Dalcin numPhysicalNames(ASCII int) 912*1f643af3SLisandro Dalcin dimension(ASCII int) physicalTag(ASCII int) "name"(127 characters max) 913*1f643af3SLisandro Dalcin ... 914*1f643af3SLisandro Dalcin $EndPhysicalNames 915*1f643af3SLisandro Dalcin */ 916698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadPhysicalNames(GmshFile *gmsh) 917698a79b9SLisandro Dalcin { 918*1f643af3SLisandro Dalcin char line[PETSC_MAX_PATH_LEN], name[128+2], *p, *q; 919*1f643af3SLisandro Dalcin int snum, numRegions, region, dim, tag; 920698a79b9SLisandro Dalcin PetscErrorCode ierr; 921698a79b9SLisandro Dalcin 922698a79b9SLisandro Dalcin PetscFunctionBegin; 923698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 924698a79b9SLisandro Dalcin snum = sscanf(line, "%d", &numRegions); 925698a79b9SLisandro Dalcin if (snum != 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 926698a79b9SLisandro Dalcin for (region = 0; region < numRegions; ++region) { 927*1f643af3SLisandro Dalcin ierr = GmshReadString(gmsh, line, 2);CHKERRQ(ierr); 928*1f643af3SLisandro Dalcin snum = sscanf(line, "%d %d", &dim, &tag); 929*1f643af3SLisandro Dalcin if (snum != 2) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 930*1f643af3SLisandro Dalcin ierr = GmshReadString(gmsh, line, -(PetscInt)sizeof(line));CHKERRQ(ierr); 931*1f643af3SLisandro Dalcin ierr = PetscStrchr(line, '"', &p);CHKERRQ(ierr); 932*1f643af3SLisandro Dalcin if (!p) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 933*1f643af3SLisandro Dalcin ierr = PetscStrrchr(line, '"', &q);CHKERRQ(ierr); 934*1f643af3SLisandro Dalcin if (q == p) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 935*1f643af3SLisandro Dalcin ierr = PetscStrncpy(name, p+1, (size_t)(q-p-1));CHKERRQ(ierr); 936698a79b9SLisandro Dalcin } 937de78e4feSLisandro Dalcin PetscFunctionReturn(0); 938de78e4feSLisandro Dalcin } 939de78e4feSLisandro Dalcin 940331830f3SMatthew G. Knepley /*@ 9417d282ae0SMichael Lange DMPlexCreateGmsh - Create a DMPlex mesh from a Gmsh file viewer 942331830f3SMatthew G. Knepley 943331830f3SMatthew G. Knepley Collective on comm 944331830f3SMatthew G. Knepley 945331830f3SMatthew G. Knepley Input Parameters: 946331830f3SMatthew G. Knepley + comm - The MPI communicator 947331830f3SMatthew G. Knepley . viewer - The Viewer associated with a Gmsh file 948331830f3SMatthew G. Knepley - interpolate - Create faces and edges in the mesh 949331830f3SMatthew G. Knepley 950331830f3SMatthew G. Knepley Output Parameter: 951331830f3SMatthew G. Knepley . dm - The DM object representing the mesh 952331830f3SMatthew G. Knepley 953698a79b9SLisandro Dalcin Note: http://gmsh.info/doc/texinfo/gmsh.html#MSH-file-format 954331830f3SMatthew G. Knepley 955331830f3SMatthew G. Knepley Level: beginner 956331830f3SMatthew G. Knepley 957331830f3SMatthew G. Knepley .keywords: mesh,Gmsh 958331830f3SMatthew G. Knepley .seealso: DMPLEX, DMCreate() 959331830f3SMatthew G. Knepley @*/ 960331830f3SMatthew G. Knepley PetscErrorCode DMPlexCreateGmsh(MPI_Comm comm, PetscViewer viewer, PetscBool interpolate, DM *dm) 961331830f3SMatthew G. Knepley { 96211c56cb0SLisandro Dalcin PetscViewer parentviewer = NULL; 96311c56cb0SLisandro Dalcin double *coordsIn = NULL; 964730356f6SLisandro Dalcin GmshEntities *entities = NULL; 9653c67d5adSSatish Balay GmshElement *gmsh_elem = NULL; 966331830f3SMatthew G. Knepley PetscSection coordSection; 967331830f3SMatthew G. Knepley Vec coordinates; 9686fbe17bfSStefano Zampini PetscBT periodicV = NULL, periodicC = NULL; 96984572febSToby Isaac PetscScalar *coords; 970698a79b9SLisandro Dalcin PetscInt dim = 0, embedDim = -1, coordSize, c, v, d, cell, *periodicMap = NULL, *periodicMapI = NULL, *hybridMap = NULL, cMax = PETSC_DETERMINE; 971698a79b9SLisandro Dalcin PetscInt numVertices = 0, numCells = 0, trueNumCells = 0; 972698a79b9SLisandro Dalcin int i, shift = 1; 97311c56cb0SLisandro Dalcin PetscMPIInt rank; 974698a79b9SLisandro Dalcin PetscBool binary, zerobase = PETSC_FALSE, periodic = PETSC_FALSE, usemarker = PETSC_FALSE; 975dea2a3c7SStefano Zampini PetscBool enable_hybrid = PETSC_FALSE; 976331830f3SMatthew G. Knepley PetscErrorCode ierr; 977331830f3SMatthew G. Knepley 978331830f3SMatthew G. Knepley PetscFunctionBegin; 979331830f3SMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 980dea2a3c7SStefano Zampini ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_gmsh_hybrid", &enable_hybrid, NULL);CHKERRQ(ierr); 981dea2a3c7SStefano Zampini ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_gmsh_periodic", &periodic, NULL);CHKERRQ(ierr); 982dea2a3c7SStefano Zampini ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_gmsh_use_marker", &usemarker, NULL);CHKERRQ(ierr); 983dea2a3c7SStefano Zampini ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_gmsh_zero_base", &zerobase, NULL);CHKERRQ(ierr); 984dea2a3c7SStefano Zampini ierr = PetscOptionsGetInt(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_gmsh_spacedim", &embedDim, NULL);CHKERRQ(ierr); 98511c56cb0SLisandro Dalcin if (zerobase) shift = 0; 98611c56cb0SLisandro Dalcin 987331830f3SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 988331830f3SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 9893b3bc66dSMichael Lange ierr = PetscLogEventBegin(DMPLEX_CreateGmsh,*dm,0,0,0);CHKERRQ(ierr); 99011c56cb0SLisandro Dalcin 99111c56cb0SLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &binary);CHKERRQ(ierr); 99211c56cb0SLisandro Dalcin 99311c56cb0SLisandro Dalcin /* Binary viewers read on all ranks, get subviewer to read only in rank 0 */ 9943b46f529SLisandro Dalcin if (binary) { 99511c56cb0SLisandro Dalcin parentviewer = viewer; 99611c56cb0SLisandro Dalcin ierr = PetscViewerGetSubViewer(parentviewer, PETSC_COMM_SELF, &viewer);CHKERRQ(ierr); 99711c56cb0SLisandro Dalcin } 99811c56cb0SLisandro Dalcin 9993b46f529SLisandro Dalcin if (!rank) { 1000698a79b9SLisandro Dalcin GmshFile gmsh_, *gmsh = &gmsh_; 1001698a79b9SLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 1002698a79b9SLisandro Dalcin PetscBool match; 1003331830f3SMatthew G. Knepley 1004698a79b9SLisandro Dalcin ierr = PetscMemzero(gmsh,sizeof(GmshFile));CHKERRQ(ierr); 1005698a79b9SLisandro Dalcin gmsh->viewer = viewer; 1006698a79b9SLisandro Dalcin gmsh->binary = binary; 1007698a79b9SLisandro Dalcin 1008698a79b9SLisandro Dalcin /* Read mesh format */ 1009698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 101004d1ad83SMichael Lange ierr = PetscStrncmp(line, "$MeshFormat", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 1011331830f3SMatthew G. Knepley if (!match) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 1012698a79b9SLisandro Dalcin ierr = DMPlexCreateGmsh_ReadMeshFormat(gmsh);CHKERRQ(ierr); 1013698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 101404d1ad83SMichael Lange ierr = PetscStrncmp(line, "$EndMeshFormat", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 1015331830f3SMatthew G. Knepley if (!match) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 101611c56cb0SLisandro Dalcin 1017dc0ede3bSMatthew G. Knepley /* OPTIONAL Read physical names */ 1018698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 1019dc0ede3bSMatthew G. Knepley ierr = PetscStrncmp(line, "$PhysicalNames", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 1020dc0ede3bSMatthew G. Knepley if (match) { 1021698a79b9SLisandro Dalcin ierr = DMPlexCreateGmsh_ReadPhysicalNames(gmsh);CHKERRQ(ierr); 1022698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 1023dc0ede3bSMatthew G. Knepley ierr = PetscStrncmp(line, "$EndPhysicalNames", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 1024dc0ede3bSMatthew G. Knepley if (!match) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 1025698a79b9SLisandro Dalcin /* Initial read for entity section */ 1026698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 1027dc0ede3bSMatthew G. Knepley } 102811c56cb0SLisandro Dalcin 1029de78e4feSLisandro Dalcin /* Read entities */ 1030698a79b9SLisandro Dalcin if (gmsh->fileFormat >= 40) { 1031de78e4feSLisandro Dalcin ierr = PetscStrncmp(line, "$Entities", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 1032de78e4feSLisandro Dalcin if (!match) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 1033698a79b9SLisandro Dalcin switch (gmsh->fileFormat) { 1034698a79b9SLisandro Dalcin case 41: ierr = DMPlexCreateGmsh_ReadEntities_v41(gmsh, &entities);CHKERRQ(ierr); break; 1035698a79b9SLisandro Dalcin default: ierr = DMPlexCreateGmsh_ReadEntities_v40(gmsh, &entities);CHKERRQ(ierr); break; 1036698a79b9SLisandro Dalcin } 1037698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 1038de78e4feSLisandro Dalcin ierr = PetscStrncmp(line, "$EndEntities", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 1039de78e4feSLisandro Dalcin if (!match) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 1040698a79b9SLisandro Dalcin /* Initial read for nodes section */ 1041698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 1042de78e4feSLisandro Dalcin } 1043de78e4feSLisandro Dalcin 1044698a79b9SLisandro Dalcin /* Read nodes */ 104504d1ad83SMichael Lange ierr = PetscStrncmp(line, "$Nodes", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 1046331830f3SMatthew G. Knepley if (!match) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 1047698a79b9SLisandro Dalcin switch (gmsh->fileFormat) { 1048698a79b9SLisandro Dalcin case 41: ierr = DMPlexCreateGmsh_ReadNodes_v41(gmsh, shift, &numVertices, &coordsIn);CHKERRQ(ierr); break; 1049698a79b9SLisandro Dalcin case 40: ierr = DMPlexCreateGmsh_ReadNodes_v40(gmsh, shift, &numVertices, &coordsIn);CHKERRQ(ierr); break; 1050698a79b9SLisandro Dalcin default: ierr = DMPlexCreateGmsh_ReadNodes_v22(gmsh, shift, &numVertices, &coordsIn);CHKERRQ(ierr); break; 1051de78e4feSLisandro Dalcin } 1052698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 105304d1ad83SMichael Lange ierr = PetscStrncmp(line, "$EndNodes", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 1054331830f3SMatthew G. Knepley if (!match) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 105511c56cb0SLisandro Dalcin 1056698a79b9SLisandro Dalcin /* Read elements */ 1057698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr);; 105804d1ad83SMichael Lange ierr = PetscStrncmp(line, "$Elements", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 1059331830f3SMatthew G. Knepley if (!match) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 1060698a79b9SLisandro Dalcin switch (gmsh->fileFormat) { 1061698a79b9SLisandro Dalcin case 41: ierr = DMPlexCreateGmsh_ReadElements_v41(gmsh, shift, entities, &numCells, &gmsh_elem);CHKERRQ(ierr); break; 1062698a79b9SLisandro Dalcin case 40: ierr = DMPlexCreateGmsh_ReadElements_v40(gmsh, shift, entities, &numCells, &gmsh_elem);CHKERRQ(ierr); break; 1063698a79b9SLisandro Dalcin default: ierr = DMPlexCreateGmsh_ReadElements_v22(gmsh, shift, &numCells, &gmsh_elem);CHKERRQ(ierr); 1064de78e4feSLisandro Dalcin } 1065698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 1066698a79b9SLisandro Dalcin ierr = PetscStrncmp(line, "$EndElements", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 1067de78e4feSLisandro Dalcin if (!match) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 1068de78e4feSLisandro Dalcin 1069698a79b9SLisandro Dalcin /* OPTIONAL Read periodic section */ 1070698a79b9SLisandro Dalcin if (periodic) { 1071698a79b9SLisandro Dalcin PetscInt pVert, *periodicMapT, *aux; 1072de78e4feSLisandro Dalcin 1073698a79b9SLisandro Dalcin ierr = PetscMalloc1(numVertices, &periodicMapT);CHKERRQ(ierr); 1074698a79b9SLisandro Dalcin ierr = PetscBTCreate(numVertices, &periodicV);CHKERRQ(ierr); 1075698a79b9SLisandro Dalcin for (i = 0; i < numVertices; i++) periodicMapT[i] = i; 1076698a79b9SLisandro Dalcin 1077698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 1078698a79b9SLisandro Dalcin ierr = PetscStrncmp(line, "$Periodic", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 1079698a79b9SLisandro Dalcin if (!match) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 1080698a79b9SLisandro Dalcin switch (gmsh->fileFormat) { 1081698a79b9SLisandro Dalcin case 41: ierr = DMPlexCreateGmsh_ReadPeriodic_v41(gmsh, shift, periodicMapT, periodicV);CHKERRQ(ierr); break; 1082698a79b9SLisandro Dalcin default: ierr = DMPlexCreateGmsh_ReadPeriodic_v40(gmsh, shift, periodicMapT, periodicV);CHKERRQ(ierr); break; 1083698a79b9SLisandro Dalcin } 1084698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 1085698a79b9SLisandro Dalcin ierr = PetscStrncmp(line, "$EndPeriodic", PETSC_MAX_PATH_LEN, &match);CHKERRQ(ierr); 1086698a79b9SLisandro Dalcin if (!match) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 1087698a79b9SLisandro Dalcin 1088698a79b9SLisandro Dalcin /* we may have slaves of slaves */ 1089698a79b9SLisandro Dalcin for (i = 0; i < numVertices; i++) { 1090698a79b9SLisandro Dalcin while (periodicMapT[periodicMapT[i]] != periodicMapT[i]) { 1091698a79b9SLisandro Dalcin periodicMapT[i] = periodicMapT[periodicMapT[i]]; 1092698a79b9SLisandro Dalcin } 1093698a79b9SLisandro Dalcin } 1094698a79b9SLisandro Dalcin /* periodicMap : from old to new numbering (periodic vertices excluded) 1095698a79b9SLisandro Dalcin periodicMapI: from new to old numbering */ 1096698a79b9SLisandro Dalcin ierr = PetscMalloc1(numVertices, &periodicMap);CHKERRQ(ierr); 1097698a79b9SLisandro Dalcin ierr = PetscMalloc1(numVertices, &periodicMapI);CHKERRQ(ierr); 1098698a79b9SLisandro Dalcin ierr = PetscMalloc1(numVertices, &aux);CHKERRQ(ierr); 1099698a79b9SLisandro Dalcin for (i = 0, pVert = 0; i < numVertices; i++) { 1100698a79b9SLisandro Dalcin if (periodicMapT[i] != i) { 1101698a79b9SLisandro Dalcin pVert++; 1102698a79b9SLisandro Dalcin } else { 1103698a79b9SLisandro Dalcin aux[i] = i - pVert; 1104698a79b9SLisandro Dalcin periodicMapI[i - pVert] = i; 1105698a79b9SLisandro Dalcin } 1106698a79b9SLisandro Dalcin } 1107698a79b9SLisandro Dalcin for (i = 0 ; i < numVertices; i++) { 1108698a79b9SLisandro Dalcin periodicMap[i] = aux[periodicMapT[i]]; 1109698a79b9SLisandro Dalcin } 1110698a79b9SLisandro Dalcin ierr = PetscFree(periodicMapT);CHKERRQ(ierr); 1111698a79b9SLisandro Dalcin ierr = PetscFree(aux);CHKERRQ(ierr); 1112698a79b9SLisandro Dalcin /* remove periodic vertices */ 1113698a79b9SLisandro Dalcin numVertices = numVertices - pVert; 1114698a79b9SLisandro Dalcin } 1115698a79b9SLisandro Dalcin 1116698a79b9SLisandro Dalcin ierr = GmshEntitiesDestroy(&entities);CHKERRQ(ierr); 1117698a79b9SLisandro Dalcin ierr = PetscFree(gmsh->wbuf);CHKERRQ(ierr); 1118698a79b9SLisandro Dalcin ierr = PetscFree(gmsh->sbuf);CHKERRQ(ierr); 1119698a79b9SLisandro Dalcin } 1120698a79b9SLisandro Dalcin 1121698a79b9SLisandro Dalcin if (parentviewer) { 1122698a79b9SLisandro Dalcin ierr = PetscViewerRestoreSubViewer(parentviewer, PETSC_COMM_SELF, &viewer);CHKERRQ(ierr); 1123698a79b9SLisandro Dalcin } 1124698a79b9SLisandro Dalcin 1125698a79b9SLisandro Dalcin if (!rank) { 1126698a79b9SLisandro Dalcin PetscBool hybrid = PETSC_FALSE; 1127698a79b9SLisandro Dalcin 1128a4bb7517SMichael Lange for (trueNumCells = 0, c = 0; c < numCells; ++c) { 1129dea2a3c7SStefano Zampini int on = -1; 1130a4bb7517SMichael Lange if (gmsh_elem[c].dim > dim) {dim = gmsh_elem[c].dim; trueNumCells = 0;} 1131dea2a3c7SStefano Zampini if (gmsh_elem[c].dim == dim) {hybrid = (trueNumCells ? (on != gmsh_elem[c].cellType ? on = gmsh_elem[c].cellType,PETSC_TRUE : hybrid) : (on = gmsh_elem[c].cellType, PETSC_FALSE) ); trueNumCells++;} 1132dea2a3c7SStefano Zampini /* wedges always indicate an hybrid mesh in PLEX */ 1133dea2a3c7SStefano Zampini if (on == 6 || on == 13) hybrid = PETSC_TRUE; 1134db397164SMichael Lange } 1135dea2a3c7SStefano Zampini /* Renumber cells for hybrid grids */ 1136dea2a3c7SStefano Zampini if (hybrid && enable_hybrid) { 1137dea2a3c7SStefano Zampini PetscInt hc1 = 0, hc2 = 0, *hybridCells1 = NULL, *hybridCells2 = NULL; 1138dea2a3c7SStefano Zampini PetscInt cell, tn, *tp; 1139dea2a3c7SStefano Zampini int n1 = 0,n2 = 0; 1140dea2a3c7SStefano Zampini 1141dea2a3c7SStefano Zampini ierr = PetscMalloc1(trueNumCells, &hybridCells1);CHKERRQ(ierr); 1142dea2a3c7SStefano Zampini ierr = PetscMalloc1(trueNumCells, &hybridCells2);CHKERRQ(ierr); 1143dea2a3c7SStefano Zampini for (cell = 0, c = 0; c < numCells; ++c) { 1144dea2a3c7SStefano Zampini if (gmsh_elem[c].dim == dim) { 1145dea2a3c7SStefano Zampini if (!n1) n1 = gmsh_elem[c].cellType; 1146dea2a3c7SStefano Zampini else if (!n2 && n1 != gmsh_elem[c].cellType) n2 = gmsh_elem[c].cellType; 1147dea2a3c7SStefano Zampini 1148dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == n1) hybridCells1[hc1++] = cell; 1149dea2a3c7SStefano Zampini else if (gmsh_elem[c].cellType == n2) hybridCells2[hc2++] = cell; 1150dea2a3c7SStefano Zampini else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle more than 2 cell types"); 1151dea2a3c7SStefano Zampini cell++; 1152dea2a3c7SStefano Zampini } 1153dea2a3c7SStefano Zampini } 1154dea2a3c7SStefano Zampini 1155dea2a3c7SStefano Zampini switch (n1) { 1156dea2a3c7SStefano Zampini case 2: /* triangles */ 1157dea2a3c7SStefano Zampini case 9: 1158dea2a3c7SStefano Zampini switch (n2) { 1159dea2a3c7SStefano Zampini case 0: /* single type mesh */ 1160dea2a3c7SStefano Zampini case 3: /* quads */ 1161dea2a3c7SStefano Zampini case 10: 1162dea2a3c7SStefano Zampini break; 1163dea2a3c7SStefano Zampini default: 1164dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1165dea2a3c7SStefano Zampini } 1166dea2a3c7SStefano Zampini break; 1167dea2a3c7SStefano Zampini case 3: 1168dea2a3c7SStefano Zampini case 10: 1169dea2a3c7SStefano Zampini switch (n2) { 1170dea2a3c7SStefano Zampini case 0: /* single type mesh */ 1171dea2a3c7SStefano Zampini case 2: /* swap since we list simplices first */ 1172dea2a3c7SStefano Zampini case 9: 1173dea2a3c7SStefano Zampini tn = hc1; 1174dea2a3c7SStefano Zampini hc1 = hc2; 1175dea2a3c7SStefano Zampini hc2 = tn; 1176dea2a3c7SStefano Zampini 1177dea2a3c7SStefano Zampini tp = hybridCells1; 1178dea2a3c7SStefano Zampini hybridCells1 = hybridCells2; 1179dea2a3c7SStefano Zampini hybridCells2 = tp; 1180dea2a3c7SStefano Zampini break; 1181dea2a3c7SStefano Zampini default: 1182dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1183dea2a3c7SStefano Zampini } 1184dea2a3c7SStefano Zampini break; 1185dea2a3c7SStefano Zampini case 4: /* tetrahedra */ 1186dea2a3c7SStefano Zampini case 11: 1187dea2a3c7SStefano Zampini switch (n2) { 1188dea2a3c7SStefano Zampini case 0: /* single type mesh */ 1189dea2a3c7SStefano Zampini case 6: /* wedges */ 1190dea2a3c7SStefano Zampini case 13: 1191dea2a3c7SStefano Zampini break; 1192dea2a3c7SStefano Zampini default: 1193dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1194dea2a3c7SStefano Zampini } 1195dea2a3c7SStefano Zampini break; 1196dea2a3c7SStefano Zampini case 6: 1197dea2a3c7SStefano Zampini case 13: 1198dea2a3c7SStefano Zampini switch (n2) { 1199dea2a3c7SStefano Zampini case 0: /* single type mesh */ 1200dea2a3c7SStefano Zampini case 4: /* swap since we list simplices first */ 1201dea2a3c7SStefano Zampini case 11: 1202dea2a3c7SStefano Zampini tn = hc1; 1203dea2a3c7SStefano Zampini hc1 = hc2; 1204dea2a3c7SStefano Zampini hc2 = tn; 1205dea2a3c7SStefano Zampini 1206dea2a3c7SStefano Zampini tp = hybridCells1; 1207dea2a3c7SStefano Zampini hybridCells1 = hybridCells2; 1208dea2a3c7SStefano Zampini hybridCells2 = tp; 1209dea2a3c7SStefano Zampini break; 1210dea2a3c7SStefano Zampini default: 1211dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1212dea2a3c7SStefano Zampini } 1213dea2a3c7SStefano Zampini break; 1214dea2a3c7SStefano Zampini default: 1215dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1216dea2a3c7SStefano Zampini } 1217dea2a3c7SStefano Zampini cMax = hc1; 1218dea2a3c7SStefano Zampini ierr = PetscMalloc1(trueNumCells, &hybridMap);CHKERRQ(ierr); 1219dea2a3c7SStefano Zampini for (cell = 0; cell < hc1; cell++) hybridMap[hybridCells1[cell]] = cell; 1220dea2a3c7SStefano Zampini for (cell = 0; cell < hc2; cell++) hybridMap[hybridCells2[cell]] = cell + hc1; 1221dea2a3c7SStefano Zampini ierr = PetscFree(hybridCells1);CHKERRQ(ierr); 1222dea2a3c7SStefano Zampini ierr = PetscFree(hybridCells2);CHKERRQ(ierr); 1223dea2a3c7SStefano Zampini } 1224dea2a3c7SStefano Zampini 122511c56cb0SLisandro Dalcin } 122611c56cb0SLisandro Dalcin 1227a4bb7517SMichael Lange /* Allocate the cell-vertex mesh */ 1228db397164SMichael Lange ierr = DMPlexSetChart(*dm, 0, trueNumCells+numVertices);CHKERRQ(ierr); 1229a4bb7517SMichael Lange for (cell = 0, c = 0; c < numCells; ++c) { 1230a4bb7517SMichael Lange if (gmsh_elem[c].dim == dim) { 1231dea2a3c7SStefano Zampini ierr = DMPlexSetConeSize(*dm, hybridMap ? hybridMap[cell] : cell, gmsh_elem[c].numNodes);CHKERRQ(ierr); 1232a4bb7517SMichael Lange cell++; 1233db397164SMichael Lange } 1234331830f3SMatthew G. Knepley } 1235331830f3SMatthew G. Knepley ierr = DMSetUp(*dm);CHKERRQ(ierr); 1236a4bb7517SMichael Lange /* Add cell-vertex connections */ 1237a4bb7517SMichael Lange for (cell = 0, c = 0; c < numCells; ++c) { 1238a4bb7517SMichael Lange if (gmsh_elem[c].dim == dim) { 123911c56cb0SLisandro Dalcin PetscInt pcone[8], corner; 1240a4bb7517SMichael Lange for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) { 1241dd169d64SMatthew G. Knepley const PetscInt cc = gmsh_elem[c].nodes[corner] - shift; 1242917266a4SLisandro Dalcin pcone[corner] = (periodicMap ? periodicMap[cc] : cc) + trueNumCells; 1243db397164SMichael Lange } 124497ed6be6Ssarens if (dim == 3) { 124597ed6be6Ssarens /* Tetrahedra are inverted */ 1246dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 4) { 124797ed6be6Ssarens PetscInt tmp = pcone[0]; 124897ed6be6Ssarens pcone[0] = pcone[1]; 124997ed6be6Ssarens pcone[1] = tmp; 125097ed6be6Ssarens } 125197ed6be6Ssarens /* Hexahedra are inverted */ 1252dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 5) { 125397ed6be6Ssarens PetscInt tmp = pcone[1]; 125497ed6be6Ssarens pcone[1] = pcone[3]; 125597ed6be6Ssarens pcone[3] = tmp; 125697ed6be6Ssarens } 1257dea2a3c7SStefano Zampini /* Prisms are inverted */ 1258dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 6) { 1259dea2a3c7SStefano Zampini PetscInt tmp; 1260dea2a3c7SStefano Zampini 1261dea2a3c7SStefano Zampini tmp = pcone[1]; 1262dea2a3c7SStefano Zampini pcone[1] = pcone[2]; 1263dea2a3c7SStefano Zampini pcone[2] = tmp; 1264dea2a3c7SStefano Zampini tmp = pcone[4]; 1265dea2a3c7SStefano Zampini pcone[4] = pcone[5]; 1266dea2a3c7SStefano Zampini pcone[5] = tmp; 126797ed6be6Ssarens } 1268dea2a3c7SStefano Zampini } else if (dim == 2 && hybridMap && hybridMap[cell] >= cMax) { /* hybrid cells */ 1269dea2a3c7SStefano Zampini /* quads are input to PLEX as prisms */ 1270dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 3) { 1271dea2a3c7SStefano Zampini PetscInt tmp = pcone[2]; 1272dea2a3c7SStefano Zampini pcone[2] = pcone[3]; 1273dea2a3c7SStefano Zampini pcone[3] = tmp; 1274dea2a3c7SStefano Zampini } 1275dea2a3c7SStefano Zampini } 1276dea2a3c7SStefano Zampini ierr = DMPlexSetCone(*dm, hybridMap ? hybridMap[cell] : cell, pcone);CHKERRQ(ierr); 1277a4bb7517SMichael Lange cell++; 1278331830f3SMatthew G. Knepley } 1279a4bb7517SMichael Lange } 12806228fc9fSJed Brown ierr = MPI_Bcast(&dim, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 1281c73cfb54SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 1282dea2a3c7SStefano Zampini ierr = DMPlexSetHybridBounds(*dm, cMax, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 1283331830f3SMatthew G. Knepley ierr = DMPlexSymmetrize(*dm);CHKERRQ(ierr); 1284331830f3SMatthew G. Knepley ierr = DMPlexStratify(*dm);CHKERRQ(ierr); 1285331830f3SMatthew G. Knepley if (interpolate) { 12865fd9971aSMatthew G. Knepley DM idm; 1287331830f3SMatthew G. Knepley 1288331830f3SMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 1289331830f3SMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 1290331830f3SMatthew G. Knepley *dm = idm; 1291331830f3SMatthew G. Knepley } 1292917266a4SLisandro Dalcin 1293f6c8a31fSLisandro Dalcin if (usemarker && !interpolate && dim > 1) SETERRQ(comm,PETSC_ERR_SUP,"Cannot create marker label without interpolation"); 1294917266a4SLisandro Dalcin if (!rank && usemarker) { 1295d3f73514SStefano Zampini PetscInt f, fStart, fEnd; 1296d3f73514SStefano Zampini 1297d3f73514SStefano Zampini ierr = DMCreateLabel(*dm, "marker");CHKERRQ(ierr); 1298d3f73514SStefano Zampini ierr = DMPlexGetHeightStratum(*dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1299d3f73514SStefano Zampini for (f = fStart; f < fEnd; ++f) { 1300d3f73514SStefano Zampini PetscInt suppSize; 1301d3f73514SStefano Zampini 1302d3f73514SStefano Zampini ierr = DMPlexGetSupportSize(*dm, f, &suppSize);CHKERRQ(ierr); 1303d3f73514SStefano Zampini if (suppSize == 1) { 1304d3f73514SStefano Zampini PetscInt *cone = NULL, coneSize, p; 1305d3f73514SStefano Zampini 1306d3f73514SStefano Zampini ierr = DMPlexGetTransitiveClosure(*dm, f, PETSC_TRUE, &coneSize, &cone);CHKERRQ(ierr); 1307d3f73514SStefano Zampini for (p = 0; p < coneSize; p += 2) { 1308d3f73514SStefano Zampini ierr = DMSetLabelValue(*dm, "marker", cone[p], 1);CHKERRQ(ierr); 1309d3f73514SStefano Zampini } 1310d3f73514SStefano Zampini ierr = DMPlexRestoreTransitiveClosure(*dm, f, PETSC_TRUE, &coneSize, &cone);CHKERRQ(ierr); 1311d3f73514SStefano Zampini } 1312d3f73514SStefano Zampini } 1313d3f73514SStefano Zampini } 131416ad7e67SMichael Lange 131516ad7e67SMichael Lange if (!rank) { 131611c56cb0SLisandro Dalcin PetscInt vStart, vEnd; 1317d1a54cefSMatthew G. Knepley 131816ad7e67SMichael Lange ierr = DMPlexGetDepthStratum(*dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 131911c56cb0SLisandro Dalcin for (cell = 0, c = 0; c < numCells; ++c) { 132011c56cb0SLisandro Dalcin 132111c56cb0SLisandro Dalcin /* Create face sets */ 13225964b3dcSLisandro Dalcin if (interpolate && gmsh_elem[c].dim == dim-1) { 132316ad7e67SMichael Lange const PetscInt *join; 132411c56cb0SLisandro Dalcin PetscInt joinSize, pcone[8], corner; 132511c56cb0SLisandro Dalcin /* Find the relevant facet with vertex joins */ 1326a4bb7517SMichael Lange for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) { 1327dd169d64SMatthew G. Knepley const PetscInt cc = gmsh_elem[c].nodes[corner] - shift; 1328917266a4SLisandro Dalcin pcone[corner] = (periodicMap ? periodicMap[cc] : cc) + vStart; 132916ad7e67SMichael Lange } 133011c56cb0SLisandro Dalcin ierr = DMPlexGetFullJoin(*dm, gmsh_elem[c].numNodes, pcone, &joinSize, &join);CHKERRQ(ierr); 1331f10f1c67SMatthew G. Knepley if (joinSize != 1) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not determine Plex facet for GMsh element %d (Plex cell %D)", gmsh_elem[c].id, c); 1332c58f1c22SToby Isaac ierr = DMSetLabelValue(*dm, "Face Sets", join[0], gmsh_elem[c].tags[0]);CHKERRQ(ierr); 1333a4bb7517SMichael Lange ierr = DMPlexRestoreJoin(*dm, gmsh_elem[c].numNodes, (const PetscInt *) pcone, &joinSize, &join);CHKERRQ(ierr); 133416ad7e67SMichael Lange } 13356e1dd89aSLawrence Mitchell 13366e1dd89aSLawrence Mitchell /* Create cell sets */ 13376e1dd89aSLawrence Mitchell if (gmsh_elem[c].dim == dim) { 13386e1dd89aSLawrence Mitchell if (gmsh_elem[c].numTags > 0) { 1339dea2a3c7SStefano Zampini ierr = DMSetLabelValue(*dm, "Cell Sets", hybridMap ? hybridMap[cell] : cell, gmsh_elem[c].tags[0]);CHKERRQ(ierr); 13406e1dd89aSLawrence Mitchell } 1341917266a4SLisandro Dalcin cell++; 13426e1dd89aSLawrence Mitchell } 13430c070f12SSander Arens 13440c070f12SSander Arens /* Create vertex sets */ 13450c070f12SSander Arens if (gmsh_elem[c].dim == 0) { 13460c070f12SSander Arens if (gmsh_elem[c].numTags > 0) { 1347917266a4SLisandro Dalcin const PetscInt cc = gmsh_elem[c].nodes[0] - shift; 134811c56cb0SLisandro Dalcin const PetscInt vid = (periodicMap ? periodicMap[cc] : cc) + vStart; 1349d08df55aSStefano Zampini ierr = DMSetLabelValue(*dm, "Vertex Sets", vid, gmsh_elem[c].tags[0]);CHKERRQ(ierr); 13500c070f12SSander Arens } 13510c070f12SSander Arens } 13520c070f12SSander Arens } 135316ad7e67SMichael Lange } 135416ad7e67SMichael Lange 135511c56cb0SLisandro Dalcin /* Create coordinates */ 1356dea2a3c7SStefano Zampini if (embedDim < 0) embedDim = dim; 1357dea2a3c7SStefano Zampini ierr = DMSetCoordinateDim(*dm, embedDim);CHKERRQ(ierr); 1358979c4b60SMatthew G. Knepley ierr = DMGetCoordinateSection(*dm, &coordSection);CHKERRQ(ierr); 1359331830f3SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 13601d64f2ccSMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, embedDim);CHKERRQ(ierr); 1361f45c9589SStefano Zampini if (periodicMap) { /* we need to localize coordinates on cells */ 1362f45c9589SStefano Zampini ierr = PetscSectionSetChart(coordSection, 0, trueNumCells + numVertices);CHKERRQ(ierr); 1363f45c9589SStefano Zampini } else { 136475b5763bSMichael Lange ierr = PetscSectionSetChart(coordSection, trueNumCells, trueNumCells + numVertices);CHKERRQ(ierr); 1365f45c9589SStefano Zampini } 136675b5763bSMichael Lange for (v = trueNumCells; v < trueNumCells+numVertices; ++v) { 13671d64f2ccSMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, embedDim);CHKERRQ(ierr); 13681d64f2ccSMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, embedDim);CHKERRQ(ierr); 1369331830f3SMatthew G. Knepley } 137011c56cb0SLisandro Dalcin if (periodicMap) { 1371437bdd5bSStefano Zampini ierr = PetscBTCreate(trueNumCells, &periodicC);CHKERRQ(ierr); 1372f45c9589SStefano Zampini for (cell = 0, c = 0; c < numCells; ++c) { 1373f45c9589SStefano Zampini if (gmsh_elem[c].dim == dim) { 1374437bdd5bSStefano Zampini PetscInt corner; 137511c56cb0SLisandro Dalcin PetscBool pc = PETSC_FALSE; 1376437bdd5bSStefano Zampini for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) { 1377917266a4SLisandro Dalcin pc = (PetscBool)(pc || PetscBTLookup(periodicV, gmsh_elem[c].nodes[corner] - shift)); 1378437bdd5bSStefano Zampini } 1379437bdd5bSStefano Zampini if (pc) { 138011c56cb0SLisandro Dalcin PetscInt dof = gmsh_elem[c].numNodes*embedDim; 1381dea2a3c7SStefano Zampini PetscInt ucell = hybridMap ? hybridMap[cell] : cell; 1382dea2a3c7SStefano Zampini ierr = PetscBTSet(periodicC, ucell);CHKERRQ(ierr); 1383dea2a3c7SStefano Zampini ierr = PetscSectionSetDof(coordSection, ucell, dof);CHKERRQ(ierr); 1384dea2a3c7SStefano Zampini ierr = PetscSectionSetFieldDof(coordSection, ucell, 0, dof);CHKERRQ(ierr); 13856fbe17bfSStefano Zampini } 1386f45c9589SStefano Zampini cell++; 1387f45c9589SStefano Zampini } 1388f45c9589SStefano Zampini } 1389f45c9589SStefano Zampini } 1390331830f3SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 1391331830f3SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 13928b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 1393331830f3SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 1394331830f3SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 13951d64f2ccSMatthew G. Knepley ierr = VecSetBlockSize(coordinates, embedDim);CHKERRQ(ierr); 1396331830f3SMatthew G. Knepley ierr = VecSetType(coordinates, VECSTANDARD);CHKERRQ(ierr); 1397331830f3SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 1398f45c9589SStefano Zampini if (periodicMap) { 1399f45c9589SStefano Zampini PetscInt off; 1400f45c9589SStefano Zampini 1401f45c9589SStefano Zampini for (cell = 0, c = 0; c < numCells; ++c) { 1402f45c9589SStefano Zampini PetscInt pcone[8], corner; 1403f45c9589SStefano Zampini if (gmsh_elem[c].dim == dim) { 1404dea2a3c7SStefano Zampini PetscInt ucell = hybridMap ? hybridMap[cell] : cell; 1405dea2a3c7SStefano Zampini if (PetscUnlikely(PetscBTLookup(periodicC, ucell))) { 1406f45c9589SStefano Zampini for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) { 1407917266a4SLisandro Dalcin pcone[corner] = gmsh_elem[c].nodes[corner] - shift; 1408f45c9589SStefano Zampini } 1409f45c9589SStefano Zampini if (dim == 3) { 1410f45c9589SStefano Zampini /* Tetrahedra are inverted */ 1411dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 4) { 1412f45c9589SStefano Zampini PetscInt tmp = pcone[0]; 1413f45c9589SStefano Zampini pcone[0] = pcone[1]; 1414f45c9589SStefano Zampini pcone[1] = tmp; 1415f45c9589SStefano Zampini } 1416f45c9589SStefano Zampini /* Hexahedra are inverted */ 1417dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 5) { 1418f45c9589SStefano Zampini PetscInt tmp = pcone[1]; 1419f45c9589SStefano Zampini pcone[1] = pcone[3]; 1420f45c9589SStefano Zampini pcone[3] = tmp; 1421f45c9589SStefano Zampini } 1422dea2a3c7SStefano Zampini /* Prisms are inverted */ 1423dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 6) { 1424dea2a3c7SStefano Zampini PetscInt tmp; 1425dea2a3c7SStefano Zampini 1426dea2a3c7SStefano Zampini tmp = pcone[1]; 1427dea2a3c7SStefano Zampini pcone[1] = pcone[2]; 1428dea2a3c7SStefano Zampini pcone[2] = tmp; 1429dea2a3c7SStefano Zampini tmp = pcone[4]; 1430dea2a3c7SStefano Zampini pcone[4] = pcone[5]; 1431dea2a3c7SStefano Zampini pcone[5] = tmp; 1432f45c9589SStefano Zampini } 1433dea2a3c7SStefano Zampini } else if (dim == 2 && hybridMap && hybridMap[cell] >= cMax) { /* hybrid cells */ 1434dea2a3c7SStefano Zampini /* quads are input to PLEX as prisms */ 1435dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 3) { 1436dea2a3c7SStefano Zampini PetscInt tmp = pcone[2]; 1437dea2a3c7SStefano Zampini pcone[2] = pcone[3]; 1438dea2a3c7SStefano Zampini pcone[3] = tmp; 1439dea2a3c7SStefano Zampini } 1440dea2a3c7SStefano Zampini } 1441dea2a3c7SStefano Zampini ierr = PetscSectionGetOffset(coordSection, ucell, &off);CHKERRQ(ierr); 1442f45c9589SStefano Zampini for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) { 144311c56cb0SLisandro Dalcin v = pcone[corner]; 1444dd169d64SMatthew G. Knepley for (d = 0; d < embedDim; ++d) { 144511c56cb0SLisandro Dalcin coords[off++] = (PetscReal) coordsIn[v*3+d]; 1446f45c9589SStefano Zampini } 1447f45c9589SStefano Zampini } 14486fbe17bfSStefano Zampini } 1449f45c9589SStefano Zampini cell++; 1450f45c9589SStefano Zampini } 1451f45c9589SStefano Zampini } 1452f45c9589SStefano Zampini for (v = 0; v < numVertices; ++v) { 1453f45c9589SStefano Zampini ierr = PetscSectionGetOffset(coordSection, v + trueNumCells, &off);CHKERRQ(ierr); 1454dd169d64SMatthew G. Knepley for (d = 0; d < embedDim; ++d) { 145511c56cb0SLisandro Dalcin coords[off+d] = (PetscReal) coordsIn[periodicMapI[v]*3+d]; 1456f45c9589SStefano Zampini } 1457f45c9589SStefano Zampini } 1458f45c9589SStefano Zampini } else { 1459331830f3SMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 14601d64f2ccSMatthew G. Knepley for (d = 0; d < embedDim; ++d) { 146111c56cb0SLisandro Dalcin coords[v*embedDim+d] = (PetscReal) coordsIn[v*3+d]; 1462331830f3SMatthew G. Knepley } 1463331830f3SMatthew G. Knepley } 1464331830f3SMatthew G. Knepley } 1465331830f3SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 1466331830f3SMatthew G. Knepley ierr = DMSetCoordinatesLocal(*dm, coordinates);CHKERRQ(ierr); 146711c56cb0SLisandro Dalcin ierr = DMSetPeriodicity(*dm, periodic, NULL, NULL, NULL);CHKERRQ(ierr); 146811c56cb0SLisandro Dalcin 146911c56cb0SLisandro Dalcin ierr = PetscFree(coordsIn);CHKERRQ(ierr); 147011c56cb0SLisandro Dalcin ierr = PetscFree(gmsh_elem);CHKERRQ(ierr); 1471dea2a3c7SStefano Zampini ierr = PetscFree(hybridMap);CHKERRQ(ierr); 1472d08df55aSStefano Zampini ierr = PetscFree(periodicMap);CHKERRQ(ierr); 1473fcd9ca0aSStefano Zampini ierr = PetscFree(periodicMapI);CHKERRQ(ierr); 14746fbe17bfSStefano Zampini ierr = PetscBTDestroy(&periodicV);CHKERRQ(ierr); 14756fbe17bfSStefano Zampini ierr = PetscBTDestroy(&periodicC);CHKERRQ(ierr); 147611c56cb0SLisandro Dalcin ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 147711c56cb0SLisandro Dalcin 14783b3bc66dSMichael Lange ierr = PetscLogEventEnd(DMPLEX_CreateGmsh,*dm,0,0,0);CHKERRQ(ierr); 1479331830f3SMatthew G. Knepley PetscFunctionReturn(0); 1480331830f3SMatthew G. Knepley } 1481