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 5de78e4feSLisandro Dalcin typedef struct { 6698a79b9SLisandro Dalcin PetscViewer viewer; 7698a79b9SLisandro Dalcin int fileFormat; 8698a79b9SLisandro Dalcin int dataSize; 9698a79b9SLisandro Dalcin PetscBool binary; 10698a79b9SLisandro Dalcin PetscBool byteSwap; 11698a79b9SLisandro Dalcin size_t wlen; 12698a79b9SLisandro Dalcin void *wbuf; 13698a79b9SLisandro Dalcin size_t slen; 14698a79b9SLisandro Dalcin void *sbuf; 15698a79b9SLisandro Dalcin } GmshFile; 16de78e4feSLisandro Dalcin 17698a79b9SLisandro Dalcin static PetscErrorCode GmshBufferGet(GmshFile *gmsh, size_t count, size_t eltsize, void *buf) 18de78e4feSLisandro Dalcin { 19de78e4feSLisandro Dalcin size_t size = count * eltsize; 2011c56cb0SLisandro Dalcin PetscErrorCode ierr; 2111c56cb0SLisandro Dalcin 2211c56cb0SLisandro Dalcin PetscFunctionBegin; 23698a79b9SLisandro Dalcin if (gmsh->wlen < size) { 24698a79b9SLisandro Dalcin ierr = PetscFree(gmsh->wbuf);CHKERRQ(ierr); 25698a79b9SLisandro Dalcin ierr = PetscMalloc(size, &gmsh->wbuf);CHKERRQ(ierr); 26698a79b9SLisandro Dalcin gmsh->wlen = size; 27de78e4feSLisandro Dalcin } 28698a79b9SLisandro Dalcin *(void**)buf = size ? gmsh->wbuf : NULL; 29de78e4feSLisandro Dalcin PetscFunctionReturn(0); 30de78e4feSLisandro Dalcin } 31de78e4feSLisandro Dalcin 32698a79b9SLisandro Dalcin static PetscErrorCode GmshBufferSizeGet(GmshFile *gmsh, size_t count, void *buf) 33698a79b9SLisandro Dalcin { 34698a79b9SLisandro Dalcin size_t dataSize = (size_t)gmsh->dataSize; 35698a79b9SLisandro Dalcin size_t size = count * dataSize; 36698a79b9SLisandro Dalcin PetscErrorCode ierr; 37698a79b9SLisandro Dalcin 38698a79b9SLisandro Dalcin PetscFunctionBegin; 39698a79b9SLisandro Dalcin if (gmsh->slen < size) { 40698a79b9SLisandro Dalcin ierr = PetscFree(gmsh->sbuf);CHKERRQ(ierr); 41698a79b9SLisandro Dalcin ierr = PetscMalloc(size, &gmsh->sbuf);CHKERRQ(ierr); 42698a79b9SLisandro Dalcin gmsh->slen = size; 43698a79b9SLisandro Dalcin } 44698a79b9SLisandro Dalcin *(void**)buf = size ? gmsh->sbuf : NULL; 45698a79b9SLisandro Dalcin PetscFunctionReturn(0); 46698a79b9SLisandro Dalcin } 47698a79b9SLisandro Dalcin 48698a79b9SLisandro Dalcin static PetscErrorCode GmshRead(GmshFile *gmsh, void *buf, PetscInt count, PetscDataType dtype) 49de78e4feSLisandro Dalcin { 50de78e4feSLisandro Dalcin PetscErrorCode ierr; 51de78e4feSLisandro Dalcin PetscFunctionBegin; 52698a79b9SLisandro Dalcin ierr = PetscViewerRead(gmsh->viewer, buf, count, NULL, dtype);CHKERRQ(ierr); 53698a79b9SLisandro Dalcin if (gmsh->byteSwap) {ierr = PetscByteSwap(buf, dtype, count);CHKERRQ(ierr);} 54698a79b9SLisandro Dalcin PetscFunctionReturn(0); 55698a79b9SLisandro Dalcin } 56698a79b9SLisandro Dalcin 57698a79b9SLisandro Dalcin static PetscErrorCode GmshReadString(GmshFile *gmsh, char *buf, PetscInt count) 58698a79b9SLisandro Dalcin { 59698a79b9SLisandro Dalcin PetscErrorCode ierr; 60698a79b9SLisandro Dalcin PetscFunctionBegin; 61698a79b9SLisandro Dalcin ierr = PetscViewerRead(gmsh->viewer, buf, count, NULL, PETSC_STRING);CHKERRQ(ierr); 62698a79b9SLisandro Dalcin PetscFunctionReturn(0); 63698a79b9SLisandro Dalcin } 64698a79b9SLisandro Dalcin 65d6689ca9SLisandro Dalcin static PetscErrorCode GmshMatch(PETSC_UNUSED GmshFile *gmsh, const char Section[], char line[PETSC_MAX_PATH_LEN], PetscBool *match) 66d6689ca9SLisandro Dalcin { 67d6689ca9SLisandro Dalcin PetscErrorCode ierr; 68d6689ca9SLisandro Dalcin PetscFunctionBegin; 69d6689ca9SLisandro Dalcin ierr = PetscStrcmp(line, Section, match);CHKERRQ(ierr); 70d6689ca9SLisandro Dalcin PetscFunctionReturn(0); 71d6689ca9SLisandro Dalcin } 72d6689ca9SLisandro Dalcin 73d6689ca9SLisandro Dalcin static PetscErrorCode GmshExpect(GmshFile *gmsh, const char Section[], char line[PETSC_MAX_PATH_LEN]) 74d6689ca9SLisandro Dalcin { 75d6689ca9SLisandro Dalcin PetscBool match; 76d6689ca9SLisandro Dalcin PetscErrorCode ierr; 77d6689ca9SLisandro Dalcin 78d6689ca9SLisandro Dalcin PetscFunctionBegin; 79d6689ca9SLisandro Dalcin ierr = GmshMatch(gmsh, Section, line, &match);CHKERRQ(ierr); 80d6689ca9SLisandro Dalcin if (!match) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file, expecting %s",Section); 81d6689ca9SLisandro Dalcin PetscFunctionReturn(0); 82d6689ca9SLisandro Dalcin } 83d6689ca9SLisandro Dalcin 84d6689ca9SLisandro Dalcin static PetscErrorCode GmshReadSection(GmshFile *gmsh, char line[PETSC_MAX_PATH_LEN]) 85d6689ca9SLisandro Dalcin { 86d6689ca9SLisandro Dalcin PetscBool match; 87d6689ca9SLisandro Dalcin PetscErrorCode ierr; 88d6689ca9SLisandro Dalcin 89d6689ca9SLisandro Dalcin PetscFunctionBegin; 90d6689ca9SLisandro Dalcin while (PETSC_TRUE) { 91d6689ca9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 92d6689ca9SLisandro Dalcin ierr = GmshMatch(gmsh, "$Comments", line, &match);CHKERRQ(ierr); 93d6689ca9SLisandro Dalcin if (!match) break; 94d6689ca9SLisandro Dalcin while (PETSC_TRUE) { 95d6689ca9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 96d6689ca9SLisandro Dalcin ierr = GmshMatch(gmsh, "$EndComments", line, &match);CHKERRQ(ierr); 97d6689ca9SLisandro Dalcin if (match) break; 98d6689ca9SLisandro Dalcin } 99d6689ca9SLisandro Dalcin } 100d6689ca9SLisandro Dalcin PetscFunctionReturn(0); 101d6689ca9SLisandro Dalcin } 102d6689ca9SLisandro Dalcin 103d6689ca9SLisandro Dalcin static PetscErrorCode GmshReadEndSection(GmshFile *gmsh, const char EndSection[], char line[PETSC_MAX_PATH_LEN]) 104d6689ca9SLisandro Dalcin { 105d6689ca9SLisandro Dalcin PetscErrorCode ierr; 106d6689ca9SLisandro Dalcin PetscFunctionBegin; 107d6689ca9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 108d6689ca9SLisandro Dalcin ierr = GmshExpect(gmsh, EndSection, line);CHKERRQ(ierr); 109d6689ca9SLisandro Dalcin PetscFunctionReturn(0); 110d6689ca9SLisandro Dalcin } 111d6689ca9SLisandro Dalcin 112698a79b9SLisandro Dalcin static PetscErrorCode GmshReadSize(GmshFile *gmsh, PetscInt *buf, PetscInt count) 113698a79b9SLisandro Dalcin { 114698a79b9SLisandro Dalcin PetscInt i; 115698a79b9SLisandro Dalcin size_t dataSize = (size_t)gmsh->dataSize; 116698a79b9SLisandro Dalcin PetscErrorCode ierr; 117698a79b9SLisandro Dalcin 118698a79b9SLisandro Dalcin PetscFunctionBegin; 119698a79b9SLisandro Dalcin if (dataSize == sizeof(PetscInt)) { 120698a79b9SLisandro Dalcin ierr = GmshRead(gmsh, buf, count, PETSC_INT);CHKERRQ(ierr); 121698a79b9SLisandro Dalcin } else if (dataSize == sizeof(int)) { 122698a79b9SLisandro Dalcin int *ibuf = NULL; 12389d5b078SSatish Balay ierr = GmshBufferSizeGet(gmsh, count, &ibuf);CHKERRQ(ierr); 124698a79b9SLisandro Dalcin ierr = GmshRead(gmsh, ibuf, count, PETSC_ENUM);CHKERRQ(ierr); 125698a79b9SLisandro Dalcin for (i = 0; i < count; ++i) buf[i] = (PetscInt)ibuf[i]; 126698a79b9SLisandro Dalcin } else if (dataSize == sizeof(long)) { 127698a79b9SLisandro Dalcin long *ibuf = NULL; 12889d5b078SSatish Balay ierr = GmshBufferSizeGet(gmsh, count, &ibuf);CHKERRQ(ierr); 129698a79b9SLisandro Dalcin ierr = GmshRead(gmsh, ibuf, count, PETSC_LONG);CHKERRQ(ierr); 130698a79b9SLisandro Dalcin for (i = 0; i < count; ++i) buf[i] = (PetscInt)ibuf[i]; 131698a79b9SLisandro Dalcin } else if (dataSize == sizeof(PetscInt64)) { 132698a79b9SLisandro Dalcin PetscInt64 *ibuf = NULL; 13389d5b078SSatish Balay ierr = GmshBufferSizeGet(gmsh, count, &ibuf);CHKERRQ(ierr); 134698a79b9SLisandro Dalcin ierr = GmshRead(gmsh, ibuf, count, PETSC_INT64);CHKERRQ(ierr); 135698a79b9SLisandro Dalcin for (i = 0; i < count; ++i) buf[i] = (PetscInt)ibuf[i]; 136698a79b9SLisandro Dalcin } 137698a79b9SLisandro Dalcin PetscFunctionReturn(0); 138698a79b9SLisandro Dalcin } 139698a79b9SLisandro Dalcin 140698a79b9SLisandro Dalcin static PetscErrorCode GmshReadInt(GmshFile *gmsh, int *buf, PetscInt count) 141698a79b9SLisandro Dalcin { 142698a79b9SLisandro Dalcin PetscErrorCode ierr; 143698a79b9SLisandro Dalcin PetscFunctionBegin; 144698a79b9SLisandro Dalcin ierr = GmshRead(gmsh, buf, count, PETSC_ENUM);CHKERRQ(ierr); 145698a79b9SLisandro Dalcin PetscFunctionReturn(0); 146698a79b9SLisandro Dalcin } 147698a79b9SLisandro Dalcin 148698a79b9SLisandro Dalcin static PetscErrorCode GmshReadDouble(GmshFile *gmsh, double *buf, PetscInt count) 149698a79b9SLisandro Dalcin { 150698a79b9SLisandro Dalcin PetscErrorCode ierr; 151698a79b9SLisandro Dalcin PetscFunctionBegin; 152698a79b9SLisandro Dalcin ierr = GmshRead(gmsh, buf, count, PETSC_DOUBLE);CHKERRQ(ierr); 153de78e4feSLisandro Dalcin PetscFunctionReturn(0); 154de78e4feSLisandro Dalcin } 155de78e4feSLisandro Dalcin 156de78e4feSLisandro Dalcin typedef struct { 157de78e4feSLisandro Dalcin PetscInt id; /* Entity number */ 158698a79b9SLisandro Dalcin PetscInt dim; /* Entity dimension */ 159de78e4feSLisandro Dalcin double bbox[6]; /* Bounding box */ 160de78e4feSLisandro Dalcin PetscInt numTags; /* Size of tag array */ 161de78e4feSLisandro Dalcin int tags[4]; /* Tag array */ 162de78e4feSLisandro Dalcin } GmshEntity; 163de78e4feSLisandro Dalcin 164de78e4feSLisandro Dalcin typedef struct { 165730356f6SLisandro Dalcin GmshEntity *entity[4]; 166730356f6SLisandro Dalcin PetscHMapI entityMap[4]; 167730356f6SLisandro Dalcin } GmshEntities; 168730356f6SLisandro Dalcin 169698a79b9SLisandro Dalcin static PetscErrorCode GmshEntitiesCreate(PetscInt count[4], GmshEntities **entities) 170730356f6SLisandro Dalcin { 171730356f6SLisandro Dalcin PetscInt dim; 172730356f6SLisandro Dalcin PetscErrorCode ierr; 173730356f6SLisandro Dalcin 174730356f6SLisandro Dalcin PetscFunctionBegin; 175730356f6SLisandro Dalcin ierr = PetscNew(entities);CHKERRQ(ierr); 176730356f6SLisandro Dalcin for (dim = 0; dim < 4; ++dim) { 177730356f6SLisandro Dalcin ierr = PetscCalloc1(count[dim], &(*entities)->entity[dim]);CHKERRQ(ierr); 178730356f6SLisandro Dalcin ierr = PetscHMapICreate(&(*entities)->entityMap[dim]);CHKERRQ(ierr); 179730356f6SLisandro Dalcin } 180730356f6SLisandro Dalcin PetscFunctionReturn(0); 181730356f6SLisandro Dalcin } 182730356f6SLisandro Dalcin 183730356f6SLisandro Dalcin static PetscErrorCode GmshEntitiesAdd(GmshEntities *entities, PetscInt index, PetscInt dim, PetscInt eid, GmshEntity** entity) 184730356f6SLisandro Dalcin { 185730356f6SLisandro Dalcin PetscErrorCode ierr; 186730356f6SLisandro Dalcin PetscFunctionBegin; 187730356f6SLisandro Dalcin ierr = PetscHMapISet(entities->entityMap[dim], eid, index);CHKERRQ(ierr); 188730356f6SLisandro Dalcin entities->entity[dim][index].dim = dim; 189730356f6SLisandro Dalcin entities->entity[dim][index].id = eid; 190730356f6SLisandro Dalcin if (entity) *entity = &entities->entity[dim][index]; 191730356f6SLisandro Dalcin PetscFunctionReturn(0); 192730356f6SLisandro Dalcin } 193730356f6SLisandro Dalcin 194730356f6SLisandro Dalcin static PetscErrorCode GmshEntitiesGet(GmshEntities *entities, PetscInt dim, PetscInt eid, GmshEntity** entity) 195730356f6SLisandro Dalcin { 196730356f6SLisandro Dalcin PetscInt index; 197730356f6SLisandro Dalcin PetscErrorCode ierr; 198730356f6SLisandro Dalcin 199730356f6SLisandro Dalcin PetscFunctionBegin; 200730356f6SLisandro Dalcin ierr = PetscHMapIGet(entities->entityMap[dim], eid, &index);CHKERRQ(ierr); 201730356f6SLisandro Dalcin *entity = &entities->entity[dim][index]; 202730356f6SLisandro Dalcin PetscFunctionReturn(0); 203730356f6SLisandro Dalcin } 204730356f6SLisandro Dalcin 205730356f6SLisandro Dalcin static PetscErrorCode GmshEntitiesDestroy(GmshEntities **entities) 206730356f6SLisandro Dalcin { 207730356f6SLisandro Dalcin PetscInt dim; 208730356f6SLisandro Dalcin PetscErrorCode ierr; 209730356f6SLisandro Dalcin 210730356f6SLisandro Dalcin PetscFunctionBegin; 211730356f6SLisandro Dalcin if (!*entities) PetscFunctionReturn(0); 212730356f6SLisandro Dalcin for (dim = 0; dim < 4; ++dim) { 213730356f6SLisandro Dalcin ierr = PetscFree((*entities)->entity[dim]);CHKERRQ(ierr); 214730356f6SLisandro Dalcin ierr = PetscHMapIDestroy(&(*entities)->entityMap[dim]);CHKERRQ(ierr); 215730356f6SLisandro Dalcin } 216730356f6SLisandro Dalcin ierr = PetscFree((*entities));CHKERRQ(ierr); 217730356f6SLisandro Dalcin PetscFunctionReturn(0); 218730356f6SLisandro Dalcin } 219730356f6SLisandro Dalcin 220730356f6SLisandro Dalcin typedef struct { 221698a79b9SLisandro Dalcin PetscInt id; /* Entity number */ 222de78e4feSLisandro Dalcin PetscInt dim; /* Entity dimension */ 223de78e4feSLisandro Dalcin PetscInt cellType; /* Cell type */ 224de78e4feSLisandro Dalcin PetscInt numNodes; /* Size of node array */ 225698a79b9SLisandro Dalcin PetscInt nodes[8]; /* Node array */ 226de78e4feSLisandro Dalcin PetscInt numTags; /* Size of tag array */ 227de78e4feSLisandro Dalcin int tags[4]; /* Tag array */ 228de78e4feSLisandro Dalcin } GmshElement; 229de78e4feSLisandro Dalcin 230698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadNodes_v22(GmshFile *gmsh, int shift, PetscInt *numVertices, double **gmsh_nodes) 231de78e4feSLisandro Dalcin { 232698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 233698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 234de78e4feSLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 235698a79b9SLisandro Dalcin int v, num, nid, snum; 236698a79b9SLisandro Dalcin double *coordinates; 237de78e4feSLisandro Dalcin PetscErrorCode ierr; 238de78e4feSLisandro Dalcin 239de78e4feSLisandro Dalcin PetscFunctionBegin; 240de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 241698a79b9SLisandro Dalcin snum = sscanf(line, "%d", &num); 242de78e4feSLisandro Dalcin if (snum != 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 243698a79b9SLisandro Dalcin ierr = PetscMalloc1(num*3, &coordinates);CHKERRQ(ierr); 244698a79b9SLisandro Dalcin *numVertices = num; 245698a79b9SLisandro Dalcin *gmsh_nodes = coordinates; 246698a79b9SLisandro Dalcin for (v = 0; v < num; ++v) { 247698a79b9SLisandro Dalcin double *xyz = coordinates + v*3; 24811c56cb0SLisandro Dalcin ierr = PetscViewerRead(viewer, &nid, 1, NULL, PETSC_ENUM);CHKERRQ(ierr); 24911c56cb0SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&nid, PETSC_ENUM, 1);CHKERRQ(ierr);} 25011c56cb0SLisandro Dalcin if (nid != v+shift) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unexpected node number %d should be %d", nid, v+shift); 25111c56cb0SLisandro Dalcin ierr = PetscViewerRead(viewer, xyz, 3, NULL, PETSC_DOUBLE);CHKERRQ(ierr); 25211c56cb0SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(xyz, PETSC_DOUBLE, 3);CHKERRQ(ierr);} 25311c56cb0SLisandro Dalcin } 25411c56cb0SLisandro Dalcin PetscFunctionReturn(0); 25511c56cb0SLisandro Dalcin } 25611c56cb0SLisandro Dalcin 257de78e4feSLisandro Dalcin /* Gmsh elements can be of any dimension/co-dimension, so we need to traverse the 258de78e4feSLisandro Dalcin file contents multiple times to figure out the true number of cells and facets 259de78e4feSLisandro Dalcin in the given mesh. To make this more efficient we read the file contents only 260de78e4feSLisandro Dalcin once and store them in memory, while determining the true number of cells. */ 261698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadElements_v22(GmshFile* gmsh, PETSC_UNUSED int shift, PetscInt *numCells, GmshElement **gmsh_elems) 26211c56cb0SLisandro Dalcin { 263698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 264698a79b9SLisandro Dalcin PetscBool binary = gmsh->binary; 265698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 266de78e4feSLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 267df032b82SMatthew G. Knepley GmshElement *elements; 268698a79b9SLisandro Dalcin int i, c, p, num, ibuf[1+4+512], snum; 26911c56cb0SLisandro Dalcin int cellType, dim, numNodes, numNodesIgnore, numElem, numTags; 270df032b82SMatthew G. Knepley PetscErrorCode ierr; 271df032b82SMatthew G. Knepley 272df032b82SMatthew G. Knepley PetscFunctionBegin; 273de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr);; 274698a79b9SLisandro Dalcin snum = sscanf(line, "%d", &num); 275de78e4feSLisandro Dalcin if (snum != 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 276698a79b9SLisandro Dalcin ierr = PetscMalloc1(num, &elements);CHKERRQ(ierr); 277698a79b9SLisandro Dalcin *numCells = num; 278698a79b9SLisandro Dalcin *gmsh_elems = elements; 279698a79b9SLisandro Dalcin for (c = 0; c < num;) { 28011c56cb0SLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, 3, NULL, PETSC_ENUM);CHKERRQ(ierr); 28111c56cb0SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, 3);CHKERRQ(ierr);} 282df032b82SMatthew G. Knepley if (binary) { 283df032b82SMatthew G. Knepley cellType = ibuf[0]; 284df032b82SMatthew G. Knepley numElem = ibuf[1]; 285df032b82SMatthew G. Knepley numTags = ibuf[2]; 286df032b82SMatthew G. Knepley } else { 287df032b82SMatthew G. Knepley elements[c].id = ibuf[0]; 288df032b82SMatthew G. Knepley cellType = ibuf[1]; 289df032b82SMatthew G. Knepley numTags = ibuf[2]; 290df032b82SMatthew G. Knepley numElem = 1; 291df032b82SMatthew G. Knepley } 292bf6ba3a3SMatthew G. Knepley /* http://gmsh.info/doc/texinfo/gmsh.html#MSH-ASCII-file-format */ 293bf6ba3a3SMatthew G. Knepley numNodesIgnore = 0; 294df032b82SMatthew G. Knepley switch (cellType) { 295df032b82SMatthew G. Knepley case 1: /* 2-node line */ 296df032b82SMatthew G. Knepley dim = 1; 297df032b82SMatthew G. Knepley numNodes = 2; 298df032b82SMatthew G. Knepley break; 299df032b82SMatthew G. Knepley case 2: /* 3-node triangle */ 300df032b82SMatthew G. Knepley dim = 2; 301df032b82SMatthew G. Knepley numNodes = 3; 302df032b82SMatthew G. Knepley break; 303df032b82SMatthew G. Knepley case 3: /* 4-node quadrangle */ 304df032b82SMatthew G. Knepley dim = 2; 305df032b82SMatthew G. Knepley numNodes = 4; 306df032b82SMatthew G. Knepley break; 307df032b82SMatthew G. Knepley case 4: /* 4-node tetrahedron */ 308df032b82SMatthew G. Knepley dim = 3; 309df032b82SMatthew G. Knepley numNodes = 4; 310df032b82SMatthew G. Knepley break; 311df032b82SMatthew G. Knepley case 5: /* 8-node hexahedron */ 312df032b82SMatthew G. Knepley dim = 3; 313df032b82SMatthew G. Knepley numNodes = 8; 314df032b82SMatthew G. Knepley break; 315dea2a3c7SStefano Zampini case 6: /* 6-node wedge */ 316dea2a3c7SStefano Zampini dim = 3; 317dea2a3c7SStefano Zampini numNodes = 6; 318dea2a3c7SStefano Zampini break; 319bf6ba3a3SMatthew G. Knepley case 8: /* 3-node 2nd order line */ 320bf6ba3a3SMatthew G. Knepley dim = 1; 321bf6ba3a3SMatthew G. Knepley numNodes = 2; 322bf6ba3a3SMatthew G. Knepley numNodesIgnore = 1; 323bf6ba3a3SMatthew G. Knepley break; 324bf6ba3a3SMatthew G. Knepley case 9: /* 6-node 2nd order triangle */ 325bf6ba3a3SMatthew G. Knepley dim = 2; 326bf6ba3a3SMatthew G. Knepley numNodes = 3; 327bf6ba3a3SMatthew G. Knepley numNodesIgnore = 3; 328bf6ba3a3SMatthew G. Knepley break; 329dea2a3c7SStefano Zampini case 13: /* 18-node 2nd wedge */ 330dea2a3c7SStefano Zampini dim = 3; 331dea2a3c7SStefano Zampini numNodes = 6; 332dea2a3c7SStefano Zampini numNodesIgnore = 12; 333dea2a3c7SStefano Zampini break; 334df032b82SMatthew G. Knepley case 15: /* 1-node vertex */ 335df032b82SMatthew G. Knepley dim = 0; 336df032b82SMatthew G. Knepley numNodes = 1; 337df032b82SMatthew G. Knepley break; 338bf6ba3a3SMatthew G. Knepley case 7: /* 5-node pyramid */ 339bf6ba3a3SMatthew G. Knepley case 10: /* 9-node 2nd order quadrangle */ 340bf6ba3a3SMatthew G. Knepley case 11: /* 10-node 2nd order tetrahedron */ 341bf6ba3a3SMatthew G. Knepley case 12: /* 27-node 2nd order hexhedron */ 342bf6ba3a3SMatthew G. Knepley case 14: /* 14-node 2nd order pyramid */ 343df032b82SMatthew G. Knepley default: 344df032b82SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported Gmsh element type %d", cellType); 345df032b82SMatthew G. Knepley } 346df032b82SMatthew G. Knepley if (binary) { 34711c56cb0SLisandro Dalcin const int nint = 1 + numTags + numNodes + numNodesIgnore; 34811c56cb0SLisandro Dalcin /* Loop over element blocks */ 349df032b82SMatthew G. Knepley for (i = 0; i < numElem; ++i, ++c) { 35011c56cb0SLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, nint, NULL, PETSC_ENUM);CHKERRQ(ierr); 35111c56cb0SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, nint);CHKERRQ(ierr);} 352df032b82SMatthew G. Knepley elements[c].dim = dim; 353df032b82SMatthew G. Knepley elements[c].numNodes = numNodes; 354df032b82SMatthew G. Knepley elements[c].numTags = numTags; 355df032b82SMatthew G. Knepley elements[c].id = ibuf[0]; 356dea2a3c7SStefano Zampini elements[c].cellType = cellType; 357df032b82SMatthew G. Knepley for (p = 0; p < numTags; p++) elements[c].tags[p] = ibuf[1 + p]; 358df032b82SMatthew G. Knepley for (p = 0; p < numNodes; p++) elements[c].nodes[p] = ibuf[1 + numTags + p]; 359df032b82SMatthew G. Knepley } 360df032b82SMatthew G. Knepley } else { 361698a79b9SLisandro Dalcin const int nint = numTags + numNodes + numNodesIgnore; 362df032b82SMatthew G. Knepley elements[c].dim = dim; 363df032b82SMatthew G. Knepley elements[c].numNodes = numNodes; 364df032b82SMatthew G. Knepley elements[c].numTags = numTags; 365dea2a3c7SStefano Zampini elements[c].cellType = cellType; 366698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, nint, NULL, PETSC_ENUM);CHKERRQ(ierr); 367698a79b9SLisandro Dalcin for (p = 0; p < numTags; p++) elements[c].tags[p] = ibuf[p]; 368698a79b9SLisandro Dalcin for (p = 0; p < numNodes; p++) elements[c].nodes[p] = ibuf[numTags + p]; 369df032b82SMatthew G. Knepley c++; 370df032b82SMatthew G. Knepley } 371df032b82SMatthew G. Knepley } 372df032b82SMatthew G. Knepley PetscFunctionReturn(0); 373df032b82SMatthew G. Knepley } 3747d282ae0SMichael Lange 375de78e4feSLisandro Dalcin /* 376de78e4feSLisandro Dalcin $Entities 377de78e4feSLisandro Dalcin numPoints(unsigned long) numCurves(unsigned long) 378de78e4feSLisandro Dalcin numSurfaces(unsigned long) numVolumes(unsigned long) 379de78e4feSLisandro Dalcin // points 380de78e4feSLisandro Dalcin tag(int) boxMinX(double) boxMinY(double) boxMinZ(double) 381de78e4feSLisandro Dalcin boxMaxX(double) boxMaxY(double) boxMaxZ(double) 382de78e4feSLisandro Dalcin numPhysicals(unsigned long) phyisicalTag[...](int) 383de78e4feSLisandro Dalcin ... 384de78e4feSLisandro Dalcin // curves 385de78e4feSLisandro Dalcin tag(int) boxMinX(double) boxMinY(double) boxMinZ(double) 386de78e4feSLisandro Dalcin boxMaxX(double) boxMaxY(double) boxMaxZ(double) 387de78e4feSLisandro Dalcin numPhysicals(unsigned long) physicalTag[...](int) 388de78e4feSLisandro Dalcin numBREPVert(unsigned long) tagBREPVert[...](int) 389de78e4feSLisandro Dalcin ... 390de78e4feSLisandro Dalcin // surfaces 391de78e4feSLisandro Dalcin tag(int) boxMinX(double) boxMinY(double) boxMinZ(double) 392de78e4feSLisandro Dalcin boxMaxX(double) boxMaxY(double) boxMaxZ(double) 393de78e4feSLisandro Dalcin numPhysicals(unsigned long) physicalTag[...](int) 394de78e4feSLisandro Dalcin numBREPCurve(unsigned long) tagBREPCurve[...](int) 395de78e4feSLisandro Dalcin ... 396de78e4feSLisandro Dalcin // volumes 397de78e4feSLisandro Dalcin tag(int) boxMinX(double) boxMinY(double) boxMinZ(double) 398de78e4feSLisandro Dalcin boxMaxX(double) boxMaxY(double) boxMaxZ(double) 399de78e4feSLisandro Dalcin numPhysicals(unsigned long) physicalTag[...](int) 400de78e4feSLisandro Dalcin numBREPSurfaces(unsigned long) tagBREPSurfaces[...](int) 401de78e4feSLisandro Dalcin ... 402de78e4feSLisandro Dalcin $EndEntities 403de78e4feSLisandro Dalcin */ 404698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadEntities_v40(GmshFile *gmsh, GmshEntities **entities) 405de78e4feSLisandro Dalcin { 406698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 407698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 408698a79b9SLisandro Dalcin long index, num, lbuf[4]; 409730356f6SLisandro Dalcin int dim, eid, numTags, *ibuf, t; 410698a79b9SLisandro Dalcin PetscInt count[4], i; 411a5ba3d71SLisandro Dalcin GmshEntity *entity = NULL; 412de78e4feSLisandro Dalcin PetscErrorCode ierr; 413de78e4feSLisandro Dalcin 414de78e4feSLisandro Dalcin PetscFunctionBegin; 415698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, lbuf, 4, NULL, PETSC_LONG);CHKERRQ(ierr); 416698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(lbuf, PETSC_LONG, 4);CHKERRQ(ierr);} 417698a79b9SLisandro Dalcin for (i = 0; i < 4; ++i) count[i] = lbuf[i]; 418730356f6SLisandro Dalcin ierr = GmshEntitiesCreate(count, entities);CHKERRQ(ierr); 419de78e4feSLisandro Dalcin for (dim = 0; dim < 4; ++dim) { 420730356f6SLisandro Dalcin for (index = 0; index < count[dim]; ++index) { 421730356f6SLisandro Dalcin ierr = PetscViewerRead(viewer, &eid, 1, NULL, PETSC_ENUM);CHKERRQ(ierr); 422730356f6SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&eid, PETSC_ENUM, 1);CHKERRQ(ierr);} 423730356f6SLisandro Dalcin ierr = GmshEntitiesAdd(*entities, (PetscInt)index, dim, eid, &entity);CHKERRQ(ierr); 424de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, entity->bbox, 6, NULL, PETSC_DOUBLE);CHKERRQ(ierr); 425de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(entity->bbox, PETSC_DOUBLE, 6);CHKERRQ(ierr);} 426de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &num, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 427de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&num, PETSC_LONG, 1);CHKERRQ(ierr);} 428698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, num, sizeof(int), &ibuf);CHKERRQ(ierr); 429de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, num, NULL, PETSC_ENUM);CHKERRQ(ierr); 430730356f6SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, num);CHKERRQ(ierr);} 431de78e4feSLisandro Dalcin entity->numTags = numTags = (int) PetscMin(num, 4); 432de78e4feSLisandro Dalcin for (t = 0; t < numTags; ++t) entity->tags[t] = ibuf[t]; 433de78e4feSLisandro Dalcin if (dim == 0) continue; 434de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &num, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 435de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&num, PETSC_LONG, 1);CHKERRQ(ierr);} 436698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, num, sizeof(int), &ibuf);CHKERRQ(ierr); 437de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, num, NULL, PETSC_ENUM);CHKERRQ(ierr); 438730356f6SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, num);CHKERRQ(ierr);} 439de78e4feSLisandro Dalcin } 440de78e4feSLisandro Dalcin } 441de78e4feSLisandro Dalcin PetscFunctionReturn(0); 442de78e4feSLisandro Dalcin } 443de78e4feSLisandro Dalcin 444de78e4feSLisandro Dalcin /* 445de78e4feSLisandro Dalcin $Nodes 446de78e4feSLisandro Dalcin numEntityBlocks(unsigned long) numNodes(unsigned long) 447de78e4feSLisandro Dalcin tagEntity(int) dimEntity(int) typeNode(int) numNodes(unsigned long) 448de78e4feSLisandro Dalcin tag(int) x(double) y(double) z(double) 449de78e4feSLisandro Dalcin ... 450de78e4feSLisandro Dalcin ... 451de78e4feSLisandro Dalcin $EndNodes 452de78e4feSLisandro Dalcin */ 453698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadNodes_v40(GmshFile *gmsh, int shift, PetscInt *numVertices, double **gmsh_nodes) 454de78e4feSLisandro Dalcin { 455698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 456698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 457de78e4feSLisandro Dalcin long block, node, v, numEntityBlocks, numTotalNodes, numNodes; 458de78e4feSLisandro Dalcin int info[3], nid; 459de78e4feSLisandro Dalcin double *coordinates; 460de78e4feSLisandro Dalcin char *cbuf; 461de78e4feSLisandro Dalcin PetscErrorCode ierr; 462de78e4feSLisandro Dalcin 463de78e4feSLisandro Dalcin PetscFunctionBegin; 464de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numEntityBlocks, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 465de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numEntityBlocks, PETSC_LONG, 1);CHKERRQ(ierr);} 466de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numTotalNodes, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 467de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numTotalNodes, PETSC_LONG, 1);CHKERRQ(ierr);} 468de78e4feSLisandro Dalcin ierr = PetscMalloc1(numTotalNodes*3, &coordinates);CHKERRQ(ierr); 469698a79b9SLisandro Dalcin *numVertices = numTotalNodes; 470de78e4feSLisandro Dalcin *gmsh_nodes = coordinates; 471de78e4feSLisandro Dalcin for (v = 0, block = 0; block < numEntityBlocks; ++block) { 472de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, info, 3, NULL, PETSC_ENUM);CHKERRQ(ierr); 473de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numNodes, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 474de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numNodes, PETSC_LONG, 1);CHKERRQ(ierr);} 475698a79b9SLisandro Dalcin if (gmsh->binary) { 476de78e4feSLisandro Dalcin int nbytes = sizeof(int) + 3*sizeof(double); 477698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numNodes, nbytes, &cbuf);CHKERRQ(ierr); 478de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, cbuf, numNodes*nbytes, NULL, PETSC_CHAR);CHKERRQ(ierr); 479de78e4feSLisandro Dalcin for (node = 0; node < numNodes; ++node, ++v) { 480de78e4feSLisandro Dalcin char *cnid = cbuf + node*nbytes, *cxyz = cnid + sizeof(int); 481de78e4feSLisandro Dalcin double *xyz = coordinates + v*3; 482de78e4feSLisandro Dalcin #if !defined(PETSC_WORDS_BIGENDIAN) 483de78e4feSLisandro Dalcin ierr = PetscByteSwap(cnid, PETSC_ENUM, 1);CHKERRQ(ierr); 484de78e4feSLisandro Dalcin ierr = PetscByteSwap(cxyz, PETSC_DOUBLE, 3);CHKERRQ(ierr); 485de78e4feSLisandro Dalcin #endif 486de78e4feSLisandro Dalcin ierr = PetscMemcpy(&nid, cnid, sizeof(int));CHKERRQ(ierr); 487de78e4feSLisandro Dalcin ierr = PetscMemcpy(xyz, cxyz, 3*sizeof(double));CHKERRQ(ierr); 488de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&nid, PETSC_ENUM, 1);CHKERRQ(ierr);} 489de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(xyz, PETSC_DOUBLE, 3);CHKERRQ(ierr);} 490de78e4feSLisandro Dalcin if (nid != v+shift) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unexpected node number %d should be %d", nid, v+shift); 491de78e4feSLisandro Dalcin } 492de78e4feSLisandro Dalcin } else { 493de78e4feSLisandro Dalcin for (node = 0; node < numNodes; ++node, ++v) { 494de78e4feSLisandro Dalcin double *xyz = coordinates + v*3; 495de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &nid, 1, NULL, PETSC_ENUM);CHKERRQ(ierr); 496de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&nid, PETSC_ENUM, 1);CHKERRQ(ierr);} 497de78e4feSLisandro Dalcin if (nid != v+shift) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unexpected node number %d should be %d", nid, v+shift); 498de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, xyz, 3, NULL, PETSC_DOUBLE);CHKERRQ(ierr); 499de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(xyz, PETSC_DOUBLE, 3);CHKERRQ(ierr);} 500de78e4feSLisandro Dalcin } 501de78e4feSLisandro Dalcin } 502de78e4feSLisandro Dalcin } 503de78e4feSLisandro Dalcin PetscFunctionReturn(0); 504de78e4feSLisandro Dalcin } 505de78e4feSLisandro Dalcin 506de78e4feSLisandro Dalcin /* 507de78e4feSLisandro Dalcin $Elements 508de78e4feSLisandro Dalcin numEntityBlocks(unsigned long) numElements(unsigned long) 509de78e4feSLisandro Dalcin tagEntity(int) dimEntity(int) typeEle(int) numElements(unsigned long) 510de78e4feSLisandro Dalcin tag(int) numVert[...](int) 511de78e4feSLisandro Dalcin ... 512de78e4feSLisandro Dalcin ... 513de78e4feSLisandro Dalcin $EndElements 514de78e4feSLisandro Dalcin */ 515698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadElements_v40(GmshFile *gmsh, PETSC_UNUSED int shift, GmshEntities *entities, PetscInt *numCells, GmshElement **gmsh_elems) 516de78e4feSLisandro Dalcin { 517698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 518698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 519de78e4feSLisandro Dalcin long c, block, numEntityBlocks, numTotalElements, elem, numElements; 520de78e4feSLisandro Dalcin int p, info[3], *ibuf = NULL; 521de78e4feSLisandro Dalcin int eid, dim, numTags, *tags, cellType, numNodes; 522a5ba3d71SLisandro Dalcin GmshEntity *entity = NULL; 523de78e4feSLisandro Dalcin GmshElement *elements; 524de78e4feSLisandro Dalcin PetscErrorCode ierr; 525de78e4feSLisandro Dalcin 526de78e4feSLisandro Dalcin PetscFunctionBegin; 527de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numEntityBlocks, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 528de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numEntityBlocks, PETSC_LONG, 1);CHKERRQ(ierr);} 529de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numTotalElements, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 530de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numTotalElements, PETSC_LONG, 1);CHKERRQ(ierr);} 531de78e4feSLisandro Dalcin ierr = PetscCalloc1(numTotalElements, &elements);CHKERRQ(ierr); 532698a79b9SLisandro Dalcin *numCells = numTotalElements; 533de78e4feSLisandro Dalcin *gmsh_elems = elements; 534de78e4feSLisandro Dalcin for (c = 0, block = 0; block < numEntityBlocks; ++block) { 535de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, info, 3, NULL, PETSC_ENUM);CHKERRQ(ierr); 536de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(info, PETSC_ENUM, 3);CHKERRQ(ierr);} 537de78e4feSLisandro Dalcin eid = info[0]; dim = info[1]; cellType = info[2]; 538730356f6SLisandro Dalcin ierr = GmshEntitiesGet(entities, dim, eid, &entity);CHKERRQ(ierr); 539730356f6SLisandro Dalcin numTags = entity->numTags; 540730356f6SLisandro Dalcin tags = entity->tags; 541de78e4feSLisandro Dalcin switch (cellType) { 542de78e4feSLisandro Dalcin case 1: /* 2-node line */ 543de78e4feSLisandro Dalcin numNodes = 2; 544de78e4feSLisandro Dalcin break; 545de78e4feSLisandro Dalcin case 2: /* 3-node triangle */ 546698a79b9SLisandro Dalcin numNodes = 3; 547698a79b9SLisandro Dalcin break; 548de78e4feSLisandro Dalcin case 3: /* 4-node quadrangle */ 549de78e4feSLisandro Dalcin numNodes = 4; 550de78e4feSLisandro Dalcin break; 551de78e4feSLisandro Dalcin case 4: /* 4-node tetrahedron */ 552de78e4feSLisandro Dalcin numNodes = 4; 553de78e4feSLisandro Dalcin break; 554de78e4feSLisandro Dalcin case 5: /* 8-node hexahedron */ 555de78e4feSLisandro Dalcin numNodes = 8; 556de78e4feSLisandro Dalcin break; 557de78e4feSLisandro Dalcin case 6: /* 6-node wedge */ 558de78e4feSLisandro Dalcin numNodes = 6; 559de78e4feSLisandro Dalcin break; 560de78e4feSLisandro Dalcin case 15: /* 1-node vertex */ 561de78e4feSLisandro Dalcin numNodes = 1; 562de78e4feSLisandro Dalcin break; 563de78e4feSLisandro Dalcin default: 564de78e4feSLisandro Dalcin SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported Gmsh element type %d", cellType); 565de78e4feSLisandro Dalcin } 566de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numElements, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 567de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numElements, PETSC_LONG, 1);CHKERRQ(ierr);} 568698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, (1+numNodes)*numElements, sizeof(int), &ibuf);CHKERRQ(ierr); 569de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, (1+numNodes)*numElements, NULL, PETSC_ENUM);CHKERRQ(ierr); 570de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, (1+numNodes)*numElements);CHKERRQ(ierr);} 571de78e4feSLisandro Dalcin for (elem = 0; elem < numElements; ++elem, ++c) { 572de78e4feSLisandro Dalcin int *id = ibuf + elem*(1+numNodes), *nodes = id + 1; 573de78e4feSLisandro Dalcin GmshElement *element = elements + c; 574de78e4feSLisandro Dalcin element->dim = dim; 575de78e4feSLisandro Dalcin element->cellType = cellType; 576de78e4feSLisandro Dalcin element->numNodes = numNodes; 577de78e4feSLisandro Dalcin element->numTags = numTags; 578de78e4feSLisandro Dalcin element->id = id[0]; 579de78e4feSLisandro Dalcin for (p = 0; p < numNodes; p++) element->nodes[p] = nodes[p]; 580de78e4feSLisandro Dalcin for (p = 0; p < numTags; p++) element->tags[p] = tags[p]; 581de78e4feSLisandro Dalcin } 582de78e4feSLisandro Dalcin } 583698a79b9SLisandro Dalcin PetscFunctionReturn(0); 584698a79b9SLisandro Dalcin } 585698a79b9SLisandro Dalcin 586698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadPeriodic_v40(GmshFile *gmsh, int shift, PetscInt slaveMap[], PetscBT bt) 587698a79b9SLisandro Dalcin { 588698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 589698a79b9SLisandro Dalcin int fileFormat = gmsh->fileFormat; 590698a79b9SLisandro Dalcin PetscBool binary = gmsh->binary; 591698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 592698a79b9SLisandro Dalcin int numPeriodic, snum, i; 593698a79b9SLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 594698a79b9SLisandro Dalcin PetscErrorCode ierr; 595698a79b9SLisandro Dalcin 596698a79b9SLisandro Dalcin PetscFunctionBegin; 597698a79b9SLisandro Dalcin if (fileFormat == 22 || !binary) { 598698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 599698a79b9SLisandro Dalcin snum = sscanf(line, "%d", &numPeriodic); 600698a79b9SLisandro Dalcin if (snum != 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 601698a79b9SLisandro Dalcin } else { 602698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, &numPeriodic, 1, NULL, PETSC_ENUM);CHKERRQ(ierr); 603698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numPeriodic, PETSC_ENUM, 1);CHKERRQ(ierr);} 604698a79b9SLisandro Dalcin } 605698a79b9SLisandro Dalcin for (i = 0; i < numPeriodic; i++) { 606698a79b9SLisandro Dalcin int ibuf[3], slaveDim = -1, slaveTag = -1, masterTag = -1, slaveNode, masterNode; 607698a79b9SLisandro Dalcin long j, nNodes; 608698a79b9SLisandro Dalcin double affine[16]; 609698a79b9SLisandro Dalcin 610698a79b9SLisandro Dalcin if (fileFormat == 22 || !binary) { 611698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 3, NULL, PETSC_STRING);CHKERRQ(ierr); 612698a79b9SLisandro Dalcin snum = sscanf(line, "%d %d %d", &slaveDim, &slaveTag, &masterTag); 613698a79b9SLisandro Dalcin if (snum != 3) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 614698a79b9SLisandro Dalcin } else { 615698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, 3, NULL, PETSC_ENUM);CHKERRQ(ierr); 616698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, 3);CHKERRQ(ierr);} 617698a79b9SLisandro Dalcin slaveDim = ibuf[0]; slaveTag = ibuf[1]; masterTag = ibuf[2]; 618698a79b9SLisandro Dalcin } 619698a79b9SLisandro Dalcin (void)slaveDim; (void)slaveTag; (void)masterTag; /* unused */ 620698a79b9SLisandro Dalcin 621698a79b9SLisandro Dalcin if (fileFormat == 22 || !binary) { 622698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 623698a79b9SLisandro Dalcin snum = sscanf(line, "%ld", &nNodes); 624698a79b9SLisandro Dalcin if (snum != 1) { /* discard tranformation and try again */ 625698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, -PETSC_MAX_PATH_LEN, NULL, PETSC_STRING);CHKERRQ(ierr); 626698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 627698a79b9SLisandro Dalcin snum = sscanf(line, "%ld", &nNodes); 628698a79b9SLisandro Dalcin if (snum != 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 629698a79b9SLisandro Dalcin } 630698a79b9SLisandro Dalcin } else { 631698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, &nNodes, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 632698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&nNodes, PETSC_LONG, 1);CHKERRQ(ierr);} 633698a79b9SLisandro Dalcin if (nNodes == -1) { /* discard tranformation and try again */ 634698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, affine, 16, NULL, PETSC_DOUBLE);CHKERRQ(ierr); 635698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, &nNodes, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 636698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&nNodes, PETSC_LONG, 1);CHKERRQ(ierr);} 637698a79b9SLisandro Dalcin } 638698a79b9SLisandro Dalcin } 639698a79b9SLisandro Dalcin 640698a79b9SLisandro Dalcin for (j = 0; j < nNodes; j++) { 641698a79b9SLisandro Dalcin if (fileFormat == 22 || !binary) { 642698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 2, NULL, PETSC_STRING);CHKERRQ(ierr); 643698a79b9SLisandro Dalcin snum = sscanf(line, "%d %d", &slaveNode, &masterNode); 644698a79b9SLisandro Dalcin if (snum != 2) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 645698a79b9SLisandro Dalcin } else { 646698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, 2, NULL, PETSC_ENUM);CHKERRQ(ierr); 647698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, 2);CHKERRQ(ierr);} 648698a79b9SLisandro Dalcin slaveNode = ibuf[0]; masterNode = ibuf[1]; 649698a79b9SLisandro Dalcin } 650698a79b9SLisandro Dalcin slaveMap[slaveNode - shift] = masterNode - shift; 651698a79b9SLisandro Dalcin ierr = PetscBTSet(bt, slaveNode - shift);CHKERRQ(ierr); 652698a79b9SLisandro Dalcin ierr = PetscBTSet(bt, masterNode - shift);CHKERRQ(ierr); 653698a79b9SLisandro Dalcin } 654698a79b9SLisandro Dalcin } 655698a79b9SLisandro Dalcin PetscFunctionReturn(0); 656698a79b9SLisandro Dalcin } 657698a79b9SLisandro Dalcin 658698a79b9SLisandro Dalcin /* 659698a79b9SLisandro Dalcin $Entities 660698a79b9SLisandro Dalcin numPoints(size_t) numCurves(size_t) 661698a79b9SLisandro Dalcin numSurfaces(size_t) numVolumes(size_t) 662698a79b9SLisandro Dalcin pointTag(int) X(double) Y(double) Z(double) 663698a79b9SLisandro Dalcin numPhysicalTags(size_t) physicalTag(int) ... 664698a79b9SLisandro Dalcin ... 665698a79b9SLisandro Dalcin curveTag(int) minX(double) minY(double) minZ(double) 666698a79b9SLisandro Dalcin maxX(double) maxY(double) maxZ(double) 667698a79b9SLisandro Dalcin numPhysicalTags(size_t) physicalTag(int) ... 668698a79b9SLisandro Dalcin numBoundingPoints(size_t) pointTag(int) ... 669698a79b9SLisandro Dalcin ... 670698a79b9SLisandro Dalcin surfaceTag(int) minX(double) minY(double) minZ(double) 671698a79b9SLisandro Dalcin maxX(double) maxY(double) maxZ(double) 672698a79b9SLisandro Dalcin numPhysicalTags(size_t) physicalTag(int) ... 673698a79b9SLisandro Dalcin numBoundingCurves(size_t) curveTag(int) ... 674698a79b9SLisandro Dalcin ... 675698a79b9SLisandro Dalcin volumeTag(int) minX(double) minY(double) minZ(double) 676698a79b9SLisandro Dalcin maxX(double) maxY(double) maxZ(double) 677698a79b9SLisandro Dalcin numPhysicalTags(size_t) physicalTag(int) ... 678698a79b9SLisandro Dalcin numBoundngSurfaces(size_t) surfaceTag(int) ... 679698a79b9SLisandro Dalcin ... 680698a79b9SLisandro Dalcin $EndEntities 681698a79b9SLisandro Dalcin */ 682698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadEntities_v41(GmshFile *gmsh, GmshEntities **entities) 683698a79b9SLisandro Dalcin { 684698a79b9SLisandro Dalcin PetscInt count[4], index, numTags, i; 685698a79b9SLisandro Dalcin int dim, eid, *tags = NULL; 686698a79b9SLisandro Dalcin GmshEntity *entity = NULL; 687698a79b9SLisandro Dalcin PetscErrorCode ierr; 688698a79b9SLisandro Dalcin 689698a79b9SLisandro Dalcin PetscFunctionBegin; 690698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, count, 4);CHKERRQ(ierr); 691698a79b9SLisandro Dalcin ierr = GmshEntitiesCreate(count, entities);CHKERRQ(ierr); 692698a79b9SLisandro Dalcin for (dim = 0; dim < 4; ++dim) { 693698a79b9SLisandro Dalcin for (index = 0; index < count[dim]; ++index) { 694698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, &eid, 1);CHKERRQ(ierr); 695698a79b9SLisandro Dalcin ierr = GmshEntitiesAdd(*entities, (PetscInt)index, dim, eid, &entity);CHKERRQ(ierr); 696698a79b9SLisandro Dalcin ierr = GmshReadDouble(gmsh, entity->bbox, (dim == 0) ? 3 : 6);CHKERRQ(ierr); 697698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numTags, 1);CHKERRQ(ierr); 698698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numTags, sizeof(int), &tags);CHKERRQ(ierr); 699698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, tags, numTags);CHKERRQ(ierr); 700698a79b9SLisandro Dalcin entity->numTags = PetscMin(numTags, 4); 701698a79b9SLisandro Dalcin for (i = 0; i < entity->numTags; ++i) entity->tags[i] = tags[i]; 702698a79b9SLisandro Dalcin if (dim == 0) continue; 703698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numTags, 1);CHKERRQ(ierr); 704698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numTags, sizeof(int), &tags);CHKERRQ(ierr); 705698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, tags, numTags);CHKERRQ(ierr); 706698a79b9SLisandro Dalcin } 707698a79b9SLisandro Dalcin } 708698a79b9SLisandro Dalcin PetscFunctionReturn(0); 709698a79b9SLisandro Dalcin } 710698a79b9SLisandro Dalcin 711698a79b9SLisandro Dalcin /* 712698a79b9SLisandro Dalcin $Nodes 713698a79b9SLisandro Dalcin numEntityBlocks(size_t) numNodes(size_t) 714698a79b9SLisandro Dalcin minNodeTag(size_t) maxNodeTag(size_t) 715698a79b9SLisandro Dalcin entityDim(int) entityTag(int) parametric(int; 0 or 1) numNodesBlock(size_t) 716698a79b9SLisandro Dalcin nodeTag(size_t) 717698a79b9SLisandro Dalcin ... 718698a79b9SLisandro Dalcin x(double) y(double) z(double) 719698a79b9SLisandro Dalcin < u(double; if parametric and entityDim = 1 or entityDim = 2) > 720698a79b9SLisandro Dalcin < v(double; if parametric and entityDim = 2) > 721698a79b9SLisandro Dalcin ... 722698a79b9SLisandro Dalcin ... 723698a79b9SLisandro Dalcin $EndNodes 724698a79b9SLisandro Dalcin */ 725698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadNodes_v41(GmshFile *gmsh, int shift, PetscInt *numVertices, double **gmsh_nodes) 726698a79b9SLisandro Dalcin { 727698a79b9SLisandro Dalcin int info[3]; 728698a79b9SLisandro Dalcin PetscInt sizes[4], numEntityBlocks, numNodes, numNodesBlock = 0, *nodeTag = NULL, block, node, i; 729698a79b9SLisandro Dalcin double *coordinates; 730698a79b9SLisandro Dalcin PetscErrorCode ierr; 731698a79b9SLisandro Dalcin 732698a79b9SLisandro Dalcin PetscFunctionBegin; 733698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, sizes, 4);CHKERRQ(ierr); 734698a79b9SLisandro Dalcin numEntityBlocks = sizes[0]; numNodes = sizes[1]; 735698a79b9SLisandro Dalcin ierr = PetscMalloc1(numNodes*3, &coordinates);CHKERRQ(ierr); 736698a79b9SLisandro Dalcin *numVertices = numNodes; 737698a79b9SLisandro Dalcin *gmsh_nodes = coordinates; 738698a79b9SLisandro Dalcin for (block = 0, node = 0; block < numEntityBlocks; ++block, node += numNodesBlock) { 739698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, info, 3);CHKERRQ(ierr); 740698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numNodesBlock, 1);CHKERRQ(ierr); 741698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numNodesBlock, sizeof(PetscInt), &nodeTag);CHKERRQ(ierr); 742698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, nodeTag, numNodesBlock);CHKERRQ(ierr); 743698a79b9SLisandro 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); 744698a79b9SLisandro Dalcin if (info[2] != 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Parametric coordinates not supported"); 745698a79b9SLisandro Dalcin ierr = GmshReadDouble(gmsh, coordinates+node*3, numNodesBlock*3);CHKERRQ(ierr); 746698a79b9SLisandro Dalcin } 747698a79b9SLisandro Dalcin PetscFunctionReturn(0); 748698a79b9SLisandro Dalcin } 749698a79b9SLisandro Dalcin 750698a79b9SLisandro Dalcin /* 751698a79b9SLisandro Dalcin $Elements 752698a79b9SLisandro Dalcin numEntityBlocks(size_t) numElements(size_t) 753698a79b9SLisandro Dalcin minElementTag(size_t) maxElementTag(size_t) 754698a79b9SLisandro Dalcin entityDim(int) entityTag(int) elementType(int; see below) numElementsBlock(size_t) 755698a79b9SLisandro Dalcin elementTag(size_t) nodeTag(size_t) ... 756698a79b9SLisandro Dalcin ... 757698a79b9SLisandro Dalcin ... 758698a79b9SLisandro Dalcin $EndElements 759698a79b9SLisandro Dalcin */ 760698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadElements_v41(GmshFile *gmsh, PETSC_UNUSED int shift, GmshEntities *entities, PetscInt *numCells, GmshElement **gmsh_elems) 761698a79b9SLisandro Dalcin { 762698a79b9SLisandro Dalcin int info[3], eid, dim, cellType, *tags; 763698a79b9SLisandro Dalcin PetscInt sizes[4], *ibuf = NULL, numEntityBlocks, numElements, numBlockElements, numNodes, numTags, block, elem, c, p; 764698a79b9SLisandro Dalcin GmshEntity *entity = NULL; 765698a79b9SLisandro Dalcin GmshElement *elements; 766698a79b9SLisandro Dalcin PetscErrorCode ierr; 767698a79b9SLisandro Dalcin 768698a79b9SLisandro Dalcin PetscFunctionBegin; 769698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, sizes, 4);CHKERRQ(ierr); 770698a79b9SLisandro Dalcin numEntityBlocks = sizes[0]; numElements = sizes[1]; 771698a79b9SLisandro Dalcin ierr = PetscCalloc1(numElements, &elements);CHKERRQ(ierr); 772698a79b9SLisandro Dalcin *numCells = numElements; 773698a79b9SLisandro Dalcin *gmsh_elems = elements; 774698a79b9SLisandro Dalcin for (c = 0, block = 0; block < numEntityBlocks; ++block) { 775698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, info, 3);CHKERRQ(ierr); 776698a79b9SLisandro Dalcin dim = info[0]; eid = info[1]; cellType = info[2]; 777698a79b9SLisandro Dalcin ierr = GmshEntitiesGet(entities, dim, eid, &entity);CHKERRQ(ierr); 778698a79b9SLisandro Dalcin numTags = entity->numTags; 779698a79b9SLisandro Dalcin tags = entity->tags; 780698a79b9SLisandro Dalcin switch (cellType) { 781698a79b9SLisandro Dalcin case 1: /* 2-node line */ 782698a79b9SLisandro Dalcin numNodes = 2; 783698a79b9SLisandro Dalcin break; 784698a79b9SLisandro Dalcin case 2: /* 3-node triangle */ 785698a79b9SLisandro Dalcin numNodes = 3; 786698a79b9SLisandro Dalcin break; 787698a79b9SLisandro Dalcin case 3: /* 4-node quadrangle */ 788698a79b9SLisandro Dalcin numNodes = 4; 789698a79b9SLisandro Dalcin break; 790698a79b9SLisandro Dalcin case 4: /* 4-node tetrahedron */ 791698a79b9SLisandro Dalcin numNodes = 4; 792698a79b9SLisandro Dalcin break; 793698a79b9SLisandro Dalcin case 5: /* 8-node hexahedron */ 794698a79b9SLisandro Dalcin numNodes = 8; 795698a79b9SLisandro Dalcin break; 796698a79b9SLisandro Dalcin case 6: /* 6-node wedge */ 797698a79b9SLisandro Dalcin numNodes = 6; 798698a79b9SLisandro Dalcin break; 799698a79b9SLisandro Dalcin case 15: /* 1-node vertex */ 800698a79b9SLisandro Dalcin numNodes = 1; 801698a79b9SLisandro Dalcin break; 802698a79b9SLisandro Dalcin default: 803698a79b9SLisandro Dalcin SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported Gmsh element type %d", cellType); 804698a79b9SLisandro Dalcin } 805698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numBlockElements, 1);CHKERRQ(ierr); 806698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, (1+numNodes)*numBlockElements, sizeof(PetscInt), &ibuf);CHKERRQ(ierr); 807698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, ibuf, (1+numNodes)*numBlockElements);CHKERRQ(ierr); 808698a79b9SLisandro Dalcin for (elem = 0; elem < numBlockElements; ++elem, ++c) { 809698a79b9SLisandro Dalcin GmshElement *element = elements + c; 810698a79b9SLisandro Dalcin PetscInt *id = ibuf + elem*(1+numNodes), *nodes = id + 1; 811698a79b9SLisandro Dalcin element->id = id[0]; 812698a79b9SLisandro Dalcin element->dim = dim; 813698a79b9SLisandro Dalcin element->cellType = cellType; 814698a79b9SLisandro Dalcin element->numNodes = numNodes; 815698a79b9SLisandro Dalcin element->numTags = numTags; 816698a79b9SLisandro Dalcin for (p = 0; p < numNodes; p++) element->nodes[p] = nodes[p]; 817698a79b9SLisandro Dalcin for (p = 0; p < numTags; p++) element->tags[p] = tags[p]; 818698a79b9SLisandro Dalcin } 819698a79b9SLisandro Dalcin } 820698a79b9SLisandro Dalcin PetscFunctionReturn(0); 821698a79b9SLisandro Dalcin } 822698a79b9SLisandro Dalcin 823698a79b9SLisandro Dalcin /* 824698a79b9SLisandro Dalcin $Periodic 825698a79b9SLisandro Dalcin numPeriodicLinks(size_t) 826698a79b9SLisandro Dalcin entityDim(int) entityTag(int) entityTagMaster(int) 827698a79b9SLisandro Dalcin numAffine(size_t) value(double) ... 828698a79b9SLisandro Dalcin numCorrespondingNodes(size_t) 829698a79b9SLisandro Dalcin nodeTag(size_t) nodeTagMaster(size_t) 830698a79b9SLisandro Dalcin ... 831698a79b9SLisandro Dalcin ... 832698a79b9SLisandro Dalcin $EndPeriodic 833698a79b9SLisandro Dalcin */ 834698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadPeriodic_v41(GmshFile *gmsh, int shift, PetscInt slaveMap[], PetscBT bt) 835698a79b9SLisandro Dalcin { 836698a79b9SLisandro Dalcin int info[3]; 837698a79b9SLisandro Dalcin PetscInt numPeriodicLinks, numAffine, numCorrespondingNodes, *nodeTags = NULL, link, node; 838698a79b9SLisandro Dalcin double dbuf[16]; 839698a79b9SLisandro Dalcin PetscErrorCode ierr; 840698a79b9SLisandro Dalcin 841698a79b9SLisandro Dalcin PetscFunctionBegin; 842698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numPeriodicLinks, 1);CHKERRQ(ierr); 843698a79b9SLisandro Dalcin for (link = 0; link < numPeriodicLinks; ++link) { 844698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, info, 3);CHKERRQ(ierr); 845698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numAffine, 1);CHKERRQ(ierr); 846698a79b9SLisandro Dalcin ierr = GmshReadDouble(gmsh, dbuf, numAffine);CHKERRQ(ierr); 847698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numCorrespondingNodes, 1);CHKERRQ(ierr); 848698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numCorrespondingNodes, sizeof(PetscInt), &nodeTags);CHKERRQ(ierr); 849698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, nodeTags, numCorrespondingNodes*2);CHKERRQ(ierr); 850698a79b9SLisandro Dalcin for (node = 0; node < numCorrespondingNodes; ++node) { 851698a79b9SLisandro Dalcin PetscInt slaveNode = nodeTags[node*2+0] - shift; 852698a79b9SLisandro Dalcin PetscInt masterNode = nodeTags[node*2+1] - shift; 853698a79b9SLisandro Dalcin slaveMap[slaveNode] = masterNode; 854698a79b9SLisandro Dalcin ierr = PetscBTSet(bt, slaveNode);CHKERRQ(ierr); 855698a79b9SLisandro Dalcin ierr = PetscBTSet(bt, masterNode);CHKERRQ(ierr); 856698a79b9SLisandro Dalcin } 857698a79b9SLisandro Dalcin } 858698a79b9SLisandro Dalcin PetscFunctionReturn(0); 859698a79b9SLisandro Dalcin } 860698a79b9SLisandro Dalcin 861d6689ca9SLisandro Dalcin /* 862d6689ca9SLisandro Dalcin $MeshFormat // same as MSH version 2 863d6689ca9SLisandro Dalcin version(ASCII double; currently 4.1) 864d6689ca9SLisandro Dalcin file-type(ASCII int; 0 for ASCII mode, 1 for binary mode) 865d6689ca9SLisandro Dalcin data-size(ASCII int; sizeof(size_t)) 866d6689ca9SLisandro Dalcin < int with value one; only in binary mode, to detect endianness > 867d6689ca9SLisandro Dalcin $EndMeshFormat 868d6689ca9SLisandro Dalcin */ 869698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadMeshFormat(GmshFile *gmsh) 870698a79b9SLisandro Dalcin { 871698a79b9SLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 872698a79b9SLisandro Dalcin int snum, fileType, fileFormat, dataSize, checkEndian; 873698a79b9SLisandro Dalcin float version; 874698a79b9SLisandro Dalcin PetscErrorCode ierr; 875698a79b9SLisandro Dalcin 876698a79b9SLisandro Dalcin PetscFunctionBegin; 877698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 3);CHKERRQ(ierr); 878698a79b9SLisandro Dalcin snum = sscanf(line, "%f %d %d", &version, &fileType, &dataSize); 879698a79b9SLisandro Dalcin if (snum != 3) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse Gmsh file header: %s", line); 880698a79b9SLisandro 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); 881698a79b9SLisandro Dalcin if ((int)version == 3) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Gmsh file version %3.1f not supported", (double)version); 882698a79b9SLisandro 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); 883698a79b9SLisandro Dalcin if (gmsh->binary && !fileType) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Viewer is binary but Gmsh file is ASCII"); 884698a79b9SLisandro Dalcin if (!gmsh->binary && fileType) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Viewer is ASCII but Gmsh file is binary"); 885698a79b9SLisandro Dalcin fileFormat = (int)(version*10); /* XXX Should use (int)roundf(version*10) ? */ 886698a79b9SLisandro 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); 887698a79b9SLisandro 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); 888698a79b9SLisandro Dalcin gmsh->fileFormat = fileFormat; 889698a79b9SLisandro Dalcin gmsh->dataSize = dataSize; 890698a79b9SLisandro Dalcin gmsh->byteSwap = PETSC_FALSE; 891698a79b9SLisandro Dalcin if (gmsh->binary) { 892698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, &checkEndian, 1);CHKERRQ(ierr); 893698a79b9SLisandro Dalcin if (checkEndian != 1) { 894698a79b9SLisandro Dalcin ierr = PetscByteSwap(&checkEndian, PETSC_ENUM, 1);CHKERRQ(ierr); 895698a79b9SLisandro Dalcin if (checkEndian != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to detect endianness in Gmsh file header: %s", line); 896698a79b9SLisandro Dalcin gmsh->byteSwap = PETSC_TRUE; 897698a79b9SLisandro Dalcin } 898698a79b9SLisandro Dalcin } 899698a79b9SLisandro Dalcin PetscFunctionReturn(0); 900698a79b9SLisandro Dalcin } 901698a79b9SLisandro Dalcin 9021f643af3SLisandro Dalcin /* 9031f643af3SLisandro Dalcin PhysicalNames 9041f643af3SLisandro Dalcin numPhysicalNames(ASCII int) 9051f643af3SLisandro Dalcin dimension(ASCII int) physicalTag(ASCII int) "name"(127 characters max) 9061f643af3SLisandro Dalcin ... 9071f643af3SLisandro Dalcin $EndPhysicalNames 9081f643af3SLisandro Dalcin */ 909698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadPhysicalNames(GmshFile *gmsh) 910698a79b9SLisandro Dalcin { 9111f643af3SLisandro Dalcin char line[PETSC_MAX_PATH_LEN], name[128+2], *p, *q; 9121f643af3SLisandro Dalcin int snum, numRegions, region, dim, tag; 913698a79b9SLisandro Dalcin PetscErrorCode ierr; 914698a79b9SLisandro Dalcin 915698a79b9SLisandro Dalcin PetscFunctionBegin; 916698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 917698a79b9SLisandro Dalcin snum = sscanf(line, "%d", &numRegions); 918698a79b9SLisandro Dalcin if (snum != 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 919698a79b9SLisandro Dalcin for (region = 0; region < numRegions; ++region) { 9201f643af3SLisandro Dalcin ierr = GmshReadString(gmsh, line, 2);CHKERRQ(ierr); 9211f643af3SLisandro Dalcin snum = sscanf(line, "%d %d", &dim, &tag); 9221f643af3SLisandro Dalcin if (snum != 2) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 9231f643af3SLisandro Dalcin ierr = GmshReadString(gmsh, line, -(PetscInt)sizeof(line));CHKERRQ(ierr); 9241f643af3SLisandro Dalcin ierr = PetscStrchr(line, '"', &p);CHKERRQ(ierr); 9251f643af3SLisandro Dalcin if (!p) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 9261f643af3SLisandro Dalcin ierr = PetscStrrchr(line, '"', &q);CHKERRQ(ierr); 9271f643af3SLisandro Dalcin if (q == p) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 9281f643af3SLisandro Dalcin ierr = PetscStrncpy(name, p+1, (size_t)(q-p-1));CHKERRQ(ierr); 929698a79b9SLisandro Dalcin } 930de78e4feSLisandro Dalcin PetscFunctionReturn(0); 931de78e4feSLisandro Dalcin } 932de78e4feSLisandro Dalcin 933d6689ca9SLisandro Dalcin /*@C 934d6689ca9SLisandro Dalcin DMPlexCreateGmshFromFile - Create a DMPlex mesh from a Gmsh file 935d6689ca9SLisandro Dalcin 936d6689ca9SLisandro Dalcin + comm - The MPI communicator 937d6689ca9SLisandro Dalcin . filename - Name of the Gmsh file 938d6689ca9SLisandro Dalcin - interpolate - Create faces and edges in the mesh 939d6689ca9SLisandro Dalcin 940d6689ca9SLisandro Dalcin Output Parameter: 941d6689ca9SLisandro Dalcin . dm - The DM object representing the mesh 942d6689ca9SLisandro Dalcin 943d6689ca9SLisandro Dalcin Level: beginner 944d6689ca9SLisandro Dalcin 945d6689ca9SLisandro Dalcin .seealso: DMPlexCreateFromFile(), DMPlexCreateGmsh(), DMPlexCreate() 946d6689ca9SLisandro Dalcin @*/ 947d6689ca9SLisandro Dalcin PetscErrorCode DMPlexCreateGmshFromFile(MPI_Comm comm, const char filename[], PetscBool interpolate, DM *dm) 948d6689ca9SLisandro Dalcin { 949d6689ca9SLisandro Dalcin PetscViewer viewer; 950d6689ca9SLisandro Dalcin PetscMPIInt rank; 951d6689ca9SLisandro Dalcin int fileType; 952d6689ca9SLisandro Dalcin PetscViewerType vtype; 953d6689ca9SLisandro Dalcin PetscErrorCode ierr; 954d6689ca9SLisandro Dalcin 955d6689ca9SLisandro Dalcin PetscFunctionBegin; 956d6689ca9SLisandro Dalcin ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 957d6689ca9SLisandro Dalcin 958d6689ca9SLisandro Dalcin /* Determine Gmsh file type (ASCII or binary) from file header */ 959d6689ca9SLisandro Dalcin if (!rank) { 960d6689ca9SLisandro Dalcin GmshFile gmsh_, *gmsh = &gmsh_; 961d6689ca9SLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 962d6689ca9SLisandro Dalcin int snum; 963d6689ca9SLisandro Dalcin float version; 964d6689ca9SLisandro Dalcin 965d6689ca9SLisandro Dalcin ierr = PetscMemzero(gmsh,sizeof(GmshFile));CHKERRQ(ierr); 966d6689ca9SLisandro Dalcin ierr = PetscViewerCreate(PETSC_COMM_SELF, &gmsh->viewer);CHKERRQ(ierr); 967d6689ca9SLisandro Dalcin ierr = PetscViewerSetType(gmsh->viewer, PETSCVIEWERASCII);CHKERRQ(ierr); 968d6689ca9SLisandro Dalcin ierr = PetscViewerFileSetMode(gmsh->viewer, FILE_MODE_READ);CHKERRQ(ierr); 969d6689ca9SLisandro Dalcin ierr = PetscViewerFileSetName(gmsh->viewer, filename);CHKERRQ(ierr); 970d6689ca9SLisandro Dalcin /* Read only the first two lines of the Gmsh file */ 971d6689ca9SLisandro Dalcin ierr = GmshReadSection(gmsh, line);CHKERRQ(ierr); 972d6689ca9SLisandro Dalcin ierr = GmshExpect(gmsh, "$MeshFormat", line);CHKERRQ(ierr); 973d6689ca9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 2);CHKERRQ(ierr); 974d6689ca9SLisandro Dalcin snum = sscanf(line, "%f %d", &version, &fileType); 975d6689ca9SLisandro Dalcin if (snum != 2) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse Gmsh file header: %s", line); 976d6689ca9SLisandro 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); 977d6689ca9SLisandro Dalcin if ((int)version == 3) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Gmsh file version %3.1f not supported", (double)version); 978d6689ca9SLisandro 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); 979d6689ca9SLisandro Dalcin ierr = PetscViewerDestroy(&gmsh->viewer);CHKERRQ(ierr); 980d6689ca9SLisandro Dalcin } 981d6689ca9SLisandro Dalcin ierr = MPI_Bcast(&fileType, 1, MPI_INT, 0, comm);CHKERRQ(ierr); 982d6689ca9SLisandro Dalcin vtype = (fileType == 0) ? PETSCVIEWERASCII : PETSCVIEWERBINARY; 983d6689ca9SLisandro Dalcin 984d6689ca9SLisandro Dalcin /* Create appropriate viewer and build plex */ 985d6689ca9SLisandro Dalcin ierr = PetscViewerCreate(comm, &viewer);CHKERRQ(ierr); 986d6689ca9SLisandro Dalcin ierr = PetscViewerSetType(viewer, vtype);CHKERRQ(ierr); 987d6689ca9SLisandro Dalcin ierr = PetscViewerFileSetMode(viewer, FILE_MODE_READ);CHKERRQ(ierr); 988d6689ca9SLisandro Dalcin ierr = PetscViewerFileSetName(viewer, filename);CHKERRQ(ierr); 989d6689ca9SLisandro Dalcin ierr = DMPlexCreateGmsh(comm, viewer, interpolate, dm);CHKERRQ(ierr); 990d6689ca9SLisandro Dalcin ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 991d6689ca9SLisandro Dalcin PetscFunctionReturn(0); 992d6689ca9SLisandro Dalcin } 993d6689ca9SLisandro Dalcin 994331830f3SMatthew G. Knepley /*@ 9957d282ae0SMichael Lange DMPlexCreateGmsh - Create a DMPlex mesh from a Gmsh file viewer 996331830f3SMatthew G. Knepley 997331830f3SMatthew G. Knepley Collective on comm 998331830f3SMatthew G. Knepley 999331830f3SMatthew G. Knepley Input Parameters: 1000331830f3SMatthew G. Knepley + comm - The MPI communicator 1001331830f3SMatthew G. Knepley . viewer - The Viewer associated with a Gmsh file 1002331830f3SMatthew G. Knepley - interpolate - Create faces and edges in the mesh 1003331830f3SMatthew G. Knepley 1004331830f3SMatthew G. Knepley Output Parameter: 1005331830f3SMatthew G. Knepley . dm - The DM object representing the mesh 1006331830f3SMatthew G. Knepley 1007698a79b9SLisandro Dalcin Note: http://gmsh.info/doc/texinfo/gmsh.html#MSH-file-format 1008331830f3SMatthew G. Knepley 1009331830f3SMatthew G. Knepley Level: beginner 1010331830f3SMatthew G. Knepley 1011331830f3SMatthew G. Knepley .keywords: mesh,Gmsh 1012331830f3SMatthew G. Knepley .seealso: DMPLEX, DMCreate() 1013331830f3SMatthew G. Knepley @*/ 1014331830f3SMatthew G. Knepley PetscErrorCode DMPlexCreateGmsh(MPI_Comm comm, PetscViewer viewer, PetscBool interpolate, DM *dm) 1015331830f3SMatthew G. Knepley { 101611c56cb0SLisandro Dalcin PetscViewer parentviewer = NULL; 101711c56cb0SLisandro Dalcin double *coordsIn = NULL; 1018730356f6SLisandro Dalcin GmshEntities *entities = NULL; 10193c67d5adSSatish Balay GmshElement *gmsh_elem = NULL; 1020331830f3SMatthew G. Knepley PetscSection coordSection; 1021331830f3SMatthew G. Knepley Vec coordinates; 10226fbe17bfSStefano Zampini PetscBT periodicV = NULL, periodicC = NULL; 102384572febSToby Isaac PetscScalar *coords; 1024698a79b9SLisandro Dalcin PetscInt dim = 0, embedDim = -1, coordSize, c, v, d, cell, *periodicMap = NULL, *periodicMapI = NULL, *hybridMap = NULL, cMax = PETSC_DETERMINE; 1025698a79b9SLisandro Dalcin PetscInt numVertices = 0, numCells = 0, trueNumCells = 0; 1026698a79b9SLisandro Dalcin int i, shift = 1; 102711c56cb0SLisandro Dalcin PetscMPIInt rank; 1028ef12879bSLisandro Dalcin PetscBool binary, zerobase = PETSC_FALSE, usemarker = PETSC_FALSE; 1029*0db3fc9eSLisandro Dalcin PetscBool enable_hybrid = interpolate, periodic = PETSC_TRUE; 1030331830f3SMatthew G. Knepley PetscErrorCode ierr; 1031331830f3SMatthew G. Knepley 1032331830f3SMatthew G. Knepley PetscFunctionBegin; 1033331830f3SMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 1034ef12879bSLisandro Dalcin ierr = PetscObjectOptionsBegin((PetscObject)viewer);CHKERRQ(ierr); 1035ef12879bSLisandro Dalcin ierr = PetscOptionsHead(PetscOptionsObject,"DMPlex Gmsh options");CHKERRQ(ierr); 1036ef12879bSLisandro Dalcin ierr = PetscOptionsBool("-dm_plex_gmsh_hybrid", "Generate hybrid cell bounds", "DMPlexCreateGmsh", enable_hybrid, &enable_hybrid, NULL);CHKERRQ(ierr); 1037ef12879bSLisandro Dalcin ierr = PetscOptionsBool("-dm_plex_gmsh_periodic","Read Gmsh periodic section", "DMPlexCreateGmsh", periodic, &periodic, NULL);CHKERRQ(ierr); 1038ef12879bSLisandro Dalcin ierr = PetscOptionsBool("-dm_plex_gmsh_use_marker", "Generate marker label", "DMPlexCreateGmsh", usemarker, &usemarker, NULL);CHKERRQ(ierr); 1039ef12879bSLisandro Dalcin ierr = PetscOptionsBool("-dm_plex_gmsh_zero_base", "Read Gmsh file with zero base indices", "DMPlexCreateGmsh", zerobase, &zerobase, NULL);CHKERRQ(ierr); 1040ef12879bSLisandro Dalcin ierr = PetscOptionsInt("-dm_plex_gmsh_spacedim", "Embedding space dimension", "DMPlexCreateGmsh", embedDim, &embedDim, NULL);CHKERRQ(ierr); 1041ef12879bSLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 1042ef12879bSLisandro Dalcin ierr = PetscOptionsEnd();CHKERRQ(ierr); 104311c56cb0SLisandro Dalcin if (zerobase) shift = 0; 104411c56cb0SLisandro Dalcin 1045331830f3SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 1046331830f3SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 10473b3bc66dSMichael Lange ierr = PetscLogEventBegin(DMPLEX_CreateGmsh,*dm,0,0,0);CHKERRQ(ierr); 104811c56cb0SLisandro Dalcin 104911c56cb0SLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &binary);CHKERRQ(ierr); 105011c56cb0SLisandro Dalcin 105111c56cb0SLisandro Dalcin /* Binary viewers read on all ranks, get subviewer to read only in rank 0 */ 10523b46f529SLisandro Dalcin if (binary) { 105311c56cb0SLisandro Dalcin parentviewer = viewer; 105411c56cb0SLisandro Dalcin ierr = PetscViewerGetSubViewer(parentviewer, PETSC_COMM_SELF, &viewer);CHKERRQ(ierr); 105511c56cb0SLisandro Dalcin } 105611c56cb0SLisandro Dalcin 10573b46f529SLisandro Dalcin if (!rank) { 1058698a79b9SLisandro Dalcin GmshFile gmsh_, *gmsh = &gmsh_; 1059698a79b9SLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 1060698a79b9SLisandro Dalcin PetscBool match; 1061331830f3SMatthew G. Knepley 1062698a79b9SLisandro Dalcin ierr = PetscMemzero(gmsh,sizeof(GmshFile));CHKERRQ(ierr); 1063698a79b9SLisandro Dalcin gmsh->viewer = viewer; 1064698a79b9SLisandro Dalcin gmsh->binary = binary; 1065698a79b9SLisandro Dalcin 1066698a79b9SLisandro Dalcin /* Read mesh format */ 1067d6689ca9SLisandro Dalcin ierr = GmshReadSection(gmsh, line);CHKERRQ(ierr); 1068d6689ca9SLisandro Dalcin ierr = GmshExpect(gmsh, "$MeshFormat", line);CHKERRQ(ierr); 1069698a79b9SLisandro Dalcin ierr = DMPlexCreateGmsh_ReadMeshFormat(gmsh);CHKERRQ(ierr); 1070d6689ca9SLisandro Dalcin ierr = GmshReadEndSection(gmsh, "$EndMeshFormat", line);CHKERRQ(ierr); 107111c56cb0SLisandro Dalcin 1072dc0ede3bSMatthew G. Knepley /* OPTIONAL Read physical names */ 1073d6689ca9SLisandro Dalcin ierr = GmshReadSection(gmsh, line);CHKERRQ(ierr); 1074d6689ca9SLisandro Dalcin ierr = GmshMatch(gmsh,"$PhysicalNames", line, &match);CHKERRQ(ierr); 1075dc0ede3bSMatthew G. Knepley if (match) { 1076698a79b9SLisandro Dalcin ierr = DMPlexCreateGmsh_ReadPhysicalNames(gmsh);CHKERRQ(ierr); 1077d6689ca9SLisandro Dalcin ierr = GmshReadEndSection(gmsh, "$EndPhysicalNames", line);CHKERRQ(ierr); 1078698a79b9SLisandro Dalcin /* Initial read for entity section */ 1079d6689ca9SLisandro Dalcin ierr = GmshReadSection(gmsh, line);CHKERRQ(ierr); 1080dc0ede3bSMatthew G. Knepley } 108111c56cb0SLisandro Dalcin 1082de78e4feSLisandro Dalcin /* Read entities */ 1083698a79b9SLisandro Dalcin if (gmsh->fileFormat >= 40) { 1084d6689ca9SLisandro Dalcin ierr = GmshExpect(gmsh, "$Entities", line);CHKERRQ(ierr); 1085698a79b9SLisandro Dalcin switch (gmsh->fileFormat) { 1086698a79b9SLisandro Dalcin case 41: ierr = DMPlexCreateGmsh_ReadEntities_v41(gmsh, &entities);CHKERRQ(ierr); break; 1087698a79b9SLisandro Dalcin default: ierr = DMPlexCreateGmsh_ReadEntities_v40(gmsh, &entities);CHKERRQ(ierr); break; 1088698a79b9SLisandro Dalcin } 1089d6689ca9SLisandro Dalcin ierr = GmshReadEndSection(gmsh, "$EndEntities", line);CHKERRQ(ierr); 1090698a79b9SLisandro Dalcin /* Initial read for nodes section */ 1091d6689ca9SLisandro Dalcin ierr = GmshReadSection(gmsh, line);CHKERRQ(ierr); 1092de78e4feSLisandro Dalcin } 1093de78e4feSLisandro Dalcin 1094698a79b9SLisandro Dalcin /* Read nodes */ 1095d6689ca9SLisandro Dalcin ierr = GmshExpect(gmsh, "$Nodes", line);CHKERRQ(ierr); 1096698a79b9SLisandro Dalcin switch (gmsh->fileFormat) { 1097698a79b9SLisandro Dalcin case 41: ierr = DMPlexCreateGmsh_ReadNodes_v41(gmsh, shift, &numVertices, &coordsIn);CHKERRQ(ierr); break; 1098698a79b9SLisandro Dalcin case 40: ierr = DMPlexCreateGmsh_ReadNodes_v40(gmsh, shift, &numVertices, &coordsIn);CHKERRQ(ierr); break; 1099698a79b9SLisandro Dalcin default: ierr = DMPlexCreateGmsh_ReadNodes_v22(gmsh, shift, &numVertices, &coordsIn);CHKERRQ(ierr); break; 1100de78e4feSLisandro Dalcin } 1101d6689ca9SLisandro Dalcin ierr = GmshReadEndSection(gmsh, "$EndNodes", line);CHKERRQ(ierr); 110211c56cb0SLisandro Dalcin 1103698a79b9SLisandro Dalcin /* Read elements */ 1104d6689ca9SLisandro Dalcin ierr = GmshReadSection(gmsh, line);CHKERRQ(ierr);; 1105d6689ca9SLisandro Dalcin ierr = GmshExpect(gmsh, "$Elements", line);CHKERRQ(ierr); 1106698a79b9SLisandro Dalcin switch (gmsh->fileFormat) { 1107698a79b9SLisandro Dalcin case 41: ierr = DMPlexCreateGmsh_ReadElements_v41(gmsh, shift, entities, &numCells, &gmsh_elem);CHKERRQ(ierr); break; 1108698a79b9SLisandro Dalcin case 40: ierr = DMPlexCreateGmsh_ReadElements_v40(gmsh, shift, entities, &numCells, &gmsh_elem);CHKERRQ(ierr); break; 1109d6689ca9SLisandro Dalcin default: ierr = DMPlexCreateGmsh_ReadElements_v22(gmsh, shift, &numCells, &gmsh_elem);CHKERRQ(ierr); break; 1110de78e4feSLisandro Dalcin } 1111d6689ca9SLisandro Dalcin ierr = GmshReadEndSection(gmsh, "$EndElements", line);CHKERRQ(ierr); 1112de78e4feSLisandro Dalcin 1113698a79b9SLisandro Dalcin /* OPTIONAL Read periodic section */ 1114698a79b9SLisandro Dalcin if (periodic) { 1115ef12879bSLisandro Dalcin ierr = GmshReadSection(gmsh, line);CHKERRQ(ierr); 1116ef12879bSLisandro Dalcin ierr = GmshMatch(gmsh, "$Periodic", line, &periodic);CHKERRQ(ierr); 1117ef12879bSLisandro Dalcin } 1118ef12879bSLisandro Dalcin if (periodic) { 1119698a79b9SLisandro Dalcin PetscInt pVert, *periodicMapT, *aux; 1120de78e4feSLisandro Dalcin 1121698a79b9SLisandro Dalcin ierr = PetscMalloc1(numVertices, &periodicMapT);CHKERRQ(ierr); 1122698a79b9SLisandro Dalcin ierr = PetscBTCreate(numVertices, &periodicV);CHKERRQ(ierr); 1123698a79b9SLisandro Dalcin for (i = 0; i < numVertices; i++) periodicMapT[i] = i; 1124698a79b9SLisandro Dalcin 1125d6689ca9SLisandro Dalcin ierr = GmshExpect(gmsh, "$Periodic", line);CHKERRQ(ierr); 1126698a79b9SLisandro Dalcin switch (gmsh->fileFormat) { 1127698a79b9SLisandro Dalcin case 41: ierr = DMPlexCreateGmsh_ReadPeriodic_v41(gmsh, shift, periodicMapT, periodicV);CHKERRQ(ierr); break; 1128698a79b9SLisandro Dalcin default: ierr = DMPlexCreateGmsh_ReadPeriodic_v40(gmsh, shift, periodicMapT, periodicV);CHKERRQ(ierr); break; 1129698a79b9SLisandro Dalcin } 1130d6689ca9SLisandro Dalcin ierr = GmshReadEndSection(gmsh, "$EndPeriodic", line);CHKERRQ(ierr); 1131698a79b9SLisandro Dalcin 1132698a79b9SLisandro Dalcin /* we may have slaves of slaves */ 1133698a79b9SLisandro Dalcin for (i = 0; i < numVertices; i++) { 1134698a79b9SLisandro Dalcin while (periodicMapT[periodicMapT[i]] != periodicMapT[i]) { 1135698a79b9SLisandro Dalcin periodicMapT[i] = periodicMapT[periodicMapT[i]]; 1136698a79b9SLisandro Dalcin } 1137698a79b9SLisandro Dalcin } 1138698a79b9SLisandro Dalcin /* periodicMap : from old to new numbering (periodic vertices excluded) 1139698a79b9SLisandro Dalcin periodicMapI: from new to old numbering */ 1140698a79b9SLisandro Dalcin ierr = PetscMalloc1(numVertices, &periodicMap);CHKERRQ(ierr); 1141698a79b9SLisandro Dalcin ierr = PetscMalloc1(numVertices, &periodicMapI);CHKERRQ(ierr); 1142698a79b9SLisandro Dalcin ierr = PetscMalloc1(numVertices, &aux);CHKERRQ(ierr); 1143698a79b9SLisandro Dalcin for (i = 0, pVert = 0; i < numVertices; i++) { 1144698a79b9SLisandro Dalcin if (periodicMapT[i] != i) { 1145698a79b9SLisandro Dalcin pVert++; 1146698a79b9SLisandro Dalcin } else { 1147698a79b9SLisandro Dalcin aux[i] = i - pVert; 1148698a79b9SLisandro Dalcin periodicMapI[i - pVert] = i; 1149698a79b9SLisandro Dalcin } 1150698a79b9SLisandro Dalcin } 1151698a79b9SLisandro Dalcin for (i = 0 ; i < numVertices; i++) { 1152698a79b9SLisandro Dalcin periodicMap[i] = aux[periodicMapT[i]]; 1153698a79b9SLisandro Dalcin } 1154698a79b9SLisandro Dalcin ierr = PetscFree(periodicMapT);CHKERRQ(ierr); 1155698a79b9SLisandro Dalcin ierr = PetscFree(aux);CHKERRQ(ierr); 1156698a79b9SLisandro Dalcin /* remove periodic vertices */ 1157698a79b9SLisandro Dalcin numVertices = numVertices - pVert; 1158698a79b9SLisandro Dalcin } 1159698a79b9SLisandro Dalcin 1160698a79b9SLisandro Dalcin ierr = GmshEntitiesDestroy(&entities);CHKERRQ(ierr); 1161698a79b9SLisandro Dalcin ierr = PetscFree(gmsh->wbuf);CHKERRQ(ierr); 1162698a79b9SLisandro Dalcin ierr = PetscFree(gmsh->sbuf);CHKERRQ(ierr); 1163698a79b9SLisandro Dalcin } 1164698a79b9SLisandro Dalcin 1165698a79b9SLisandro Dalcin if (parentviewer) { 1166698a79b9SLisandro Dalcin ierr = PetscViewerRestoreSubViewer(parentviewer, PETSC_COMM_SELF, &viewer);CHKERRQ(ierr); 1167698a79b9SLisandro Dalcin } 1168698a79b9SLisandro Dalcin 1169698a79b9SLisandro Dalcin if (!rank) { 1170698a79b9SLisandro Dalcin PetscBool hybrid = PETSC_FALSE; 1171*0db3fc9eSLisandro Dalcin PetscInt cellType = -1; 1172698a79b9SLisandro Dalcin 1173a4bb7517SMichael Lange for (trueNumCells = 0, c = 0; c < numCells; ++c) { 1174*0db3fc9eSLisandro Dalcin if (gmsh_elem[c].dim > dim) {dim = gmsh_elem[c].dim; trueNumCells = 0; hybrid = PETSC_FALSE; cellType = -1;} 1175*0db3fc9eSLisandro Dalcin if (gmsh_elem[c].dim < dim) continue; 1176*0db3fc9eSLisandro Dalcin if (cellType == -1) cellType = gmsh_elem[c].cellType; 1177*0db3fc9eSLisandro Dalcin /* different cell type indicate an hybrid mesh in PLEX */ 1178*0db3fc9eSLisandro Dalcin if (cellType != gmsh_elem[c].cellType) hybrid = PETSC_TRUE; 1179dea2a3c7SStefano Zampini /* wedges always indicate an hybrid mesh in PLEX */ 1180*0db3fc9eSLisandro Dalcin if (cellType == 6 || cellType == 13) hybrid = PETSC_TRUE; 1181*0db3fc9eSLisandro Dalcin trueNumCells++; 1182db397164SMichael Lange } 1183dea2a3c7SStefano Zampini /* Renumber cells for hybrid grids */ 1184dea2a3c7SStefano Zampini if (hybrid && enable_hybrid) { 1185dea2a3c7SStefano Zampini PetscInt hc1 = 0, hc2 = 0, *hybridCells1 = NULL, *hybridCells2 = NULL; 1186dea2a3c7SStefano Zampini PetscInt cell, tn, *tp; 1187dea2a3c7SStefano Zampini int n1 = 0,n2 = 0; 1188dea2a3c7SStefano Zampini 1189dea2a3c7SStefano Zampini ierr = PetscMalloc1(trueNumCells, &hybridCells1);CHKERRQ(ierr); 1190dea2a3c7SStefano Zampini ierr = PetscMalloc1(trueNumCells, &hybridCells2);CHKERRQ(ierr); 1191dea2a3c7SStefano Zampini for (cell = 0, c = 0; c < numCells; ++c) { 1192dea2a3c7SStefano Zampini if (gmsh_elem[c].dim == dim) { 1193dea2a3c7SStefano Zampini if (!n1) n1 = gmsh_elem[c].cellType; 1194dea2a3c7SStefano Zampini else if (!n2 && n1 != gmsh_elem[c].cellType) n2 = gmsh_elem[c].cellType; 1195dea2a3c7SStefano Zampini 1196dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == n1) hybridCells1[hc1++] = cell; 1197dea2a3c7SStefano Zampini else if (gmsh_elem[c].cellType == n2) hybridCells2[hc2++] = cell; 1198dea2a3c7SStefano Zampini else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle more than 2 cell types"); 1199dea2a3c7SStefano Zampini cell++; 1200dea2a3c7SStefano Zampini } 1201dea2a3c7SStefano Zampini } 1202dea2a3c7SStefano Zampini 1203dea2a3c7SStefano Zampini switch (n1) { 1204dea2a3c7SStefano Zampini case 2: /* triangles */ 1205dea2a3c7SStefano Zampini case 9: 1206dea2a3c7SStefano Zampini switch (n2) { 1207dea2a3c7SStefano Zampini case 0: /* single type mesh */ 1208dea2a3c7SStefano Zampini case 3: /* quads */ 1209dea2a3c7SStefano Zampini case 10: 1210dea2a3c7SStefano Zampini break; 1211dea2a3c7SStefano Zampini default: 1212dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1213dea2a3c7SStefano Zampini } 1214dea2a3c7SStefano Zampini break; 1215dea2a3c7SStefano Zampini case 3: 1216dea2a3c7SStefano Zampini case 10: 1217dea2a3c7SStefano Zampini switch (n2) { 1218dea2a3c7SStefano Zampini case 0: /* single type mesh */ 1219dea2a3c7SStefano Zampini case 2: /* swap since we list simplices first */ 1220dea2a3c7SStefano Zampini case 9: 1221dea2a3c7SStefano Zampini tn = hc1; 1222dea2a3c7SStefano Zampini hc1 = hc2; 1223dea2a3c7SStefano Zampini hc2 = tn; 1224dea2a3c7SStefano Zampini 1225dea2a3c7SStefano Zampini tp = hybridCells1; 1226dea2a3c7SStefano Zampini hybridCells1 = hybridCells2; 1227dea2a3c7SStefano Zampini hybridCells2 = tp; 1228dea2a3c7SStefano Zampini break; 1229dea2a3c7SStefano Zampini default: 1230dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1231dea2a3c7SStefano Zampini } 1232dea2a3c7SStefano Zampini break; 1233dea2a3c7SStefano Zampini case 4: /* tetrahedra */ 1234dea2a3c7SStefano Zampini case 11: 1235dea2a3c7SStefano Zampini switch (n2) { 1236dea2a3c7SStefano Zampini case 0: /* single type mesh */ 1237dea2a3c7SStefano Zampini case 6: /* wedges */ 1238dea2a3c7SStefano Zampini case 13: 1239dea2a3c7SStefano Zampini break; 1240dea2a3c7SStefano Zampini default: 1241dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1242dea2a3c7SStefano Zampini } 1243dea2a3c7SStefano Zampini break; 1244dea2a3c7SStefano Zampini case 6: 1245dea2a3c7SStefano Zampini case 13: 1246dea2a3c7SStefano Zampini switch (n2) { 1247dea2a3c7SStefano Zampini case 0: /* single type mesh */ 1248dea2a3c7SStefano Zampini case 4: /* swap since we list simplices first */ 1249dea2a3c7SStefano Zampini case 11: 1250dea2a3c7SStefano Zampini tn = hc1; 1251dea2a3c7SStefano Zampini hc1 = hc2; 1252dea2a3c7SStefano Zampini hc2 = tn; 1253dea2a3c7SStefano Zampini 1254dea2a3c7SStefano Zampini tp = hybridCells1; 1255dea2a3c7SStefano Zampini hybridCells1 = hybridCells2; 1256dea2a3c7SStefano Zampini hybridCells2 = tp; 1257dea2a3c7SStefano Zampini break; 1258dea2a3c7SStefano Zampini default: 1259dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1260dea2a3c7SStefano Zampini } 1261dea2a3c7SStefano Zampini break; 1262dea2a3c7SStefano Zampini default: 1263dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1264dea2a3c7SStefano Zampini } 1265dea2a3c7SStefano Zampini cMax = hc1; 1266dea2a3c7SStefano Zampini ierr = PetscMalloc1(trueNumCells, &hybridMap);CHKERRQ(ierr); 1267dea2a3c7SStefano Zampini for (cell = 0; cell < hc1; cell++) hybridMap[hybridCells1[cell]] = cell; 1268dea2a3c7SStefano Zampini for (cell = 0; cell < hc2; cell++) hybridMap[hybridCells2[cell]] = cell + hc1; 1269dea2a3c7SStefano Zampini ierr = PetscFree(hybridCells1);CHKERRQ(ierr); 1270dea2a3c7SStefano Zampini ierr = PetscFree(hybridCells2);CHKERRQ(ierr); 1271dea2a3c7SStefano Zampini } 1272dea2a3c7SStefano Zampini 127311c56cb0SLisandro Dalcin } 127411c56cb0SLisandro Dalcin 1275a4bb7517SMichael Lange /* Allocate the cell-vertex mesh */ 1276db397164SMichael Lange ierr = DMPlexSetChart(*dm, 0, trueNumCells+numVertices);CHKERRQ(ierr); 1277a4bb7517SMichael Lange for (cell = 0, c = 0; c < numCells; ++c) { 1278a4bb7517SMichael Lange if (gmsh_elem[c].dim == dim) { 1279dea2a3c7SStefano Zampini ierr = DMPlexSetConeSize(*dm, hybridMap ? hybridMap[cell] : cell, gmsh_elem[c].numNodes);CHKERRQ(ierr); 1280a4bb7517SMichael Lange cell++; 1281db397164SMichael Lange } 1282331830f3SMatthew G. Knepley } 1283331830f3SMatthew G. Knepley ierr = DMSetUp(*dm);CHKERRQ(ierr); 1284a4bb7517SMichael Lange /* Add cell-vertex connections */ 1285a4bb7517SMichael Lange for (cell = 0, c = 0; c < numCells; ++c) { 1286a4bb7517SMichael Lange if (gmsh_elem[c].dim == dim) { 128711c56cb0SLisandro Dalcin PetscInt pcone[8], corner; 1288a4bb7517SMichael Lange for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) { 1289dd169d64SMatthew G. Knepley const PetscInt cc = gmsh_elem[c].nodes[corner] - shift; 1290917266a4SLisandro Dalcin pcone[corner] = (periodicMap ? periodicMap[cc] : cc) + trueNumCells; 1291db397164SMichael Lange } 129297ed6be6Ssarens if (dim == 3) { 129397ed6be6Ssarens /* Tetrahedra are inverted */ 1294dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 4) { 129597ed6be6Ssarens PetscInt tmp = pcone[0]; 129697ed6be6Ssarens pcone[0] = pcone[1]; 129797ed6be6Ssarens pcone[1] = tmp; 129897ed6be6Ssarens } 129997ed6be6Ssarens /* Hexahedra are inverted */ 1300dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 5) { 130197ed6be6Ssarens PetscInt tmp = pcone[1]; 130297ed6be6Ssarens pcone[1] = pcone[3]; 130397ed6be6Ssarens pcone[3] = tmp; 130497ed6be6Ssarens } 1305dea2a3c7SStefano Zampini /* Prisms are inverted */ 1306dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 6) { 1307dea2a3c7SStefano Zampini PetscInt tmp; 1308dea2a3c7SStefano Zampini 1309dea2a3c7SStefano Zampini tmp = pcone[1]; 1310dea2a3c7SStefano Zampini pcone[1] = pcone[2]; 1311dea2a3c7SStefano Zampini pcone[2] = tmp; 1312dea2a3c7SStefano Zampini tmp = pcone[4]; 1313dea2a3c7SStefano Zampini pcone[4] = pcone[5]; 1314dea2a3c7SStefano Zampini pcone[5] = tmp; 131597ed6be6Ssarens } 1316dea2a3c7SStefano Zampini } else if (dim == 2 && hybridMap && hybridMap[cell] >= cMax) { /* hybrid cells */ 1317dea2a3c7SStefano Zampini /* quads are input to PLEX as prisms */ 1318dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 3) { 1319dea2a3c7SStefano Zampini PetscInt tmp = pcone[2]; 1320dea2a3c7SStefano Zampini pcone[2] = pcone[3]; 1321dea2a3c7SStefano Zampini pcone[3] = tmp; 1322dea2a3c7SStefano Zampini } 1323dea2a3c7SStefano Zampini } 1324dea2a3c7SStefano Zampini ierr = DMPlexSetCone(*dm, hybridMap ? hybridMap[cell] : cell, pcone);CHKERRQ(ierr); 1325a4bb7517SMichael Lange cell++; 1326331830f3SMatthew G. Knepley } 1327a4bb7517SMichael Lange } 13286228fc9fSJed Brown ierr = MPI_Bcast(&dim, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 1329c73cfb54SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 1330dea2a3c7SStefano Zampini ierr = DMPlexSetHybridBounds(*dm, cMax, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 1331331830f3SMatthew G. Knepley ierr = DMPlexSymmetrize(*dm);CHKERRQ(ierr); 1332331830f3SMatthew G. Knepley ierr = DMPlexStratify(*dm);CHKERRQ(ierr); 1333331830f3SMatthew G. Knepley if (interpolate) { 13345fd9971aSMatthew G. Knepley DM idm; 1335331830f3SMatthew G. Knepley 1336331830f3SMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 1337331830f3SMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 1338331830f3SMatthew G. Knepley *dm = idm; 1339331830f3SMatthew G. Knepley } 1340917266a4SLisandro Dalcin 1341f6c8a31fSLisandro Dalcin if (usemarker && !interpolate && dim > 1) SETERRQ(comm,PETSC_ERR_SUP,"Cannot create marker label without interpolation"); 1342917266a4SLisandro Dalcin if (!rank && usemarker) { 1343d3f73514SStefano Zampini PetscInt f, fStart, fEnd; 1344d3f73514SStefano Zampini 1345d3f73514SStefano Zampini ierr = DMCreateLabel(*dm, "marker");CHKERRQ(ierr); 1346d3f73514SStefano Zampini ierr = DMPlexGetHeightStratum(*dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1347d3f73514SStefano Zampini for (f = fStart; f < fEnd; ++f) { 1348d3f73514SStefano Zampini PetscInt suppSize; 1349d3f73514SStefano Zampini 1350d3f73514SStefano Zampini ierr = DMPlexGetSupportSize(*dm, f, &suppSize);CHKERRQ(ierr); 1351d3f73514SStefano Zampini if (suppSize == 1) { 1352d3f73514SStefano Zampini PetscInt *cone = NULL, coneSize, p; 1353d3f73514SStefano Zampini 1354d3f73514SStefano Zampini ierr = DMPlexGetTransitiveClosure(*dm, f, PETSC_TRUE, &coneSize, &cone);CHKERRQ(ierr); 1355d3f73514SStefano Zampini for (p = 0; p < coneSize; p += 2) { 1356d3f73514SStefano Zampini ierr = DMSetLabelValue(*dm, "marker", cone[p], 1);CHKERRQ(ierr); 1357d3f73514SStefano Zampini } 1358d3f73514SStefano Zampini ierr = DMPlexRestoreTransitiveClosure(*dm, f, PETSC_TRUE, &coneSize, &cone);CHKERRQ(ierr); 1359d3f73514SStefano Zampini } 1360d3f73514SStefano Zampini } 1361d3f73514SStefano Zampini } 136216ad7e67SMichael Lange 136316ad7e67SMichael Lange if (!rank) { 136411c56cb0SLisandro Dalcin PetscInt vStart, vEnd; 1365d1a54cefSMatthew G. Knepley 136616ad7e67SMichael Lange ierr = DMPlexGetDepthStratum(*dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 136711c56cb0SLisandro Dalcin for (cell = 0, c = 0; c < numCells; ++c) { 136811c56cb0SLisandro Dalcin 136911c56cb0SLisandro Dalcin /* Create face sets */ 13705964b3dcSLisandro Dalcin if (interpolate && gmsh_elem[c].dim == dim-1) { 137116ad7e67SMichael Lange const PetscInt *join; 137211c56cb0SLisandro Dalcin PetscInt joinSize, pcone[8], corner; 137311c56cb0SLisandro Dalcin /* Find the relevant facet with vertex joins */ 1374a4bb7517SMichael Lange for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) { 1375dd169d64SMatthew G. Knepley const PetscInt cc = gmsh_elem[c].nodes[corner] - shift; 1376917266a4SLisandro Dalcin pcone[corner] = (periodicMap ? periodicMap[cc] : cc) + vStart; 137716ad7e67SMichael Lange } 137811c56cb0SLisandro Dalcin ierr = DMPlexGetFullJoin(*dm, gmsh_elem[c].numNodes, pcone, &joinSize, &join);CHKERRQ(ierr); 1379f10f1c67SMatthew 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); 1380c58f1c22SToby Isaac ierr = DMSetLabelValue(*dm, "Face Sets", join[0], gmsh_elem[c].tags[0]);CHKERRQ(ierr); 1381a4bb7517SMichael Lange ierr = DMPlexRestoreJoin(*dm, gmsh_elem[c].numNodes, (const PetscInt *) pcone, &joinSize, &join);CHKERRQ(ierr); 138216ad7e67SMichael Lange } 13836e1dd89aSLawrence Mitchell 13846e1dd89aSLawrence Mitchell /* Create cell sets */ 13856e1dd89aSLawrence Mitchell if (gmsh_elem[c].dim == dim) { 13866e1dd89aSLawrence Mitchell if (gmsh_elem[c].numTags > 0) { 1387dea2a3c7SStefano Zampini ierr = DMSetLabelValue(*dm, "Cell Sets", hybridMap ? hybridMap[cell] : cell, gmsh_elem[c].tags[0]);CHKERRQ(ierr); 13886e1dd89aSLawrence Mitchell } 1389917266a4SLisandro Dalcin cell++; 13906e1dd89aSLawrence Mitchell } 13910c070f12SSander Arens 13920c070f12SSander Arens /* Create vertex sets */ 13930c070f12SSander Arens if (gmsh_elem[c].dim == 0) { 13940c070f12SSander Arens if (gmsh_elem[c].numTags > 0) { 1395917266a4SLisandro Dalcin const PetscInt cc = gmsh_elem[c].nodes[0] - shift; 139611c56cb0SLisandro Dalcin const PetscInt vid = (periodicMap ? periodicMap[cc] : cc) + vStart; 1397d08df55aSStefano Zampini ierr = DMSetLabelValue(*dm, "Vertex Sets", vid, gmsh_elem[c].tags[0]);CHKERRQ(ierr); 13980c070f12SSander Arens } 13990c070f12SSander Arens } 14000c070f12SSander Arens } 140116ad7e67SMichael Lange } 140216ad7e67SMichael Lange 140311c56cb0SLisandro Dalcin /* Create coordinates */ 1404dea2a3c7SStefano Zampini if (embedDim < 0) embedDim = dim; 1405dea2a3c7SStefano Zampini ierr = DMSetCoordinateDim(*dm, embedDim);CHKERRQ(ierr); 1406979c4b60SMatthew G. Knepley ierr = DMGetCoordinateSection(*dm, &coordSection);CHKERRQ(ierr); 1407331830f3SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 14081d64f2ccSMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, embedDim);CHKERRQ(ierr); 1409f45c9589SStefano Zampini if (periodicMap) { /* we need to localize coordinates on cells */ 1410f45c9589SStefano Zampini ierr = PetscSectionSetChart(coordSection, 0, trueNumCells + numVertices);CHKERRQ(ierr); 1411f45c9589SStefano Zampini } else { 141275b5763bSMichael Lange ierr = PetscSectionSetChart(coordSection, trueNumCells, trueNumCells + numVertices);CHKERRQ(ierr); 1413f45c9589SStefano Zampini } 141475b5763bSMichael Lange for (v = trueNumCells; v < trueNumCells+numVertices; ++v) { 14151d64f2ccSMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, embedDim);CHKERRQ(ierr); 14161d64f2ccSMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, embedDim);CHKERRQ(ierr); 1417331830f3SMatthew G. Knepley } 141811c56cb0SLisandro Dalcin if (periodicMap) { 1419437bdd5bSStefano Zampini ierr = PetscBTCreate(trueNumCells, &periodicC);CHKERRQ(ierr); 1420f45c9589SStefano Zampini for (cell = 0, c = 0; c < numCells; ++c) { 1421f45c9589SStefano Zampini if (gmsh_elem[c].dim == dim) { 1422437bdd5bSStefano Zampini PetscInt corner; 142311c56cb0SLisandro Dalcin PetscBool pc = PETSC_FALSE; 1424437bdd5bSStefano Zampini for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) { 1425917266a4SLisandro Dalcin pc = (PetscBool)(pc || PetscBTLookup(periodicV, gmsh_elem[c].nodes[corner] - shift)); 1426437bdd5bSStefano Zampini } 1427437bdd5bSStefano Zampini if (pc) { 142811c56cb0SLisandro Dalcin PetscInt dof = gmsh_elem[c].numNodes*embedDim; 1429dea2a3c7SStefano Zampini PetscInt ucell = hybridMap ? hybridMap[cell] : cell; 1430dea2a3c7SStefano Zampini ierr = PetscBTSet(periodicC, ucell);CHKERRQ(ierr); 1431dea2a3c7SStefano Zampini ierr = PetscSectionSetDof(coordSection, ucell, dof);CHKERRQ(ierr); 1432dea2a3c7SStefano Zampini ierr = PetscSectionSetFieldDof(coordSection, ucell, 0, dof);CHKERRQ(ierr); 14336fbe17bfSStefano Zampini } 1434f45c9589SStefano Zampini cell++; 1435f45c9589SStefano Zampini } 1436f45c9589SStefano Zampini } 1437f45c9589SStefano Zampini } 1438331830f3SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 1439331830f3SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 14408b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 1441331830f3SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 1442331830f3SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 14431d64f2ccSMatthew G. Knepley ierr = VecSetBlockSize(coordinates, embedDim);CHKERRQ(ierr); 1444331830f3SMatthew G. Knepley ierr = VecSetType(coordinates, VECSTANDARD);CHKERRQ(ierr); 1445331830f3SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 1446f45c9589SStefano Zampini if (periodicMap) { 1447f45c9589SStefano Zampini PetscInt off; 1448f45c9589SStefano Zampini 1449f45c9589SStefano Zampini for (cell = 0, c = 0; c < numCells; ++c) { 1450f45c9589SStefano Zampini PetscInt pcone[8], corner; 1451f45c9589SStefano Zampini if (gmsh_elem[c].dim == dim) { 1452dea2a3c7SStefano Zampini PetscInt ucell = hybridMap ? hybridMap[cell] : cell; 1453dea2a3c7SStefano Zampini if (PetscUnlikely(PetscBTLookup(periodicC, ucell))) { 1454f45c9589SStefano Zampini for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) { 1455917266a4SLisandro Dalcin pcone[corner] = gmsh_elem[c].nodes[corner] - shift; 1456f45c9589SStefano Zampini } 1457f45c9589SStefano Zampini if (dim == 3) { 1458f45c9589SStefano Zampini /* Tetrahedra are inverted */ 1459dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 4) { 1460f45c9589SStefano Zampini PetscInt tmp = pcone[0]; 1461f45c9589SStefano Zampini pcone[0] = pcone[1]; 1462f45c9589SStefano Zampini pcone[1] = tmp; 1463f45c9589SStefano Zampini } 1464f45c9589SStefano Zampini /* Hexahedra are inverted */ 1465dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 5) { 1466f45c9589SStefano Zampini PetscInt tmp = pcone[1]; 1467f45c9589SStefano Zampini pcone[1] = pcone[3]; 1468f45c9589SStefano Zampini pcone[3] = tmp; 1469f45c9589SStefano Zampini } 1470dea2a3c7SStefano Zampini /* Prisms are inverted */ 1471dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 6) { 1472dea2a3c7SStefano Zampini PetscInt tmp; 1473dea2a3c7SStefano Zampini 1474dea2a3c7SStefano Zampini tmp = pcone[1]; 1475dea2a3c7SStefano Zampini pcone[1] = pcone[2]; 1476dea2a3c7SStefano Zampini pcone[2] = tmp; 1477dea2a3c7SStefano Zampini tmp = pcone[4]; 1478dea2a3c7SStefano Zampini pcone[4] = pcone[5]; 1479dea2a3c7SStefano Zampini pcone[5] = tmp; 1480f45c9589SStefano Zampini } 1481dea2a3c7SStefano Zampini } else if (dim == 2 && hybridMap && hybridMap[cell] >= cMax) { /* hybrid cells */ 1482dea2a3c7SStefano Zampini /* quads are input to PLEX as prisms */ 1483dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == 3) { 1484dea2a3c7SStefano Zampini PetscInt tmp = pcone[2]; 1485dea2a3c7SStefano Zampini pcone[2] = pcone[3]; 1486dea2a3c7SStefano Zampini pcone[3] = tmp; 1487dea2a3c7SStefano Zampini } 1488dea2a3c7SStefano Zampini } 1489dea2a3c7SStefano Zampini ierr = PetscSectionGetOffset(coordSection, ucell, &off);CHKERRQ(ierr); 1490f45c9589SStefano Zampini for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) { 149111c56cb0SLisandro Dalcin v = pcone[corner]; 1492dd169d64SMatthew G. Knepley for (d = 0; d < embedDim; ++d) { 149311c56cb0SLisandro Dalcin coords[off++] = (PetscReal) coordsIn[v*3+d]; 1494f45c9589SStefano Zampini } 1495f45c9589SStefano Zampini } 14966fbe17bfSStefano Zampini } 1497f45c9589SStefano Zampini cell++; 1498f45c9589SStefano Zampini } 1499f45c9589SStefano Zampini } 1500f45c9589SStefano Zampini for (v = 0; v < numVertices; ++v) { 1501f45c9589SStefano Zampini ierr = PetscSectionGetOffset(coordSection, v + trueNumCells, &off);CHKERRQ(ierr); 1502dd169d64SMatthew G. Knepley for (d = 0; d < embedDim; ++d) { 150311c56cb0SLisandro Dalcin coords[off+d] = (PetscReal) coordsIn[periodicMapI[v]*3+d]; 1504f45c9589SStefano Zampini } 1505f45c9589SStefano Zampini } 1506f45c9589SStefano Zampini } else { 1507331830f3SMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 15081d64f2ccSMatthew G. Knepley for (d = 0; d < embedDim; ++d) { 150911c56cb0SLisandro Dalcin coords[v*embedDim+d] = (PetscReal) coordsIn[v*3+d]; 1510331830f3SMatthew G. Knepley } 1511331830f3SMatthew G. Knepley } 1512331830f3SMatthew G. Knepley } 1513331830f3SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 1514331830f3SMatthew G. Knepley ierr = DMSetCoordinatesLocal(*dm, coordinates);CHKERRQ(ierr); 1515ef12879bSLisandro Dalcin 1516ef12879bSLisandro Dalcin periodic = periodicMap ? PETSC_TRUE : PETSC_FALSE; 1517ef12879bSLisandro Dalcin ierr = MPI_Bcast(&periodic, 1, MPIU_BOOL, 0, comm);CHKERRQ(ierr); 151811c56cb0SLisandro Dalcin ierr = DMSetPeriodicity(*dm, periodic, NULL, NULL, NULL);CHKERRQ(ierr); 151911c56cb0SLisandro Dalcin 152011c56cb0SLisandro Dalcin ierr = PetscFree(coordsIn);CHKERRQ(ierr); 152111c56cb0SLisandro Dalcin ierr = PetscFree(gmsh_elem);CHKERRQ(ierr); 1522dea2a3c7SStefano Zampini ierr = PetscFree(hybridMap);CHKERRQ(ierr); 1523d08df55aSStefano Zampini ierr = PetscFree(periodicMap);CHKERRQ(ierr); 1524fcd9ca0aSStefano Zampini ierr = PetscFree(periodicMapI);CHKERRQ(ierr); 15256fbe17bfSStefano Zampini ierr = PetscBTDestroy(&periodicV);CHKERRQ(ierr); 15266fbe17bfSStefano Zampini ierr = PetscBTDestroy(&periodicC);CHKERRQ(ierr); 152711c56cb0SLisandro Dalcin ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 152811c56cb0SLisandro Dalcin 15293b3bc66dSMichael Lange ierr = PetscLogEventEnd(DMPLEX_CreateGmsh,*dm,0,0,0);CHKERRQ(ierr); 1530331830f3SMatthew G. Knepley PetscFunctionReturn(0); 1531331830f3SMatthew G. Knepley } 1532