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; 273feb237baSPierre Jolivet 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; 329a1e86c74SStefano Zampini case 10: /* 9-node 2nd order quadrangle */ 330a1e86c74SStefano Zampini dim = 2; 331a1e86c74SStefano Zampini numNodes = 4; 332a1e86c74SStefano Zampini numNodesIgnore = 5; 333a1e86c74SStefano Zampini break; 334a1e86c74SStefano Zampini case 11: /* 10-node 2nd order tetrahedron */ 335a1e86c74SStefano Zampini dim = 3; 336a1e86c74SStefano Zampini numNodes = 4; 337a1e86c74SStefano Zampini numNodesIgnore = 6; 338a1e86c74SStefano Zampini break; 339a1e86c74SStefano Zampini case 12: /* 27-node 2nd order hexhedron */ 340a1e86c74SStefano Zampini dim = 3; 341a1e86c74SStefano Zampini numNodes = 8; 342a1e86c74SStefano Zampini numNodesIgnore = 19; 343a1e86c74SStefano Zampini break; 344dea2a3c7SStefano Zampini case 13: /* 18-node 2nd wedge */ 345dea2a3c7SStefano Zampini dim = 3; 346dea2a3c7SStefano Zampini numNodes = 6; 347dea2a3c7SStefano Zampini numNodesIgnore = 12; 348dea2a3c7SStefano Zampini break; 349df032b82SMatthew G. Knepley case 15: /* 1-node vertex */ 350df032b82SMatthew G. Knepley dim = 0; 351df032b82SMatthew G. Knepley numNodes = 1; 352df032b82SMatthew G. Knepley break; 353bf6ba3a3SMatthew G. Knepley case 7: /* 5-node pyramid */ 354bf6ba3a3SMatthew G. Knepley case 14: /* 14-node 2nd order pyramid */ 355df032b82SMatthew G. Knepley default: 356df032b82SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported Gmsh element type %d", cellType); 357df032b82SMatthew G. Knepley } 358df032b82SMatthew G. Knepley if (binary) { 35911c56cb0SLisandro Dalcin const int nint = 1 + numTags + numNodes + numNodesIgnore; 36011c56cb0SLisandro Dalcin /* Loop over element blocks */ 361df032b82SMatthew G. Knepley for (i = 0; i < numElem; ++i, ++c) { 36211c56cb0SLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, nint, NULL, PETSC_ENUM);CHKERRQ(ierr); 36311c56cb0SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, nint);CHKERRQ(ierr);} 364df032b82SMatthew G. Knepley elements[c].dim = dim; 365df032b82SMatthew G. Knepley elements[c].numNodes = numNodes; 366df032b82SMatthew G. Knepley elements[c].numTags = numTags; 367df032b82SMatthew G. Knepley elements[c].id = ibuf[0]; 368dea2a3c7SStefano Zampini elements[c].cellType = cellType; 369df032b82SMatthew G. Knepley for (p = 0; p < numTags; p++) elements[c].tags[p] = ibuf[1 + p]; 370df032b82SMatthew G. Knepley for (p = 0; p < numNodes; p++) elements[c].nodes[p] = ibuf[1 + numTags + p]; 371df032b82SMatthew G. Knepley } 372df032b82SMatthew G. Knepley } else { 373698a79b9SLisandro Dalcin const int nint = numTags + numNodes + numNodesIgnore; 374df032b82SMatthew G. Knepley elements[c].dim = dim; 375df032b82SMatthew G. Knepley elements[c].numNodes = numNodes; 376df032b82SMatthew G. Knepley elements[c].numTags = numTags; 377dea2a3c7SStefano Zampini elements[c].cellType = cellType; 378698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, nint, NULL, PETSC_ENUM);CHKERRQ(ierr); 379698a79b9SLisandro Dalcin for (p = 0; p < numTags; p++) elements[c].tags[p] = ibuf[p]; 380698a79b9SLisandro Dalcin for (p = 0; p < numNodes; p++) elements[c].nodes[p] = ibuf[numTags + p]; 381df032b82SMatthew G. Knepley c++; 382df032b82SMatthew G. Knepley } 383df032b82SMatthew G. Knepley } 384df032b82SMatthew G. Knepley PetscFunctionReturn(0); 385df032b82SMatthew G. Knepley } 3867d282ae0SMichael Lange 387de78e4feSLisandro Dalcin /* 388de78e4feSLisandro Dalcin $Entities 389de78e4feSLisandro Dalcin numPoints(unsigned long) numCurves(unsigned long) 390de78e4feSLisandro Dalcin numSurfaces(unsigned long) numVolumes(unsigned long) 391de78e4feSLisandro Dalcin // points 392de78e4feSLisandro Dalcin tag(int) boxMinX(double) boxMinY(double) boxMinZ(double) 393de78e4feSLisandro Dalcin boxMaxX(double) boxMaxY(double) boxMaxZ(double) 394de78e4feSLisandro Dalcin numPhysicals(unsigned long) phyisicalTag[...](int) 395de78e4feSLisandro Dalcin ... 396de78e4feSLisandro Dalcin // curves 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 numBREPVert(unsigned long) tagBREPVert[...](int) 401de78e4feSLisandro Dalcin ... 402de78e4feSLisandro Dalcin // surfaces 403de78e4feSLisandro Dalcin tag(int) boxMinX(double) boxMinY(double) boxMinZ(double) 404de78e4feSLisandro Dalcin boxMaxX(double) boxMaxY(double) boxMaxZ(double) 405de78e4feSLisandro Dalcin numPhysicals(unsigned long) physicalTag[...](int) 406de78e4feSLisandro Dalcin numBREPCurve(unsigned long) tagBREPCurve[...](int) 407de78e4feSLisandro Dalcin ... 408de78e4feSLisandro Dalcin // volumes 409de78e4feSLisandro Dalcin tag(int) boxMinX(double) boxMinY(double) boxMinZ(double) 410de78e4feSLisandro Dalcin boxMaxX(double) boxMaxY(double) boxMaxZ(double) 411de78e4feSLisandro Dalcin numPhysicals(unsigned long) physicalTag[...](int) 412de78e4feSLisandro Dalcin numBREPSurfaces(unsigned long) tagBREPSurfaces[...](int) 413de78e4feSLisandro Dalcin ... 414de78e4feSLisandro Dalcin $EndEntities 415de78e4feSLisandro Dalcin */ 416698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadEntities_v40(GmshFile *gmsh, GmshEntities **entities) 417de78e4feSLisandro Dalcin { 418698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 419698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 420698a79b9SLisandro Dalcin long index, num, lbuf[4]; 421730356f6SLisandro Dalcin int dim, eid, numTags, *ibuf, t; 422698a79b9SLisandro Dalcin PetscInt count[4], i; 423a5ba3d71SLisandro Dalcin GmshEntity *entity = NULL; 424de78e4feSLisandro Dalcin PetscErrorCode ierr; 425de78e4feSLisandro Dalcin 426de78e4feSLisandro Dalcin PetscFunctionBegin; 427698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, lbuf, 4, NULL, PETSC_LONG);CHKERRQ(ierr); 428698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(lbuf, PETSC_LONG, 4);CHKERRQ(ierr);} 429698a79b9SLisandro Dalcin for (i = 0; i < 4; ++i) count[i] = lbuf[i]; 430730356f6SLisandro Dalcin ierr = GmshEntitiesCreate(count, entities);CHKERRQ(ierr); 431de78e4feSLisandro Dalcin for (dim = 0; dim < 4; ++dim) { 432730356f6SLisandro Dalcin for (index = 0; index < count[dim]; ++index) { 433730356f6SLisandro Dalcin ierr = PetscViewerRead(viewer, &eid, 1, NULL, PETSC_ENUM);CHKERRQ(ierr); 434730356f6SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&eid, PETSC_ENUM, 1);CHKERRQ(ierr);} 435730356f6SLisandro Dalcin ierr = GmshEntitiesAdd(*entities, (PetscInt)index, dim, eid, &entity);CHKERRQ(ierr); 436de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, entity->bbox, 6, NULL, PETSC_DOUBLE);CHKERRQ(ierr); 437de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(entity->bbox, PETSC_DOUBLE, 6);CHKERRQ(ierr);} 438de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &num, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 439de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&num, PETSC_LONG, 1);CHKERRQ(ierr);} 440698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, num, sizeof(int), &ibuf);CHKERRQ(ierr); 441de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, num, NULL, PETSC_ENUM);CHKERRQ(ierr); 442730356f6SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, num);CHKERRQ(ierr);} 443de78e4feSLisandro Dalcin entity->numTags = numTags = (int) PetscMin(num, 4); 444de78e4feSLisandro Dalcin for (t = 0; t < numTags; ++t) entity->tags[t] = ibuf[t]; 445de78e4feSLisandro Dalcin if (dim == 0) continue; 446de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &num, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 447de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&num, PETSC_LONG, 1);CHKERRQ(ierr);} 448698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, num, sizeof(int), &ibuf);CHKERRQ(ierr); 449de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, num, NULL, PETSC_ENUM);CHKERRQ(ierr); 450730356f6SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, num);CHKERRQ(ierr);} 451de78e4feSLisandro Dalcin } 452de78e4feSLisandro Dalcin } 453de78e4feSLisandro Dalcin PetscFunctionReturn(0); 454de78e4feSLisandro Dalcin } 455de78e4feSLisandro Dalcin 456de78e4feSLisandro Dalcin /* 457de78e4feSLisandro Dalcin $Nodes 458de78e4feSLisandro Dalcin numEntityBlocks(unsigned long) numNodes(unsigned long) 459de78e4feSLisandro Dalcin tagEntity(int) dimEntity(int) typeNode(int) numNodes(unsigned long) 460de78e4feSLisandro Dalcin tag(int) x(double) y(double) z(double) 461de78e4feSLisandro Dalcin ... 462de78e4feSLisandro Dalcin ... 463de78e4feSLisandro Dalcin $EndNodes 464de78e4feSLisandro Dalcin */ 465698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadNodes_v40(GmshFile *gmsh, int shift, PetscInt *numVertices, double **gmsh_nodes) 466de78e4feSLisandro Dalcin { 467698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 468698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 469de78e4feSLisandro Dalcin long block, node, v, numEntityBlocks, numTotalNodes, numNodes; 470de78e4feSLisandro Dalcin int info[3], nid; 471de78e4feSLisandro Dalcin double *coordinates; 472de78e4feSLisandro Dalcin PetscErrorCode ierr; 473de78e4feSLisandro Dalcin 474de78e4feSLisandro Dalcin PetscFunctionBegin; 475de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numEntityBlocks, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 476de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numEntityBlocks, PETSC_LONG, 1);CHKERRQ(ierr);} 477de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numTotalNodes, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 478de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numTotalNodes, PETSC_LONG, 1);CHKERRQ(ierr);} 479de78e4feSLisandro Dalcin ierr = PetscMalloc1(numTotalNodes*3, &coordinates);CHKERRQ(ierr); 480698a79b9SLisandro Dalcin *numVertices = numTotalNodes; 481de78e4feSLisandro Dalcin *gmsh_nodes = coordinates; 482de78e4feSLisandro Dalcin for (v = 0, block = 0; block < numEntityBlocks; ++block) { 483de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, info, 3, NULL, PETSC_ENUM);CHKERRQ(ierr); 484de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numNodes, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 485de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numNodes, PETSC_LONG, 1);CHKERRQ(ierr);} 486698a79b9SLisandro Dalcin if (gmsh->binary) { 487277f51e8SBarry Smith size_t nbytes = sizeof(int) + 3*sizeof(double); 488277f51e8SBarry Smith char *cbuf = NULL; /* dummy value to prevent warning from compiler about possible unitilized value */ 489698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numNodes, nbytes, &cbuf);CHKERRQ(ierr); 490de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, cbuf, numNodes*nbytes, NULL, PETSC_CHAR);CHKERRQ(ierr); 491de78e4feSLisandro Dalcin for (node = 0; node < numNodes; ++node, ++v) { 492de78e4feSLisandro Dalcin char *cnid = cbuf + node*nbytes, *cxyz = cnid + sizeof(int); 493de78e4feSLisandro Dalcin double *xyz = coordinates + v*3; 49430815ce0SLisandro Dalcin if (!PetscBinaryBigEndian()) {ierr = PetscByteSwap(cnid, PETSC_ENUM, 1);CHKERRQ(ierr);} 49530815ce0SLisandro Dalcin if (!PetscBinaryBigEndian()) {ierr = PetscByteSwap(cxyz, PETSC_DOUBLE, 3);CHKERRQ(ierr);} 496de78e4feSLisandro Dalcin ierr = PetscMemcpy(&nid, cnid, sizeof(int));CHKERRQ(ierr); 497de78e4feSLisandro Dalcin ierr = PetscMemcpy(xyz, cxyz, 3*sizeof(double));CHKERRQ(ierr); 498de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&nid, PETSC_ENUM, 1);CHKERRQ(ierr);} 499de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(xyz, PETSC_DOUBLE, 3);CHKERRQ(ierr);} 500277f51e8SBarry Smith if ((long)nid != v+shift) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unexpected node number %d should be %ld", nid, v+shift); 501de78e4feSLisandro Dalcin } 502de78e4feSLisandro Dalcin } else { 503de78e4feSLisandro Dalcin for (node = 0; node < numNodes; ++node, ++v) { 504de78e4feSLisandro Dalcin double *xyz = coordinates + v*3; 505de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &nid, 1, NULL, PETSC_ENUM);CHKERRQ(ierr); 506de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&nid, PETSC_ENUM, 1);CHKERRQ(ierr);} 507277f51e8SBarry Smith if ((long)nid != v+shift) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unexpected node number %d should be %ld", nid, v+shift); 508de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, xyz, 3, NULL, PETSC_DOUBLE);CHKERRQ(ierr); 509de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(xyz, PETSC_DOUBLE, 3);CHKERRQ(ierr);} 510de78e4feSLisandro Dalcin } 511de78e4feSLisandro Dalcin } 512de78e4feSLisandro Dalcin } 513de78e4feSLisandro Dalcin PetscFunctionReturn(0); 514de78e4feSLisandro Dalcin } 515de78e4feSLisandro Dalcin 516de78e4feSLisandro Dalcin /* 517de78e4feSLisandro Dalcin $Elements 518de78e4feSLisandro Dalcin numEntityBlocks(unsigned long) numElements(unsigned long) 519de78e4feSLisandro Dalcin tagEntity(int) dimEntity(int) typeEle(int) numElements(unsigned long) 520de78e4feSLisandro Dalcin tag(int) numVert[...](int) 521de78e4feSLisandro Dalcin ... 522de78e4feSLisandro Dalcin ... 523de78e4feSLisandro Dalcin $EndElements 524de78e4feSLisandro Dalcin */ 525698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadElements_v40(GmshFile *gmsh, PETSC_UNUSED int shift, GmshEntities *entities, PetscInt *numCells, GmshElement **gmsh_elems) 526de78e4feSLisandro Dalcin { 527698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 528698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 529de78e4feSLisandro Dalcin long c, block, numEntityBlocks, numTotalElements, elem, numElements; 530de78e4feSLisandro Dalcin int p, info[3], *ibuf = NULL; 531de78e4feSLisandro Dalcin int eid, dim, numTags, *tags, cellType, numNodes; 532a5ba3d71SLisandro Dalcin GmshEntity *entity = NULL; 533de78e4feSLisandro Dalcin GmshElement *elements; 534de78e4feSLisandro Dalcin PetscErrorCode ierr; 535de78e4feSLisandro Dalcin 536de78e4feSLisandro Dalcin PetscFunctionBegin; 537de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numEntityBlocks, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 538de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numEntityBlocks, PETSC_LONG, 1);CHKERRQ(ierr);} 539de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numTotalElements, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 540de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numTotalElements, PETSC_LONG, 1);CHKERRQ(ierr);} 541de78e4feSLisandro Dalcin ierr = PetscCalloc1(numTotalElements, &elements);CHKERRQ(ierr); 542698a79b9SLisandro Dalcin *numCells = numTotalElements; 543de78e4feSLisandro Dalcin *gmsh_elems = elements; 544de78e4feSLisandro Dalcin for (c = 0, block = 0; block < numEntityBlocks; ++block) { 545de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, info, 3, NULL, PETSC_ENUM);CHKERRQ(ierr); 546de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(info, PETSC_ENUM, 3);CHKERRQ(ierr);} 547de78e4feSLisandro Dalcin eid = info[0]; dim = info[1]; cellType = info[2]; 548730356f6SLisandro Dalcin ierr = GmshEntitiesGet(entities, dim, eid, &entity);CHKERRQ(ierr); 549730356f6SLisandro Dalcin numTags = entity->numTags; 550730356f6SLisandro Dalcin tags = entity->tags; 551de78e4feSLisandro Dalcin switch (cellType) { 552de78e4feSLisandro Dalcin case 1: /* 2-node line */ 553de78e4feSLisandro Dalcin numNodes = 2; 554de78e4feSLisandro Dalcin break; 555de78e4feSLisandro Dalcin case 2: /* 3-node triangle */ 556698a79b9SLisandro Dalcin numNodes = 3; 557698a79b9SLisandro Dalcin break; 558de78e4feSLisandro Dalcin case 3: /* 4-node quadrangle */ 559de78e4feSLisandro Dalcin numNodes = 4; 560de78e4feSLisandro Dalcin break; 561de78e4feSLisandro Dalcin case 4: /* 4-node tetrahedron */ 562de78e4feSLisandro Dalcin numNodes = 4; 563de78e4feSLisandro Dalcin break; 564de78e4feSLisandro Dalcin case 5: /* 8-node hexahedron */ 565de78e4feSLisandro Dalcin numNodes = 8; 566de78e4feSLisandro Dalcin break; 567de78e4feSLisandro Dalcin case 6: /* 6-node wedge */ 568de78e4feSLisandro Dalcin numNodes = 6; 569de78e4feSLisandro Dalcin break; 570de78e4feSLisandro Dalcin case 15: /* 1-node vertex */ 571de78e4feSLisandro Dalcin numNodes = 1; 572de78e4feSLisandro Dalcin break; 573de78e4feSLisandro Dalcin default: 574de78e4feSLisandro Dalcin SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported Gmsh element type %d", cellType); 575de78e4feSLisandro Dalcin } 576de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, &numElements, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 577de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numElements, PETSC_LONG, 1);CHKERRQ(ierr);} 578698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, (1+numNodes)*numElements, sizeof(int), &ibuf);CHKERRQ(ierr); 579de78e4feSLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, (1+numNodes)*numElements, NULL, PETSC_ENUM);CHKERRQ(ierr); 580de78e4feSLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, (1+numNodes)*numElements);CHKERRQ(ierr);} 581de78e4feSLisandro Dalcin for (elem = 0; elem < numElements; ++elem, ++c) { 582de78e4feSLisandro Dalcin int *id = ibuf + elem*(1+numNodes), *nodes = id + 1; 583de78e4feSLisandro Dalcin GmshElement *element = elements + c; 584de78e4feSLisandro Dalcin element->dim = dim; 585de78e4feSLisandro Dalcin element->cellType = cellType; 586de78e4feSLisandro Dalcin element->numNodes = numNodes; 587de78e4feSLisandro Dalcin element->numTags = numTags; 588de78e4feSLisandro Dalcin element->id = id[0]; 589de78e4feSLisandro Dalcin for (p = 0; p < numNodes; p++) element->nodes[p] = nodes[p]; 590de78e4feSLisandro Dalcin for (p = 0; p < numTags; p++) element->tags[p] = tags[p]; 591de78e4feSLisandro Dalcin } 592de78e4feSLisandro Dalcin } 593698a79b9SLisandro Dalcin PetscFunctionReturn(0); 594698a79b9SLisandro Dalcin } 595698a79b9SLisandro Dalcin 596698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadPeriodic_v40(GmshFile *gmsh, int shift, PetscInt slaveMap[], PetscBT bt) 597698a79b9SLisandro Dalcin { 598698a79b9SLisandro Dalcin PetscViewer viewer = gmsh->viewer; 599698a79b9SLisandro Dalcin int fileFormat = gmsh->fileFormat; 600698a79b9SLisandro Dalcin PetscBool binary = gmsh->binary; 601698a79b9SLisandro Dalcin PetscBool byteSwap = gmsh->byteSwap; 602698a79b9SLisandro Dalcin int numPeriodic, snum, i; 603698a79b9SLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 604698a79b9SLisandro Dalcin PetscErrorCode ierr; 605698a79b9SLisandro Dalcin 606698a79b9SLisandro Dalcin PetscFunctionBegin; 607698a79b9SLisandro Dalcin if (fileFormat == 22 || !binary) { 608698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 609698a79b9SLisandro Dalcin snum = sscanf(line, "%d", &numPeriodic); 610698a79b9SLisandro Dalcin if (snum != 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 611698a79b9SLisandro Dalcin } else { 612698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, &numPeriodic, 1, NULL, PETSC_ENUM);CHKERRQ(ierr); 613698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&numPeriodic, PETSC_ENUM, 1);CHKERRQ(ierr);} 614698a79b9SLisandro Dalcin } 615698a79b9SLisandro Dalcin for (i = 0; i < numPeriodic; i++) { 616698a79b9SLisandro Dalcin int ibuf[3], slaveDim = -1, slaveTag = -1, masterTag = -1, slaveNode, masterNode; 617698a79b9SLisandro Dalcin long j, nNodes; 618698a79b9SLisandro Dalcin double affine[16]; 619698a79b9SLisandro Dalcin 620698a79b9SLisandro Dalcin if (fileFormat == 22 || !binary) { 621698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 3, NULL, PETSC_STRING);CHKERRQ(ierr); 622698a79b9SLisandro Dalcin snum = sscanf(line, "%d %d %d", &slaveDim, &slaveTag, &masterTag); 623698a79b9SLisandro Dalcin if (snum != 3) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 624698a79b9SLisandro Dalcin } else { 625698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, 3, NULL, PETSC_ENUM);CHKERRQ(ierr); 626698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, 3);CHKERRQ(ierr);} 627698a79b9SLisandro Dalcin slaveDim = ibuf[0]; slaveTag = ibuf[1]; masterTag = ibuf[2]; 628698a79b9SLisandro Dalcin } 629698a79b9SLisandro Dalcin (void)slaveDim; (void)slaveTag; (void)masterTag; /* unused */ 630698a79b9SLisandro Dalcin 631698a79b9SLisandro Dalcin if (fileFormat == 22 || !binary) { 632698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 633698a79b9SLisandro Dalcin snum = sscanf(line, "%ld", &nNodes); 6344c500f23SPierre Jolivet if (snum != 1) { /* discard transformation and try again */ 635698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, -PETSC_MAX_PATH_LEN, NULL, PETSC_STRING);CHKERRQ(ierr); 636698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 1, NULL, PETSC_STRING);CHKERRQ(ierr); 637698a79b9SLisandro Dalcin snum = sscanf(line, "%ld", &nNodes); 638698a79b9SLisandro Dalcin if (snum != 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 639698a79b9SLisandro Dalcin } 640698a79b9SLisandro Dalcin } else { 641698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, &nNodes, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 642698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&nNodes, PETSC_LONG, 1);CHKERRQ(ierr);} 6434c500f23SPierre Jolivet if (nNodes == -1) { /* discard transformation and try again */ 644698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, affine, 16, NULL, PETSC_DOUBLE);CHKERRQ(ierr); 645698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, &nNodes, 1, NULL, PETSC_LONG);CHKERRQ(ierr); 646698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(&nNodes, PETSC_LONG, 1);CHKERRQ(ierr);} 647698a79b9SLisandro Dalcin } 648698a79b9SLisandro Dalcin } 649698a79b9SLisandro Dalcin 650698a79b9SLisandro Dalcin for (j = 0; j < nNodes; j++) { 651698a79b9SLisandro Dalcin if (fileFormat == 22 || !binary) { 652698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, line, 2, NULL, PETSC_STRING);CHKERRQ(ierr); 653698a79b9SLisandro Dalcin snum = sscanf(line, "%d %d", &slaveNode, &masterNode); 654698a79b9SLisandro Dalcin if (snum != 2) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 655698a79b9SLisandro Dalcin } else { 656698a79b9SLisandro Dalcin ierr = PetscViewerRead(viewer, ibuf, 2, NULL, PETSC_ENUM);CHKERRQ(ierr); 657698a79b9SLisandro Dalcin if (byteSwap) {ierr = PetscByteSwap(ibuf, PETSC_ENUM, 2);CHKERRQ(ierr);} 658698a79b9SLisandro Dalcin slaveNode = ibuf[0]; masterNode = ibuf[1]; 659698a79b9SLisandro Dalcin } 660698a79b9SLisandro Dalcin slaveMap[slaveNode - shift] = masterNode - shift; 661698a79b9SLisandro Dalcin ierr = PetscBTSet(bt, slaveNode - shift);CHKERRQ(ierr); 662698a79b9SLisandro Dalcin ierr = PetscBTSet(bt, masterNode - shift);CHKERRQ(ierr); 663698a79b9SLisandro Dalcin } 664698a79b9SLisandro Dalcin } 665698a79b9SLisandro Dalcin PetscFunctionReturn(0); 666698a79b9SLisandro Dalcin } 667698a79b9SLisandro Dalcin 668698a79b9SLisandro Dalcin /* 669698a79b9SLisandro Dalcin $Entities 670698a79b9SLisandro Dalcin numPoints(size_t) numCurves(size_t) 671698a79b9SLisandro Dalcin numSurfaces(size_t) numVolumes(size_t) 672698a79b9SLisandro Dalcin pointTag(int) X(double) Y(double) Z(double) 673698a79b9SLisandro Dalcin numPhysicalTags(size_t) physicalTag(int) ... 674698a79b9SLisandro Dalcin ... 675698a79b9SLisandro Dalcin curveTag(int) minX(double) minY(double) minZ(double) 676698a79b9SLisandro Dalcin maxX(double) maxY(double) maxZ(double) 677698a79b9SLisandro Dalcin numPhysicalTags(size_t) physicalTag(int) ... 678698a79b9SLisandro Dalcin numBoundingPoints(size_t) pointTag(int) ... 679698a79b9SLisandro Dalcin ... 680698a79b9SLisandro Dalcin surfaceTag(int) minX(double) minY(double) minZ(double) 681698a79b9SLisandro Dalcin maxX(double) maxY(double) maxZ(double) 682698a79b9SLisandro Dalcin numPhysicalTags(size_t) physicalTag(int) ... 683698a79b9SLisandro Dalcin numBoundingCurves(size_t) curveTag(int) ... 684698a79b9SLisandro Dalcin ... 685698a79b9SLisandro Dalcin volumeTag(int) minX(double) minY(double) minZ(double) 686698a79b9SLisandro Dalcin maxX(double) maxY(double) maxZ(double) 687698a79b9SLisandro Dalcin numPhysicalTags(size_t) physicalTag(int) ... 688698a79b9SLisandro Dalcin numBoundngSurfaces(size_t) surfaceTag(int) ... 689698a79b9SLisandro Dalcin ... 690698a79b9SLisandro Dalcin $EndEntities 691698a79b9SLisandro Dalcin */ 692698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadEntities_v41(GmshFile *gmsh, GmshEntities **entities) 693698a79b9SLisandro Dalcin { 694698a79b9SLisandro Dalcin PetscInt count[4], index, numTags, i; 695698a79b9SLisandro Dalcin int dim, eid, *tags = NULL; 696698a79b9SLisandro Dalcin GmshEntity *entity = NULL; 697698a79b9SLisandro Dalcin PetscErrorCode ierr; 698698a79b9SLisandro Dalcin 699698a79b9SLisandro Dalcin PetscFunctionBegin; 700698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, count, 4);CHKERRQ(ierr); 701698a79b9SLisandro Dalcin ierr = GmshEntitiesCreate(count, entities);CHKERRQ(ierr); 702698a79b9SLisandro Dalcin for (dim = 0; dim < 4; ++dim) { 703698a79b9SLisandro Dalcin for (index = 0; index < count[dim]; ++index) { 704698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, &eid, 1);CHKERRQ(ierr); 705698a79b9SLisandro Dalcin ierr = GmshEntitiesAdd(*entities, (PetscInt)index, dim, eid, &entity);CHKERRQ(ierr); 706698a79b9SLisandro Dalcin ierr = GmshReadDouble(gmsh, entity->bbox, (dim == 0) ? 3 : 6);CHKERRQ(ierr); 707698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numTags, 1);CHKERRQ(ierr); 708698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numTags, sizeof(int), &tags);CHKERRQ(ierr); 709698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, tags, numTags);CHKERRQ(ierr); 710698a79b9SLisandro Dalcin entity->numTags = PetscMin(numTags, 4); 711698a79b9SLisandro Dalcin for (i = 0; i < entity->numTags; ++i) entity->tags[i] = tags[i]; 712698a79b9SLisandro Dalcin if (dim == 0) continue; 713698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numTags, 1);CHKERRQ(ierr); 714698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numTags, sizeof(int), &tags);CHKERRQ(ierr); 715698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, tags, numTags);CHKERRQ(ierr); 716698a79b9SLisandro Dalcin } 717698a79b9SLisandro Dalcin } 718698a79b9SLisandro Dalcin PetscFunctionReturn(0); 719698a79b9SLisandro Dalcin } 720698a79b9SLisandro Dalcin 721698a79b9SLisandro Dalcin /* 722698a79b9SLisandro Dalcin $Nodes 723698a79b9SLisandro Dalcin numEntityBlocks(size_t) numNodes(size_t) 724698a79b9SLisandro Dalcin minNodeTag(size_t) maxNodeTag(size_t) 725698a79b9SLisandro Dalcin entityDim(int) entityTag(int) parametric(int; 0 or 1) numNodesBlock(size_t) 726698a79b9SLisandro Dalcin nodeTag(size_t) 727698a79b9SLisandro Dalcin ... 728698a79b9SLisandro Dalcin x(double) y(double) z(double) 729698a79b9SLisandro Dalcin < u(double; if parametric and entityDim = 1 or entityDim = 2) > 730698a79b9SLisandro Dalcin < v(double; if parametric and entityDim = 2) > 731698a79b9SLisandro Dalcin ... 732698a79b9SLisandro Dalcin ... 733698a79b9SLisandro Dalcin $EndNodes 734698a79b9SLisandro Dalcin */ 735698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadNodes_v41(GmshFile *gmsh, int shift, PetscInt *numVertices, double **gmsh_nodes) 736698a79b9SLisandro Dalcin { 737698a79b9SLisandro Dalcin int info[3]; 738698a79b9SLisandro Dalcin PetscInt sizes[4], numEntityBlocks, numNodes, numNodesBlock = 0, *nodeTag = NULL, block, node, i; 739698a79b9SLisandro Dalcin double *coordinates; 740698a79b9SLisandro Dalcin PetscErrorCode ierr; 741698a79b9SLisandro Dalcin 742698a79b9SLisandro Dalcin PetscFunctionBegin; 743698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, sizes, 4);CHKERRQ(ierr); 744698a79b9SLisandro Dalcin numEntityBlocks = sizes[0]; numNodes = sizes[1]; 745698a79b9SLisandro Dalcin ierr = PetscMalloc1(numNodes*3, &coordinates);CHKERRQ(ierr); 746698a79b9SLisandro Dalcin *numVertices = numNodes; 747698a79b9SLisandro Dalcin *gmsh_nodes = coordinates; 748698a79b9SLisandro Dalcin for (block = 0, node = 0; block < numEntityBlocks; ++block, node += numNodesBlock) { 749698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, info, 3);CHKERRQ(ierr); 750698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numNodesBlock, 1);CHKERRQ(ierr); 751698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numNodesBlock, sizeof(PetscInt), &nodeTag);CHKERRQ(ierr); 752698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, nodeTag, numNodesBlock);CHKERRQ(ierr); 753698a79b9SLisandro 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); 754698a79b9SLisandro Dalcin if (info[2] != 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Parametric coordinates not supported"); 755698a79b9SLisandro Dalcin ierr = GmshReadDouble(gmsh, coordinates+node*3, numNodesBlock*3);CHKERRQ(ierr); 756698a79b9SLisandro Dalcin } 757698a79b9SLisandro Dalcin PetscFunctionReturn(0); 758698a79b9SLisandro Dalcin } 759698a79b9SLisandro Dalcin 760698a79b9SLisandro Dalcin /* 761698a79b9SLisandro Dalcin $Elements 762698a79b9SLisandro Dalcin numEntityBlocks(size_t) numElements(size_t) 763698a79b9SLisandro Dalcin minElementTag(size_t) maxElementTag(size_t) 764698a79b9SLisandro Dalcin entityDim(int) entityTag(int) elementType(int; see below) numElementsBlock(size_t) 765698a79b9SLisandro Dalcin elementTag(size_t) nodeTag(size_t) ... 766698a79b9SLisandro Dalcin ... 767698a79b9SLisandro Dalcin ... 768698a79b9SLisandro Dalcin $EndElements 769698a79b9SLisandro Dalcin */ 770698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadElements_v41(GmshFile *gmsh, PETSC_UNUSED int shift, GmshEntities *entities, PetscInt *numCells, GmshElement **gmsh_elems) 771698a79b9SLisandro Dalcin { 772698a79b9SLisandro Dalcin int info[3], eid, dim, cellType, *tags; 773698a79b9SLisandro Dalcin PetscInt sizes[4], *ibuf = NULL, numEntityBlocks, numElements, numBlockElements, numNodes, numTags, block, elem, c, p; 774698a79b9SLisandro Dalcin GmshEntity *entity = NULL; 775698a79b9SLisandro Dalcin GmshElement *elements; 776698a79b9SLisandro Dalcin PetscErrorCode ierr; 777698a79b9SLisandro Dalcin 778698a79b9SLisandro Dalcin PetscFunctionBegin; 779698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, sizes, 4);CHKERRQ(ierr); 780698a79b9SLisandro Dalcin numEntityBlocks = sizes[0]; numElements = sizes[1]; 781698a79b9SLisandro Dalcin ierr = PetscCalloc1(numElements, &elements);CHKERRQ(ierr); 782698a79b9SLisandro Dalcin *numCells = numElements; 783698a79b9SLisandro Dalcin *gmsh_elems = elements; 784698a79b9SLisandro Dalcin for (c = 0, block = 0; block < numEntityBlocks; ++block) { 785698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, info, 3);CHKERRQ(ierr); 786698a79b9SLisandro Dalcin dim = info[0]; eid = info[1]; cellType = info[2]; 787698a79b9SLisandro Dalcin ierr = GmshEntitiesGet(entities, dim, eid, &entity);CHKERRQ(ierr); 788698a79b9SLisandro Dalcin numTags = entity->numTags; 789698a79b9SLisandro Dalcin tags = entity->tags; 790698a79b9SLisandro Dalcin switch (cellType) { 791698a79b9SLisandro Dalcin case 1: /* 2-node line */ 792698a79b9SLisandro Dalcin numNodes = 2; 793698a79b9SLisandro Dalcin break; 794698a79b9SLisandro Dalcin case 2: /* 3-node triangle */ 795698a79b9SLisandro Dalcin numNodes = 3; 796698a79b9SLisandro Dalcin break; 797698a79b9SLisandro Dalcin case 3: /* 4-node quadrangle */ 798698a79b9SLisandro Dalcin numNodes = 4; 799698a79b9SLisandro Dalcin break; 800698a79b9SLisandro Dalcin case 4: /* 4-node tetrahedron */ 801698a79b9SLisandro Dalcin numNodes = 4; 802698a79b9SLisandro Dalcin break; 803698a79b9SLisandro Dalcin case 5: /* 8-node hexahedron */ 804698a79b9SLisandro Dalcin numNodes = 8; 805698a79b9SLisandro Dalcin break; 806698a79b9SLisandro Dalcin case 6: /* 6-node wedge */ 807698a79b9SLisandro Dalcin numNodes = 6; 808698a79b9SLisandro Dalcin break; 809698a79b9SLisandro Dalcin case 15: /* 1-node vertex */ 810698a79b9SLisandro Dalcin numNodes = 1; 811698a79b9SLisandro Dalcin break; 812698a79b9SLisandro Dalcin default: 813698a79b9SLisandro Dalcin SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported Gmsh element type %d", cellType); 814698a79b9SLisandro Dalcin } 815698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numBlockElements, 1);CHKERRQ(ierr); 816698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, (1+numNodes)*numBlockElements, sizeof(PetscInt), &ibuf);CHKERRQ(ierr); 817698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, ibuf, (1+numNodes)*numBlockElements);CHKERRQ(ierr); 818698a79b9SLisandro Dalcin for (elem = 0; elem < numBlockElements; ++elem, ++c) { 819698a79b9SLisandro Dalcin GmshElement *element = elements + c; 820698a79b9SLisandro Dalcin PetscInt *id = ibuf + elem*(1+numNodes), *nodes = id + 1; 821698a79b9SLisandro Dalcin element->id = id[0]; 822698a79b9SLisandro Dalcin element->dim = dim; 823698a79b9SLisandro Dalcin element->cellType = cellType; 824698a79b9SLisandro Dalcin element->numNodes = numNodes; 825698a79b9SLisandro Dalcin element->numTags = numTags; 826698a79b9SLisandro Dalcin for (p = 0; p < numNodes; p++) element->nodes[p] = nodes[p]; 827698a79b9SLisandro Dalcin for (p = 0; p < numTags; p++) element->tags[p] = tags[p]; 828698a79b9SLisandro Dalcin } 829698a79b9SLisandro Dalcin } 830698a79b9SLisandro Dalcin PetscFunctionReturn(0); 831698a79b9SLisandro Dalcin } 832698a79b9SLisandro Dalcin 833698a79b9SLisandro Dalcin /* 834698a79b9SLisandro Dalcin $Periodic 835698a79b9SLisandro Dalcin numPeriodicLinks(size_t) 836698a79b9SLisandro Dalcin entityDim(int) entityTag(int) entityTagMaster(int) 837698a79b9SLisandro Dalcin numAffine(size_t) value(double) ... 838698a79b9SLisandro Dalcin numCorrespondingNodes(size_t) 839698a79b9SLisandro Dalcin nodeTag(size_t) nodeTagMaster(size_t) 840698a79b9SLisandro Dalcin ... 841698a79b9SLisandro Dalcin ... 842698a79b9SLisandro Dalcin $EndPeriodic 843698a79b9SLisandro Dalcin */ 844698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadPeriodic_v41(GmshFile *gmsh, int shift, PetscInt slaveMap[], PetscBT bt) 845698a79b9SLisandro Dalcin { 846698a79b9SLisandro Dalcin int info[3]; 847698a79b9SLisandro Dalcin PetscInt numPeriodicLinks, numAffine, numCorrespondingNodes, *nodeTags = NULL, link, node; 848698a79b9SLisandro Dalcin double dbuf[16]; 849698a79b9SLisandro Dalcin PetscErrorCode ierr; 850698a79b9SLisandro Dalcin 851698a79b9SLisandro Dalcin PetscFunctionBegin; 852698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numPeriodicLinks, 1);CHKERRQ(ierr); 853698a79b9SLisandro Dalcin for (link = 0; link < numPeriodicLinks; ++link) { 854698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, info, 3);CHKERRQ(ierr); 855698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numAffine, 1);CHKERRQ(ierr); 856698a79b9SLisandro Dalcin ierr = GmshReadDouble(gmsh, dbuf, numAffine);CHKERRQ(ierr); 857698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, &numCorrespondingNodes, 1);CHKERRQ(ierr); 858698a79b9SLisandro Dalcin ierr = GmshBufferGet(gmsh, numCorrespondingNodes, sizeof(PetscInt), &nodeTags);CHKERRQ(ierr); 859698a79b9SLisandro Dalcin ierr = GmshReadSize(gmsh, nodeTags, numCorrespondingNodes*2);CHKERRQ(ierr); 860698a79b9SLisandro Dalcin for (node = 0; node < numCorrespondingNodes; ++node) { 861698a79b9SLisandro Dalcin PetscInt slaveNode = nodeTags[node*2+0] - shift; 862698a79b9SLisandro Dalcin PetscInt masterNode = nodeTags[node*2+1] - shift; 863698a79b9SLisandro Dalcin slaveMap[slaveNode] = masterNode; 864698a79b9SLisandro Dalcin ierr = PetscBTSet(bt, slaveNode);CHKERRQ(ierr); 865698a79b9SLisandro Dalcin ierr = PetscBTSet(bt, masterNode);CHKERRQ(ierr); 866698a79b9SLisandro Dalcin } 867698a79b9SLisandro Dalcin } 868698a79b9SLisandro Dalcin PetscFunctionReturn(0); 869698a79b9SLisandro Dalcin } 870698a79b9SLisandro Dalcin 871d6689ca9SLisandro Dalcin /* 872d6689ca9SLisandro Dalcin $MeshFormat // same as MSH version 2 873d6689ca9SLisandro Dalcin version(ASCII double; currently 4.1) 874d6689ca9SLisandro Dalcin file-type(ASCII int; 0 for ASCII mode, 1 for binary mode) 875d6689ca9SLisandro Dalcin data-size(ASCII int; sizeof(size_t)) 876d6689ca9SLisandro Dalcin < int with value one; only in binary mode, to detect endianness > 877d6689ca9SLisandro Dalcin $EndMeshFormat 878d6689ca9SLisandro Dalcin */ 879698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadMeshFormat(GmshFile *gmsh) 880698a79b9SLisandro Dalcin { 881698a79b9SLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 882698a79b9SLisandro Dalcin int snum, fileType, fileFormat, dataSize, checkEndian; 883698a79b9SLisandro Dalcin float version; 884698a79b9SLisandro Dalcin PetscErrorCode ierr; 885698a79b9SLisandro Dalcin 886698a79b9SLisandro Dalcin PetscFunctionBegin; 887698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 3);CHKERRQ(ierr); 888698a79b9SLisandro Dalcin snum = sscanf(line, "%f %d %d", &version, &fileType, &dataSize); 889698a79b9SLisandro Dalcin if (snum != 3) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse Gmsh file header: %s", line); 890698a79b9SLisandro 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); 891698a79b9SLisandro Dalcin if ((int)version == 3) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Gmsh file version %3.1f not supported", (double)version); 892698a79b9SLisandro 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); 893698a79b9SLisandro Dalcin if (gmsh->binary && !fileType) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Viewer is binary but Gmsh file is ASCII"); 894698a79b9SLisandro Dalcin if (!gmsh->binary && fileType) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Viewer is ASCII but Gmsh file is binary"); 895698a79b9SLisandro Dalcin fileFormat = (int)(version*10); /* XXX Should use (int)roundf(version*10) ? */ 896698a79b9SLisandro 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); 897698a79b9SLisandro 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); 898698a79b9SLisandro Dalcin gmsh->fileFormat = fileFormat; 899698a79b9SLisandro Dalcin gmsh->dataSize = dataSize; 900698a79b9SLisandro Dalcin gmsh->byteSwap = PETSC_FALSE; 901698a79b9SLisandro Dalcin if (gmsh->binary) { 902698a79b9SLisandro Dalcin ierr = GmshReadInt(gmsh, &checkEndian, 1);CHKERRQ(ierr); 903698a79b9SLisandro Dalcin if (checkEndian != 1) { 904698a79b9SLisandro Dalcin ierr = PetscByteSwap(&checkEndian, PETSC_ENUM, 1);CHKERRQ(ierr); 905698a79b9SLisandro Dalcin if (checkEndian != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to detect endianness in Gmsh file header: %s", line); 906698a79b9SLisandro Dalcin gmsh->byteSwap = PETSC_TRUE; 907698a79b9SLisandro Dalcin } 908698a79b9SLisandro Dalcin } 909698a79b9SLisandro Dalcin PetscFunctionReturn(0); 910698a79b9SLisandro Dalcin } 911698a79b9SLisandro Dalcin 9121f643af3SLisandro Dalcin /* 9131f643af3SLisandro Dalcin PhysicalNames 9141f643af3SLisandro Dalcin numPhysicalNames(ASCII int) 9151f643af3SLisandro Dalcin dimension(ASCII int) physicalTag(ASCII int) "name"(127 characters max) 9161f643af3SLisandro Dalcin ... 9171f643af3SLisandro Dalcin $EndPhysicalNames 9181f643af3SLisandro Dalcin */ 919698a79b9SLisandro Dalcin static PetscErrorCode DMPlexCreateGmsh_ReadPhysicalNames(GmshFile *gmsh) 920698a79b9SLisandro Dalcin { 9211f643af3SLisandro Dalcin char line[PETSC_MAX_PATH_LEN], name[128+2], *p, *q; 9221f643af3SLisandro Dalcin int snum, numRegions, region, dim, tag; 923698a79b9SLisandro Dalcin PetscErrorCode ierr; 924698a79b9SLisandro Dalcin 925698a79b9SLisandro Dalcin PetscFunctionBegin; 926698a79b9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 1);CHKERRQ(ierr); 927698a79b9SLisandro Dalcin snum = sscanf(line, "%d", &numRegions); 928698a79b9SLisandro Dalcin if (snum != 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 929698a79b9SLisandro Dalcin for (region = 0; region < numRegions; ++region) { 9301f643af3SLisandro Dalcin ierr = GmshReadString(gmsh, line, 2);CHKERRQ(ierr); 9311f643af3SLisandro Dalcin snum = sscanf(line, "%d %d", &dim, &tag); 9321f643af3SLisandro Dalcin if (snum != 2) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 9331f643af3SLisandro Dalcin ierr = GmshReadString(gmsh, line, -(PetscInt)sizeof(line));CHKERRQ(ierr); 9341f643af3SLisandro Dalcin ierr = PetscStrchr(line, '"', &p);CHKERRQ(ierr); 9351f643af3SLisandro Dalcin if (!p) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 9361f643af3SLisandro Dalcin ierr = PetscStrrchr(line, '"', &q);CHKERRQ(ierr); 9371f643af3SLisandro Dalcin if (q == p) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "File is not a valid Gmsh file"); 9381f643af3SLisandro Dalcin ierr = PetscStrncpy(name, p+1, (size_t)(q-p-1));CHKERRQ(ierr); 939698a79b9SLisandro Dalcin } 940de78e4feSLisandro Dalcin PetscFunctionReturn(0); 941de78e4feSLisandro Dalcin } 942de78e4feSLisandro Dalcin 943*96ca5757SLisandro Dalcin 944*96ca5757SLisandro Dalcin PETSC_STATIC_INLINE DMPolytopeType DMPolytopeTypeFromGmsh(PetscInt ctGmsh) 945*96ca5757SLisandro Dalcin { 946*96ca5757SLisandro Dalcin switch (ctGmsh) { 947*96ca5757SLisandro Dalcin case 15: 948*96ca5757SLisandro Dalcin return DM_POLYTOPE_POINT; 949*96ca5757SLisandro Dalcin case 1: 950*96ca5757SLisandro Dalcin case 8: 951*96ca5757SLisandro Dalcin return DM_POLYTOPE_SEGMENT; 952*96ca5757SLisandro Dalcin case 2: 953*96ca5757SLisandro Dalcin case 9: 954*96ca5757SLisandro Dalcin return DM_POLYTOPE_TRIANGLE; 955*96ca5757SLisandro Dalcin case 3: 956*96ca5757SLisandro Dalcin case 10: 957*96ca5757SLisandro Dalcin return DM_POLYTOPE_QUADRILATERAL; 958*96ca5757SLisandro Dalcin case 4: 959*96ca5757SLisandro Dalcin case 11: 960*96ca5757SLisandro Dalcin return DM_POLYTOPE_TETRAHEDRON; 961*96ca5757SLisandro Dalcin case 5: 962*96ca5757SLisandro Dalcin case 12: 963*96ca5757SLisandro Dalcin return DM_POLYTOPE_HEXAHEDRON; 964*96ca5757SLisandro Dalcin case 6: 965*96ca5757SLisandro Dalcin case 13: 966*96ca5757SLisandro Dalcin return DM_POLYTOPE_TRI_PRISM; 967*96ca5757SLisandro Dalcin case 7: 968*96ca5757SLisandro Dalcin case 14: 969*96ca5757SLisandro Dalcin return DM_POLYTOPE_UNKNOWN; /* Pyramid */ 970*96ca5757SLisandro Dalcin default: 971*96ca5757SLisandro Dalcin return DM_POLYTOPE_UNKNOWN; 972*96ca5757SLisandro Dalcin } 973*96ca5757SLisandro Dalcin } 974*96ca5757SLisandro Dalcin 975d6689ca9SLisandro Dalcin /*@C 976d6689ca9SLisandro Dalcin DMPlexCreateGmshFromFile - Create a DMPlex mesh from a Gmsh file 977d6689ca9SLisandro Dalcin 978d6689ca9SLisandro Dalcin + comm - The MPI communicator 979d6689ca9SLisandro Dalcin . filename - Name of the Gmsh file 980d6689ca9SLisandro Dalcin - interpolate - Create faces and edges in the mesh 981d6689ca9SLisandro Dalcin 982d6689ca9SLisandro Dalcin Output Parameter: 983d6689ca9SLisandro Dalcin . dm - The DM object representing the mesh 984d6689ca9SLisandro Dalcin 985d6689ca9SLisandro Dalcin Level: beginner 986d6689ca9SLisandro Dalcin 987d6689ca9SLisandro Dalcin .seealso: DMPlexCreateFromFile(), DMPlexCreateGmsh(), DMPlexCreate() 988d6689ca9SLisandro Dalcin @*/ 989d6689ca9SLisandro Dalcin PetscErrorCode DMPlexCreateGmshFromFile(MPI_Comm comm, const char filename[], PetscBool interpolate, DM *dm) 990d6689ca9SLisandro Dalcin { 991d6689ca9SLisandro Dalcin PetscViewer viewer; 992d6689ca9SLisandro Dalcin PetscMPIInt rank; 993d6689ca9SLisandro Dalcin int fileType; 994d6689ca9SLisandro Dalcin PetscViewerType vtype; 995d6689ca9SLisandro Dalcin PetscErrorCode ierr; 996d6689ca9SLisandro Dalcin 997d6689ca9SLisandro Dalcin PetscFunctionBegin; 998d6689ca9SLisandro Dalcin ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 999d6689ca9SLisandro Dalcin 1000d6689ca9SLisandro Dalcin /* Determine Gmsh file type (ASCII or binary) from file header */ 1001d6689ca9SLisandro Dalcin if (!rank) { 1002d6689ca9SLisandro Dalcin GmshFile gmsh_, *gmsh = &gmsh_; 1003d6689ca9SLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 1004d6689ca9SLisandro Dalcin int snum; 1005d6689ca9SLisandro Dalcin float version; 1006d6689ca9SLisandro Dalcin 1007580bdb30SBarry Smith ierr = PetscArrayzero(gmsh,1);CHKERRQ(ierr); 1008d6689ca9SLisandro Dalcin ierr = PetscViewerCreate(PETSC_COMM_SELF, &gmsh->viewer);CHKERRQ(ierr); 1009d6689ca9SLisandro Dalcin ierr = PetscViewerSetType(gmsh->viewer, PETSCVIEWERASCII);CHKERRQ(ierr); 1010d6689ca9SLisandro Dalcin ierr = PetscViewerFileSetMode(gmsh->viewer, FILE_MODE_READ);CHKERRQ(ierr); 1011d6689ca9SLisandro Dalcin ierr = PetscViewerFileSetName(gmsh->viewer, filename);CHKERRQ(ierr); 1012d6689ca9SLisandro Dalcin /* Read only the first two lines of the Gmsh file */ 1013d6689ca9SLisandro Dalcin ierr = GmshReadSection(gmsh, line);CHKERRQ(ierr); 1014d6689ca9SLisandro Dalcin ierr = GmshExpect(gmsh, "$MeshFormat", line);CHKERRQ(ierr); 1015d6689ca9SLisandro Dalcin ierr = GmshReadString(gmsh, line, 2);CHKERRQ(ierr); 1016d6689ca9SLisandro Dalcin snum = sscanf(line, "%f %d", &version, &fileType); 1017d6689ca9SLisandro Dalcin if (snum != 2) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to parse Gmsh file header: %s", line); 1018d6689ca9SLisandro 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); 1019d6689ca9SLisandro Dalcin if ((int)version == 3) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Gmsh file version %3.1f not supported", (double)version); 1020d6689ca9SLisandro 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); 1021d6689ca9SLisandro Dalcin ierr = PetscViewerDestroy(&gmsh->viewer);CHKERRQ(ierr); 1022d6689ca9SLisandro Dalcin } 1023d6689ca9SLisandro Dalcin ierr = MPI_Bcast(&fileType, 1, MPI_INT, 0, comm);CHKERRQ(ierr); 1024d6689ca9SLisandro Dalcin vtype = (fileType == 0) ? PETSCVIEWERASCII : PETSCVIEWERBINARY; 1025d6689ca9SLisandro Dalcin 1026d6689ca9SLisandro Dalcin /* Create appropriate viewer and build plex */ 1027d6689ca9SLisandro Dalcin ierr = PetscViewerCreate(comm, &viewer);CHKERRQ(ierr); 1028d6689ca9SLisandro Dalcin ierr = PetscViewerSetType(viewer, vtype);CHKERRQ(ierr); 1029d6689ca9SLisandro Dalcin ierr = PetscViewerFileSetMode(viewer, FILE_MODE_READ);CHKERRQ(ierr); 1030d6689ca9SLisandro Dalcin ierr = PetscViewerFileSetName(viewer, filename);CHKERRQ(ierr); 1031d6689ca9SLisandro Dalcin ierr = DMPlexCreateGmsh(comm, viewer, interpolate, dm);CHKERRQ(ierr); 1032d6689ca9SLisandro Dalcin ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1033d6689ca9SLisandro Dalcin PetscFunctionReturn(0); 1034d6689ca9SLisandro Dalcin } 1035d6689ca9SLisandro Dalcin 1036331830f3SMatthew G. Knepley /*@ 10377d282ae0SMichael Lange DMPlexCreateGmsh - Create a DMPlex mesh from a Gmsh file viewer 1038331830f3SMatthew G. Knepley 1039d083f849SBarry Smith Collective 1040331830f3SMatthew G. Knepley 1041331830f3SMatthew G. Knepley Input Parameters: 1042331830f3SMatthew G. Knepley + comm - The MPI communicator 1043331830f3SMatthew G. Knepley . viewer - The Viewer associated with a Gmsh file 1044331830f3SMatthew G. Knepley - interpolate - Create faces and edges in the mesh 1045331830f3SMatthew G. Knepley 1046331830f3SMatthew G. Knepley Output Parameter: 1047331830f3SMatthew G. Knepley . dm - The DM object representing the mesh 1048331830f3SMatthew G. Knepley 1049698a79b9SLisandro Dalcin Note: http://gmsh.info/doc/texinfo/gmsh.html#MSH-file-format 1050331830f3SMatthew G. Knepley 1051331830f3SMatthew G. Knepley Level: beginner 1052331830f3SMatthew G. Knepley 1053331830f3SMatthew G. Knepley .seealso: DMPLEX, DMCreate() 1054331830f3SMatthew G. Knepley @*/ 1055331830f3SMatthew G. Knepley PetscErrorCode DMPlexCreateGmsh(MPI_Comm comm, PetscViewer viewer, PetscBool interpolate, DM *dm) 1056331830f3SMatthew G. Knepley { 105711c56cb0SLisandro Dalcin PetscViewer parentviewer = NULL; 105811c56cb0SLisandro Dalcin double *coordsIn = NULL; 1059730356f6SLisandro Dalcin GmshEntities *entities = NULL; 10603c67d5adSSatish Balay GmshElement *gmsh_elem = NULL; 1061331830f3SMatthew G. Knepley PetscSection coordSection; 1062331830f3SMatthew G. Knepley Vec coordinates; 10636fbe17bfSStefano Zampini PetscBT periodicV = NULL, periodicC = NULL; 106484572febSToby Isaac PetscScalar *coords; 1065412e9a14SMatthew G. Knepley PetscInt dim = 0, embedDim = -1, coordSize, c, v, d, cell, *periodicMap = NULL, *periodicMapI = NULL, *hybridMap = NULL; 1066698a79b9SLisandro Dalcin PetscInt numVertices = 0, numCells = 0, trueNumCells = 0; 1067698a79b9SLisandro Dalcin int i, shift = 1; 106811c56cb0SLisandro Dalcin PetscMPIInt rank; 1069ef12879bSLisandro Dalcin PetscBool binary, zerobase = PETSC_FALSE, usemarker = PETSC_FALSE; 10700db3fc9eSLisandro Dalcin PetscBool enable_hybrid = interpolate, periodic = PETSC_TRUE; 1071*96ca5757SLisandro Dalcin PetscBool hasTetra = PETSC_FALSE; 1072331830f3SMatthew G. Knepley PetscErrorCode ierr; 1073331830f3SMatthew G. Knepley 1074331830f3SMatthew G. Knepley PetscFunctionBegin; 1075331830f3SMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 1076ef12879bSLisandro Dalcin ierr = PetscObjectOptionsBegin((PetscObject)viewer);CHKERRQ(ierr); 1077ef12879bSLisandro Dalcin ierr = PetscOptionsHead(PetscOptionsObject,"DMPlex Gmsh options");CHKERRQ(ierr); 1078ef12879bSLisandro Dalcin ierr = PetscOptionsBool("-dm_plex_gmsh_hybrid", "Generate hybrid cell bounds", "DMPlexCreateGmsh", enable_hybrid, &enable_hybrid, NULL);CHKERRQ(ierr); 1079ef12879bSLisandro Dalcin ierr = PetscOptionsBool("-dm_plex_gmsh_periodic","Read Gmsh periodic section", "DMPlexCreateGmsh", periodic, &periodic, NULL);CHKERRQ(ierr); 1080ef12879bSLisandro Dalcin ierr = PetscOptionsBool("-dm_plex_gmsh_use_marker", "Generate marker label", "DMPlexCreateGmsh", usemarker, &usemarker, NULL);CHKERRQ(ierr); 1081ef12879bSLisandro Dalcin ierr = PetscOptionsBool("-dm_plex_gmsh_zero_base", "Read Gmsh file with zero base indices", "DMPlexCreateGmsh", zerobase, &zerobase, NULL);CHKERRQ(ierr); 10825a856986SBarry Smith ierr = PetscOptionsBoundedInt("-dm_plex_gmsh_spacedim", "Embedding space dimension", "DMPlexCreateGmsh", embedDim, &embedDim, NULL,PETSC_DECIDE);CHKERRQ(ierr); 1083ef12879bSLisandro Dalcin ierr = PetscOptionsTail();CHKERRQ(ierr); 1084ef12879bSLisandro Dalcin ierr = PetscOptionsEnd();CHKERRQ(ierr); 108511c56cb0SLisandro Dalcin if (zerobase) shift = 0; 108611c56cb0SLisandro Dalcin 1087331830f3SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 1088331830f3SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 10893b3bc66dSMichael Lange ierr = PetscLogEventBegin(DMPLEX_CreateGmsh,*dm,0,0,0);CHKERRQ(ierr); 109011c56cb0SLisandro Dalcin 109111c56cb0SLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &binary);CHKERRQ(ierr); 109211c56cb0SLisandro Dalcin 109311c56cb0SLisandro Dalcin /* Binary viewers read on all ranks, get subviewer to read only in rank 0 */ 10943b46f529SLisandro Dalcin if (binary) { 109511c56cb0SLisandro Dalcin parentviewer = viewer; 109611c56cb0SLisandro Dalcin ierr = PetscViewerGetSubViewer(parentviewer, PETSC_COMM_SELF, &viewer);CHKERRQ(ierr); 109711c56cb0SLisandro Dalcin } 109811c56cb0SLisandro Dalcin 10993b46f529SLisandro Dalcin if (!rank) { 1100698a79b9SLisandro Dalcin GmshFile gmsh_, *gmsh = &gmsh_; 1101698a79b9SLisandro Dalcin char line[PETSC_MAX_PATH_LEN]; 1102698a79b9SLisandro Dalcin PetscBool match; 1103331830f3SMatthew G. Knepley 1104580bdb30SBarry Smith ierr = PetscArrayzero(gmsh,1);CHKERRQ(ierr); 1105698a79b9SLisandro Dalcin gmsh->viewer = viewer; 1106698a79b9SLisandro Dalcin gmsh->binary = binary; 1107698a79b9SLisandro Dalcin 1108698a79b9SLisandro Dalcin /* Read mesh format */ 1109d6689ca9SLisandro Dalcin ierr = GmshReadSection(gmsh, line);CHKERRQ(ierr); 1110d6689ca9SLisandro Dalcin ierr = GmshExpect(gmsh, "$MeshFormat", line);CHKERRQ(ierr); 1111698a79b9SLisandro Dalcin ierr = DMPlexCreateGmsh_ReadMeshFormat(gmsh);CHKERRQ(ierr); 1112d6689ca9SLisandro Dalcin ierr = GmshReadEndSection(gmsh, "$EndMeshFormat", line);CHKERRQ(ierr); 111311c56cb0SLisandro Dalcin 1114dc0ede3bSMatthew G. Knepley /* OPTIONAL Read physical names */ 1115d6689ca9SLisandro Dalcin ierr = GmshReadSection(gmsh, line);CHKERRQ(ierr); 1116d6689ca9SLisandro Dalcin ierr = GmshMatch(gmsh,"$PhysicalNames", line, &match);CHKERRQ(ierr); 1117dc0ede3bSMatthew G. Knepley if (match) { 1118698a79b9SLisandro Dalcin ierr = DMPlexCreateGmsh_ReadPhysicalNames(gmsh);CHKERRQ(ierr); 1119d6689ca9SLisandro Dalcin ierr = GmshReadEndSection(gmsh, "$EndPhysicalNames", line);CHKERRQ(ierr); 1120698a79b9SLisandro Dalcin /* Initial read for entity section */ 1121d6689ca9SLisandro Dalcin ierr = GmshReadSection(gmsh, line);CHKERRQ(ierr); 1122dc0ede3bSMatthew G. Knepley } 112311c56cb0SLisandro Dalcin 1124de78e4feSLisandro Dalcin /* Read entities */ 1125698a79b9SLisandro Dalcin if (gmsh->fileFormat >= 40) { 1126d6689ca9SLisandro Dalcin ierr = GmshExpect(gmsh, "$Entities", line);CHKERRQ(ierr); 1127698a79b9SLisandro Dalcin switch (gmsh->fileFormat) { 1128698a79b9SLisandro Dalcin case 41: ierr = DMPlexCreateGmsh_ReadEntities_v41(gmsh, &entities);CHKERRQ(ierr); break; 1129698a79b9SLisandro Dalcin default: ierr = DMPlexCreateGmsh_ReadEntities_v40(gmsh, &entities);CHKERRQ(ierr); break; 1130698a79b9SLisandro Dalcin } 1131d6689ca9SLisandro Dalcin ierr = GmshReadEndSection(gmsh, "$EndEntities", line);CHKERRQ(ierr); 1132698a79b9SLisandro Dalcin /* Initial read for nodes section */ 1133d6689ca9SLisandro Dalcin ierr = GmshReadSection(gmsh, line);CHKERRQ(ierr); 1134de78e4feSLisandro Dalcin } 1135de78e4feSLisandro Dalcin 1136698a79b9SLisandro Dalcin /* Read nodes */ 1137d6689ca9SLisandro Dalcin ierr = GmshExpect(gmsh, "$Nodes", line);CHKERRQ(ierr); 1138698a79b9SLisandro Dalcin switch (gmsh->fileFormat) { 1139698a79b9SLisandro Dalcin case 41: ierr = DMPlexCreateGmsh_ReadNodes_v41(gmsh, shift, &numVertices, &coordsIn);CHKERRQ(ierr); break; 1140698a79b9SLisandro Dalcin case 40: ierr = DMPlexCreateGmsh_ReadNodes_v40(gmsh, shift, &numVertices, &coordsIn);CHKERRQ(ierr); break; 1141698a79b9SLisandro Dalcin default: ierr = DMPlexCreateGmsh_ReadNodes_v22(gmsh, shift, &numVertices, &coordsIn);CHKERRQ(ierr); break; 1142de78e4feSLisandro Dalcin } 1143d6689ca9SLisandro Dalcin ierr = GmshReadEndSection(gmsh, "$EndNodes", line);CHKERRQ(ierr); 114411c56cb0SLisandro Dalcin 1145698a79b9SLisandro Dalcin /* Read elements */ 1146feb237baSPierre Jolivet ierr = GmshReadSection(gmsh, line);CHKERRQ(ierr); 1147d6689ca9SLisandro Dalcin ierr = GmshExpect(gmsh, "$Elements", line);CHKERRQ(ierr); 1148698a79b9SLisandro Dalcin switch (gmsh->fileFormat) { 1149698a79b9SLisandro Dalcin case 41: ierr = DMPlexCreateGmsh_ReadElements_v41(gmsh, shift, entities, &numCells, &gmsh_elem);CHKERRQ(ierr); break; 1150698a79b9SLisandro Dalcin case 40: ierr = DMPlexCreateGmsh_ReadElements_v40(gmsh, shift, entities, &numCells, &gmsh_elem);CHKERRQ(ierr); break; 1151d6689ca9SLisandro Dalcin default: ierr = DMPlexCreateGmsh_ReadElements_v22(gmsh, shift, &numCells, &gmsh_elem);CHKERRQ(ierr); break; 1152de78e4feSLisandro Dalcin } 1153d6689ca9SLisandro Dalcin ierr = GmshReadEndSection(gmsh, "$EndElements", line);CHKERRQ(ierr); 1154de78e4feSLisandro Dalcin 1155698a79b9SLisandro Dalcin /* OPTIONAL Read periodic section */ 1156698a79b9SLisandro Dalcin if (periodic) { 1157ef12879bSLisandro Dalcin ierr = GmshReadSection(gmsh, line);CHKERRQ(ierr); 1158ef12879bSLisandro Dalcin ierr = GmshMatch(gmsh, "$Periodic", line, &periodic);CHKERRQ(ierr); 1159ef12879bSLisandro Dalcin } 1160ef12879bSLisandro Dalcin if (periodic) { 1161698a79b9SLisandro Dalcin PetscInt pVert, *periodicMapT, *aux; 1162de78e4feSLisandro Dalcin 1163698a79b9SLisandro Dalcin ierr = PetscMalloc1(numVertices, &periodicMapT);CHKERRQ(ierr); 1164698a79b9SLisandro Dalcin ierr = PetscBTCreate(numVertices, &periodicV);CHKERRQ(ierr); 1165698a79b9SLisandro Dalcin for (i = 0; i < numVertices; i++) periodicMapT[i] = i; 1166698a79b9SLisandro Dalcin 1167d6689ca9SLisandro Dalcin ierr = GmshExpect(gmsh, "$Periodic", line);CHKERRQ(ierr); 1168698a79b9SLisandro Dalcin switch (gmsh->fileFormat) { 1169698a79b9SLisandro Dalcin case 41: ierr = DMPlexCreateGmsh_ReadPeriodic_v41(gmsh, shift, periodicMapT, periodicV);CHKERRQ(ierr); break; 1170698a79b9SLisandro Dalcin default: ierr = DMPlexCreateGmsh_ReadPeriodic_v40(gmsh, shift, periodicMapT, periodicV);CHKERRQ(ierr); break; 1171698a79b9SLisandro Dalcin } 1172d6689ca9SLisandro Dalcin ierr = GmshReadEndSection(gmsh, "$EndPeriodic", line);CHKERRQ(ierr); 1173698a79b9SLisandro Dalcin 1174698a79b9SLisandro Dalcin /* we may have slaves of slaves */ 1175698a79b9SLisandro Dalcin for (i = 0; i < numVertices; i++) { 1176698a79b9SLisandro Dalcin while (periodicMapT[periodicMapT[i]] != periodicMapT[i]) { 1177698a79b9SLisandro Dalcin periodicMapT[i] = periodicMapT[periodicMapT[i]]; 1178698a79b9SLisandro Dalcin } 1179698a79b9SLisandro Dalcin } 1180698a79b9SLisandro Dalcin /* periodicMap : from old to new numbering (periodic vertices excluded) 1181698a79b9SLisandro Dalcin periodicMapI: from new to old numbering */ 1182698a79b9SLisandro Dalcin ierr = PetscMalloc1(numVertices, &periodicMap);CHKERRQ(ierr); 1183698a79b9SLisandro Dalcin ierr = PetscMalloc1(numVertices, &periodicMapI);CHKERRQ(ierr); 1184698a79b9SLisandro Dalcin ierr = PetscMalloc1(numVertices, &aux);CHKERRQ(ierr); 1185698a79b9SLisandro Dalcin for (i = 0, pVert = 0; i < numVertices; i++) { 1186698a79b9SLisandro Dalcin if (periodicMapT[i] != i) { 1187698a79b9SLisandro Dalcin pVert++; 1188698a79b9SLisandro Dalcin } else { 1189698a79b9SLisandro Dalcin aux[i] = i - pVert; 1190698a79b9SLisandro Dalcin periodicMapI[i - pVert] = i; 1191698a79b9SLisandro Dalcin } 1192698a79b9SLisandro Dalcin } 1193698a79b9SLisandro Dalcin for (i = 0 ; i < numVertices; i++) { 1194698a79b9SLisandro Dalcin periodicMap[i] = aux[periodicMapT[i]]; 1195698a79b9SLisandro Dalcin } 1196698a79b9SLisandro Dalcin ierr = PetscFree(periodicMapT);CHKERRQ(ierr); 1197698a79b9SLisandro Dalcin ierr = PetscFree(aux);CHKERRQ(ierr); 1198698a79b9SLisandro Dalcin /* remove periodic vertices */ 1199698a79b9SLisandro Dalcin numVertices = numVertices - pVert; 1200698a79b9SLisandro Dalcin } 1201698a79b9SLisandro Dalcin 1202698a79b9SLisandro Dalcin ierr = GmshEntitiesDestroy(&entities);CHKERRQ(ierr); 1203698a79b9SLisandro Dalcin ierr = PetscFree(gmsh->wbuf);CHKERRQ(ierr); 1204698a79b9SLisandro Dalcin ierr = PetscFree(gmsh->sbuf);CHKERRQ(ierr); 1205698a79b9SLisandro Dalcin } 1206698a79b9SLisandro Dalcin 1207698a79b9SLisandro Dalcin if (parentviewer) { 1208698a79b9SLisandro Dalcin ierr = PetscViewerRestoreSubViewer(parentviewer, PETSC_COMM_SELF, &viewer);CHKERRQ(ierr); 1209698a79b9SLisandro Dalcin } 1210698a79b9SLisandro Dalcin 1211698a79b9SLisandro Dalcin if (!rank) { 1212698a79b9SLisandro Dalcin PetscBool hybrid = PETSC_FALSE; 12130db3fc9eSLisandro Dalcin PetscInt cellType = -1; 1214698a79b9SLisandro Dalcin 1215a4bb7517SMichael Lange for (trueNumCells = 0, c = 0; c < numCells; ++c) { 12160db3fc9eSLisandro Dalcin if (gmsh_elem[c].dim > dim) {dim = gmsh_elem[c].dim; trueNumCells = 0; hybrid = PETSC_FALSE; cellType = -1;} 12170db3fc9eSLisandro Dalcin if (gmsh_elem[c].dim < dim) continue; 12180db3fc9eSLisandro Dalcin if (cellType == -1) cellType = gmsh_elem[c].cellType; 12190db3fc9eSLisandro Dalcin /* different cell type indicate an hybrid mesh in PLEX */ 12200db3fc9eSLisandro Dalcin if (cellType != gmsh_elem[c].cellType) hybrid = PETSC_TRUE; 1221dea2a3c7SStefano Zampini /* wedges always indicate an hybrid mesh in PLEX */ 12220db3fc9eSLisandro Dalcin if (cellType == 6 || cellType == 13) hybrid = PETSC_TRUE; 1223*96ca5757SLisandro Dalcin if (cellType == 4 || cellType == 11) hasTetra = PETSC_TRUE; 12240db3fc9eSLisandro Dalcin trueNumCells++; 1225db397164SMichael Lange } 1226dea2a3c7SStefano Zampini /* Renumber cells for hybrid grids */ 1227dea2a3c7SStefano Zampini if (hybrid && enable_hybrid) { 1228dea2a3c7SStefano Zampini PetscInt hc1 = 0, hc2 = 0, *hybridCells1 = NULL, *hybridCells2 = NULL; 1229dea2a3c7SStefano Zampini PetscInt cell, tn, *tp; 1230dea2a3c7SStefano Zampini int n1 = 0,n2 = 0; 1231dea2a3c7SStefano Zampini 1232dea2a3c7SStefano Zampini ierr = PetscMalloc1(trueNumCells, &hybridCells1);CHKERRQ(ierr); 1233dea2a3c7SStefano Zampini ierr = PetscMalloc1(trueNumCells, &hybridCells2);CHKERRQ(ierr); 1234dea2a3c7SStefano Zampini for (cell = 0, c = 0; c < numCells; ++c) { 1235dea2a3c7SStefano Zampini if (gmsh_elem[c].dim == dim) { 1236dea2a3c7SStefano Zampini if (!n1) n1 = gmsh_elem[c].cellType; 1237dea2a3c7SStefano Zampini else if (!n2 && n1 != gmsh_elem[c].cellType) n2 = gmsh_elem[c].cellType; 1238dea2a3c7SStefano Zampini 1239dea2a3c7SStefano Zampini if (gmsh_elem[c].cellType == n1) hybridCells1[hc1++] = cell; 1240dea2a3c7SStefano Zampini else if (gmsh_elem[c].cellType == n2) hybridCells2[hc2++] = cell; 1241dea2a3c7SStefano Zampini else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle more than 2 cell types"); 1242dea2a3c7SStefano Zampini cell++; 1243dea2a3c7SStefano Zampini } 1244dea2a3c7SStefano Zampini } 1245dea2a3c7SStefano Zampini 1246dea2a3c7SStefano Zampini switch (n1) { 1247dea2a3c7SStefano Zampini case 2: /* triangles */ 1248dea2a3c7SStefano Zampini case 9: 1249dea2a3c7SStefano Zampini switch (n2) { 1250dea2a3c7SStefano Zampini case 0: /* single type mesh */ 1251dea2a3c7SStefano Zampini case 3: /* quads */ 1252dea2a3c7SStefano Zampini case 10: 1253dea2a3c7SStefano Zampini break; 1254dea2a3c7SStefano Zampini default: 1255dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1256dea2a3c7SStefano Zampini } 1257dea2a3c7SStefano Zampini break; 1258a5b208b6SMatthew G. Knepley case 3: /* quadrilateral */ 1259dea2a3c7SStefano Zampini case 10: 1260dea2a3c7SStefano Zampini switch (n2) { 1261dea2a3c7SStefano Zampini case 0: /* single type mesh */ 1262dea2a3c7SStefano Zampini case 2: /* swap since we list simplices first */ 1263dea2a3c7SStefano Zampini case 9: 1264dea2a3c7SStefano Zampini tn = hc1; 1265dea2a3c7SStefano Zampini hc1 = hc2; 1266dea2a3c7SStefano Zampini hc2 = tn; 1267dea2a3c7SStefano Zampini 1268dea2a3c7SStefano Zampini tp = hybridCells1; 1269dea2a3c7SStefano Zampini hybridCells1 = hybridCells2; 1270dea2a3c7SStefano Zampini hybridCells2 = tp; 1271dea2a3c7SStefano Zampini break; 1272dea2a3c7SStefano Zampini default: 1273dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1274dea2a3c7SStefano Zampini } 1275dea2a3c7SStefano Zampini break; 1276dea2a3c7SStefano Zampini case 4: /* tetrahedra */ 1277dea2a3c7SStefano Zampini case 11: 1278dea2a3c7SStefano Zampini switch (n2) { 1279dea2a3c7SStefano Zampini case 0: /* single type mesh */ 1280dea2a3c7SStefano Zampini case 6: /* wedges */ 1281dea2a3c7SStefano Zampini case 13: 1282dea2a3c7SStefano Zampini break; 1283dea2a3c7SStefano Zampini default: 1284dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1285dea2a3c7SStefano Zampini } 1286dea2a3c7SStefano Zampini break; 1287a5b208b6SMatthew G. Knepley case 5: /* hexahedra */ 1288a5b208b6SMatthew G. Knepley case 12: 1289a5b208b6SMatthew G. Knepley switch (n2) { 1290a5b208b6SMatthew G. Knepley case 0: /* single type mesh */ 1291a5b208b6SMatthew G. Knepley case 6: /* wedges */ 1292a5b208b6SMatthew G. Knepley case 13: 1293a5b208b6SMatthew G. Knepley break; 1294a5b208b6SMatthew G. Knepley default: 1295a5b208b6SMatthew G. Knepley SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1296a5b208b6SMatthew G. Knepley } 1297a5b208b6SMatthew G. Knepley break; 1298a5b208b6SMatthew G. Knepley case 6: /* wedge */ 1299dea2a3c7SStefano Zampini case 13: 1300dea2a3c7SStefano Zampini switch (n2) { 1301dea2a3c7SStefano Zampini case 0: /* single type mesh */ 1302a5b208b6SMatthew G. Knepley case 4: /* tetrahedra: swap since we list simplices first */ 1303dea2a3c7SStefano Zampini case 11: 1304a5b208b6SMatthew G. Knepley case 5: /* hexahedra */ 1305a5b208b6SMatthew G. Knepley case 12: 1306dea2a3c7SStefano Zampini tn = hc1; 1307dea2a3c7SStefano Zampini hc1 = hc2; 1308dea2a3c7SStefano Zampini hc2 = tn; 1309dea2a3c7SStefano Zampini 1310dea2a3c7SStefano Zampini tp = hybridCells1; 1311dea2a3c7SStefano Zampini hybridCells1 = hybridCells2; 1312dea2a3c7SStefano Zampini hybridCells2 = tp; 1313dea2a3c7SStefano Zampini break; 1314dea2a3c7SStefano Zampini default: 1315dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1316dea2a3c7SStefano Zampini } 1317dea2a3c7SStefano Zampini break; 1318dea2a3c7SStefano Zampini default: 1319dea2a3c7SStefano Zampini SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unsupported cell types %d and %d",n1, n2); 1320dea2a3c7SStefano Zampini } 1321dea2a3c7SStefano Zampini ierr = PetscMalloc1(trueNumCells, &hybridMap);CHKERRQ(ierr); 1322dea2a3c7SStefano Zampini for (cell = 0; cell < hc1; cell++) hybridMap[hybridCells1[cell]] = cell; 1323dea2a3c7SStefano Zampini for (cell = 0; cell < hc2; cell++) hybridMap[hybridCells2[cell]] = cell + hc1; 1324dea2a3c7SStefano Zampini ierr = PetscFree(hybridCells1);CHKERRQ(ierr); 1325dea2a3c7SStefano Zampini ierr = PetscFree(hybridCells2);CHKERRQ(ierr); 1326dea2a3c7SStefano Zampini } 1327dea2a3c7SStefano Zampini 132811c56cb0SLisandro Dalcin } 132911c56cb0SLisandro Dalcin 1330a4bb7517SMichael Lange /* Allocate the cell-vertex mesh */ 1331412e9a14SMatthew G. Knepley /* We do not want this label automatically computed, instead we compute it here */ 1332412e9a14SMatthew G. Knepley ierr = DMCreateLabel(*dm, "celltype");CHKERRQ(ierr); 1333db397164SMichael Lange ierr = DMPlexSetChart(*dm, 0, trueNumCells+numVertices);CHKERRQ(ierr); 1334a4bb7517SMichael Lange for (cell = 0, c = 0; c < numCells; ++c) { 1335a4bb7517SMichael Lange if (gmsh_elem[c].dim == dim) { 1336*96ca5757SLisandro Dalcin PetscInt ucell = hybridMap ? hybridMap[cell] : cell; 1337*96ca5757SLisandro Dalcin DMPolytopeType ctype = DMPolytopeTypeFromGmsh(gmsh_elem[c].cellType); 1338*96ca5757SLisandro Dalcin if (hybridMap && hasTetra && ctype == DM_POLYTOPE_TRI_PRISM) ctype = DM_POLYTOPE_TRI_PRISM_TENSOR; 1339*96ca5757SLisandro Dalcin ierr = DMPlexSetConeSize(*dm, ucell, gmsh_elem[c].numNodes);CHKERRQ(ierr); 1340*96ca5757SLisandro Dalcin ierr = DMPlexSetCellType(*dm, ucell, ctype);CHKERRQ(ierr); 1341a4bb7517SMichael Lange cell++; 1342db397164SMichael Lange } 1343331830f3SMatthew G. Knepley } 1344*96ca5757SLisandro Dalcin for (v = trueNumCells; v < trueNumCells+numVertices; ++v) { 1345*96ca5757SLisandro Dalcin ierr = DMPlexSetCellType(*dm, v, DM_POLYTOPE_POINT);CHKERRQ(ierr); 1346*96ca5757SLisandro Dalcin } 1347331830f3SMatthew G. Knepley ierr = DMSetUp(*dm);CHKERRQ(ierr); 1348*96ca5757SLisandro Dalcin 1349a4bb7517SMichael Lange /* Add cell-vertex connections */ 1350a4bb7517SMichael Lange for (cell = 0, c = 0; c < numCells; ++c) { 1351a4bb7517SMichael Lange if (gmsh_elem[c].dim == dim) { 135211c56cb0SLisandro Dalcin PetscInt pcone[8], corner; 1353*96ca5757SLisandro Dalcin PetscInt ucell = hybridMap ? hybridMap[cell] : cell; 1354a4bb7517SMichael Lange for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) { 1355dd169d64SMatthew G. Knepley const PetscInt cc = gmsh_elem[c].nodes[corner] - shift; 1356917266a4SLisandro Dalcin pcone[corner] = (periodicMap ? periodicMap[cc] : cc) + trueNumCells; 1357db397164SMichael Lange } 1358*96ca5757SLisandro Dalcin ierr = DMPlexReorderCell(*dm, ucell, pcone);CHKERRQ(ierr); 1359*96ca5757SLisandro Dalcin ierr = DMPlexSetCone(*dm, ucell, pcone);CHKERRQ(ierr); 1360a4bb7517SMichael Lange cell++; 1361331830f3SMatthew G. Knepley } 1362a4bb7517SMichael Lange } 1363*96ca5757SLisandro Dalcin 13646228fc9fSJed Brown ierr = MPI_Bcast(&dim, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 1365c73cfb54SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 1366331830f3SMatthew G. Knepley ierr = DMPlexSymmetrize(*dm);CHKERRQ(ierr); 1367331830f3SMatthew G. Knepley ierr = DMPlexStratify(*dm);CHKERRQ(ierr); 1368331830f3SMatthew G. Knepley if (interpolate) { 13695fd9971aSMatthew G. Knepley DM idm; 1370331830f3SMatthew G. Knepley 1371331830f3SMatthew G. Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 1372331830f3SMatthew G. Knepley ierr = DMDestroy(dm);CHKERRQ(ierr); 1373331830f3SMatthew G. Knepley *dm = idm; 1374331830f3SMatthew G. Knepley } 1375917266a4SLisandro Dalcin 1376f6c8a31fSLisandro Dalcin if (usemarker && !interpolate && dim > 1) SETERRQ(comm,PETSC_ERR_SUP,"Cannot create marker label without interpolation"); 1377917266a4SLisandro Dalcin if (!rank && usemarker) { 1378d3f73514SStefano Zampini PetscInt f, fStart, fEnd; 1379d3f73514SStefano Zampini 1380d3f73514SStefano Zampini ierr = DMCreateLabel(*dm, "marker");CHKERRQ(ierr); 1381d3f73514SStefano Zampini ierr = DMPlexGetHeightStratum(*dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1382d3f73514SStefano Zampini for (f = fStart; f < fEnd; ++f) { 1383d3f73514SStefano Zampini PetscInt suppSize; 1384d3f73514SStefano Zampini 1385d3f73514SStefano Zampini ierr = DMPlexGetSupportSize(*dm, f, &suppSize);CHKERRQ(ierr); 1386d3f73514SStefano Zampini if (suppSize == 1) { 1387d3f73514SStefano Zampini PetscInt *cone = NULL, coneSize, p; 1388d3f73514SStefano Zampini 1389d3f73514SStefano Zampini ierr = DMPlexGetTransitiveClosure(*dm, f, PETSC_TRUE, &coneSize, &cone);CHKERRQ(ierr); 1390d3f73514SStefano Zampini for (p = 0; p < coneSize; p += 2) { 1391d3f73514SStefano Zampini ierr = DMSetLabelValue(*dm, "marker", cone[p], 1);CHKERRQ(ierr); 1392d3f73514SStefano Zampini } 1393d3f73514SStefano Zampini ierr = DMPlexRestoreTransitiveClosure(*dm, f, PETSC_TRUE, &coneSize, &cone);CHKERRQ(ierr); 1394d3f73514SStefano Zampini } 1395d3f73514SStefano Zampini } 1396d3f73514SStefano Zampini } 139716ad7e67SMichael Lange 139816ad7e67SMichael Lange if (!rank) { 139911c56cb0SLisandro Dalcin PetscInt vStart, vEnd; 1400d1a54cefSMatthew G. Knepley 140116ad7e67SMichael Lange ierr = DMPlexGetDepthStratum(*dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 140211c56cb0SLisandro Dalcin for (cell = 0, c = 0; c < numCells; ++c) { 140311c56cb0SLisandro Dalcin 140411c56cb0SLisandro Dalcin /* Create face sets */ 14055964b3dcSLisandro Dalcin if (interpolate && gmsh_elem[c].dim == dim-1) { 140616ad7e67SMichael Lange const PetscInt *join; 140711c56cb0SLisandro Dalcin PetscInt joinSize, pcone[8], corner; 140811c56cb0SLisandro Dalcin /* Find the relevant facet with vertex joins */ 1409a4bb7517SMichael Lange for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) { 1410dd169d64SMatthew G. Knepley const PetscInt cc = gmsh_elem[c].nodes[corner] - shift; 1411917266a4SLisandro Dalcin pcone[corner] = (periodicMap ? periodicMap[cc] : cc) + vStart; 141216ad7e67SMichael Lange } 141311c56cb0SLisandro Dalcin ierr = DMPlexGetFullJoin(*dm, gmsh_elem[c].numNodes, pcone, &joinSize, &join);CHKERRQ(ierr); 1414f10f1c67SMatthew 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); 1415c58f1c22SToby Isaac ierr = DMSetLabelValue(*dm, "Face Sets", join[0], gmsh_elem[c].tags[0]);CHKERRQ(ierr); 1416a4bb7517SMichael Lange ierr = DMPlexRestoreJoin(*dm, gmsh_elem[c].numNodes, (const PetscInt *) pcone, &joinSize, &join);CHKERRQ(ierr); 141716ad7e67SMichael Lange } 14186e1dd89aSLawrence Mitchell 14196e1dd89aSLawrence Mitchell /* Create cell sets */ 14206e1dd89aSLawrence Mitchell if (gmsh_elem[c].dim == dim) { 14216e1dd89aSLawrence Mitchell if (gmsh_elem[c].numTags > 0) { 1422dea2a3c7SStefano Zampini ierr = DMSetLabelValue(*dm, "Cell Sets", hybridMap ? hybridMap[cell] : cell, gmsh_elem[c].tags[0]);CHKERRQ(ierr); 14236e1dd89aSLawrence Mitchell } 1424917266a4SLisandro Dalcin cell++; 14256e1dd89aSLawrence Mitchell } 14260c070f12SSander Arens 14270c070f12SSander Arens /* Create vertex sets */ 14280c070f12SSander Arens if (gmsh_elem[c].dim == 0) { 14290c070f12SSander Arens if (gmsh_elem[c].numTags > 0) { 1430917266a4SLisandro Dalcin const PetscInt cc = gmsh_elem[c].nodes[0] - shift; 143111c56cb0SLisandro Dalcin const PetscInt vid = (periodicMap ? periodicMap[cc] : cc) + vStart; 1432d08df55aSStefano Zampini ierr = DMSetLabelValue(*dm, "Vertex Sets", vid, gmsh_elem[c].tags[0]);CHKERRQ(ierr); 14330c070f12SSander Arens } 14340c070f12SSander Arens } 14350c070f12SSander Arens } 143616ad7e67SMichael Lange } 143716ad7e67SMichael Lange 143811c56cb0SLisandro Dalcin /* Create coordinates */ 1439dea2a3c7SStefano Zampini if (embedDim < 0) embedDim = dim; 1440dea2a3c7SStefano Zampini ierr = DMSetCoordinateDim(*dm, embedDim);CHKERRQ(ierr); 1441979c4b60SMatthew G. Knepley ierr = DMGetCoordinateSection(*dm, &coordSection);CHKERRQ(ierr); 1442331830f3SMatthew G. Knepley ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 14431d64f2ccSMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, embedDim);CHKERRQ(ierr); 1444f45c9589SStefano Zampini if (periodicMap) { /* we need to localize coordinates on cells */ 1445f45c9589SStefano Zampini ierr = PetscSectionSetChart(coordSection, 0, trueNumCells + numVertices);CHKERRQ(ierr); 1446f45c9589SStefano Zampini } else { 144775b5763bSMichael Lange ierr = PetscSectionSetChart(coordSection, trueNumCells, trueNumCells + numVertices);CHKERRQ(ierr); 1448f45c9589SStefano Zampini } 144975b5763bSMichael Lange for (v = trueNumCells; v < trueNumCells+numVertices; ++v) { 14501d64f2ccSMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, embedDim);CHKERRQ(ierr); 14511d64f2ccSMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, embedDim);CHKERRQ(ierr); 1452331830f3SMatthew G. Knepley } 145311c56cb0SLisandro Dalcin if (periodicMap) { 1454437bdd5bSStefano Zampini ierr = PetscBTCreate(trueNumCells, &periodicC);CHKERRQ(ierr); 1455f45c9589SStefano Zampini for (cell = 0, c = 0; c < numCells; ++c) { 1456f45c9589SStefano Zampini if (gmsh_elem[c].dim == dim) { 1457*96ca5757SLisandro Dalcin PetscInt corner, pc = PETSC_FALSE; 1458437bdd5bSStefano Zampini for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) { 1459917266a4SLisandro Dalcin pc = (PetscBool)(pc || PetscBTLookup(periodicV, gmsh_elem[c].nodes[corner] - shift)); 1460437bdd5bSStefano Zampini } 1461437bdd5bSStefano Zampini if (pc) { 146211c56cb0SLisandro Dalcin PetscInt dof = gmsh_elem[c].numNodes*embedDim; 1463dea2a3c7SStefano Zampini PetscInt ucell = hybridMap ? hybridMap[cell] : cell; 1464dea2a3c7SStefano Zampini ierr = PetscBTSet(periodicC, ucell);CHKERRQ(ierr); 1465dea2a3c7SStefano Zampini ierr = PetscSectionSetDof(coordSection, ucell, dof);CHKERRQ(ierr); 1466dea2a3c7SStefano Zampini ierr = PetscSectionSetFieldDof(coordSection, ucell, 0, dof);CHKERRQ(ierr); 14676fbe17bfSStefano Zampini } 1468f45c9589SStefano Zampini cell++; 1469f45c9589SStefano Zampini } 1470f45c9589SStefano Zampini } 1471f45c9589SStefano Zampini } 1472331830f3SMatthew G. Knepley ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 1473331830f3SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 14748b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 1475331830f3SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 1476331830f3SMatthew G. Knepley ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 14771d64f2ccSMatthew G. Knepley ierr = VecSetBlockSize(coordinates, embedDim);CHKERRQ(ierr); 1478331830f3SMatthew G. Knepley ierr = VecSetType(coordinates, VECSTANDARD);CHKERRQ(ierr); 1479331830f3SMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 1480f45c9589SStefano Zampini if (periodicMap) { 1481f45c9589SStefano Zampini PetscInt off; 1482f45c9589SStefano Zampini 1483f45c9589SStefano Zampini for (cell = 0, c = 0; c < numCells; ++c) { 1484f45c9589SStefano Zampini if (gmsh_elem[c].dim == dim) { 1485*96ca5757SLisandro Dalcin PetscInt pcone[8], corner; 1486dea2a3c7SStefano Zampini PetscInt ucell = hybridMap ? hybridMap[cell] : cell; 1487dea2a3c7SStefano Zampini if (PetscUnlikely(PetscBTLookup(periodicC, ucell))) { 1488f45c9589SStefano Zampini for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) { 1489917266a4SLisandro Dalcin pcone[corner] = gmsh_elem[c].nodes[corner] - shift; 1490f45c9589SStefano Zampini } 1491*96ca5757SLisandro Dalcin ierr = DMPlexReorderCell(*dm, ucell, pcone);CHKERRQ(ierr); 1492dea2a3c7SStefano Zampini ierr = PetscSectionGetOffset(coordSection, ucell, &off);CHKERRQ(ierr); 1493*96ca5757SLisandro Dalcin for (corner = 0; corner < gmsh_elem[c].numNodes; ++corner) 1494*96ca5757SLisandro Dalcin for (v = pcone[corner], d = 0; d < embedDim; ++d) 149511c56cb0SLisandro Dalcin coords[off++] = (PetscReal) coordsIn[v*3+d]; 1496f45c9589SStefano 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