1d9deefdfSMatthew G. Knepley #include <petsc-private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2d9deefdfSMatthew G. Knepley 3d9deefdfSMatthew G. Knepley #undef __FUNCT__ 4d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexInvertCell_Internal" 5d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexInvertCell_Internal(PetscInt dim, PetscInt numCorners, PetscInt cone[]) 6d9deefdfSMatthew G. Knepley { 7d9deefdfSMatthew G. Knepley int tmpc; 8d9deefdfSMatthew G. Knepley 9d9deefdfSMatthew G. Knepley PetscFunctionBegin; 10d9deefdfSMatthew G. Knepley if (dim != 3) PetscFunctionReturn(0); 11d9deefdfSMatthew G. Knepley switch (numCorners) { 12d9deefdfSMatthew G. Knepley case 4: 13d9deefdfSMatthew G. Knepley tmpc = cone[0]; 14d9deefdfSMatthew G. Knepley cone[0] = cone[1]; 15d9deefdfSMatthew G. Knepley cone[1] = tmpc; 16d9deefdfSMatthew G. Knepley break; 17d9deefdfSMatthew G. Knepley case 8: 18d9deefdfSMatthew G. Knepley tmpc = cone[1]; 19d9deefdfSMatthew G. Knepley cone[1] = cone[3]; 20d9deefdfSMatthew G. Knepley cone[3] = tmpc; 21d9deefdfSMatthew G. Knepley break; 22d9deefdfSMatthew G. Knepley default: break; 23d9deefdfSMatthew G. Knepley } 24d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 25d9deefdfSMatthew G. Knepley } 26d9deefdfSMatthew G. Knepley 27d9deefdfSMatthew G. Knepley #undef __FUNCT__ 28d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexInvertCell" 29d9deefdfSMatthew G. Knepley /*@C 30d9deefdfSMatthew G. Knepley DMPlexInvertCell - This flips tetrahedron and hexahedron orientation since Plex stores them internally with outward normals. Other cells are left untouched. 31d9deefdfSMatthew G. Knepley 32d9deefdfSMatthew G. Knepley Input Parameters: 33d9deefdfSMatthew G. Knepley + numCorners - The number of vertices in a cell 34d9deefdfSMatthew G. Knepley - cone - The incoming cone 35d9deefdfSMatthew G. Knepley 36d9deefdfSMatthew G. Knepley Output Parameter: 37d9deefdfSMatthew G. Knepley . cone - The inverted cone (in-place) 38d9deefdfSMatthew G. Knepley 39d9deefdfSMatthew G. Knepley Level: developer 40d9deefdfSMatthew G. Knepley 41d9deefdfSMatthew G. Knepley .seealso: DMPlexGenerate() 42d9deefdfSMatthew G. Knepley @*/ 43d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexInvertCell(PetscInt dim, PetscInt numCorners, int cone[]) 44d9deefdfSMatthew G. Knepley { 45d9deefdfSMatthew G. Knepley int tmpc; 46d9deefdfSMatthew G. Knepley 47d9deefdfSMatthew G. Knepley PetscFunctionBegin; 48d9deefdfSMatthew G. Knepley if (dim != 3) PetscFunctionReturn(0); 49d9deefdfSMatthew G. Knepley switch (numCorners) { 50d9deefdfSMatthew G. Knepley case 4: 51d9deefdfSMatthew G. Knepley tmpc = cone[0]; 52d9deefdfSMatthew G. Knepley cone[0] = cone[1]; 53d9deefdfSMatthew G. Knepley cone[1] = tmpc; 54d9deefdfSMatthew G. Knepley break; 55d9deefdfSMatthew G. Knepley case 8: 56d9deefdfSMatthew G. Knepley tmpc = cone[1]; 57d9deefdfSMatthew G. Knepley cone[1] = cone[3]; 58d9deefdfSMatthew G. Knepley cone[3] = tmpc; 59d9deefdfSMatthew G. Knepley break; 60d9deefdfSMatthew G. Knepley default: break; 61d9deefdfSMatthew G. Knepley } 62d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 63d9deefdfSMatthew G. Knepley } 64d9deefdfSMatthew G. Knepley 65d9deefdfSMatthew G. Knepley #undef __FUNCT__ 66d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexInvertCells_Internal" 67d9deefdfSMatthew G. Knepley /* This is to fix the tetrahedron orientation from TetGen */ 68d9deefdfSMatthew G. Knepley PETSC_UNUSED static PetscErrorCode DMPlexInvertCells_Internal(PetscInt dim, PetscInt numCells, PetscInt numCorners, int cells[]) 69d9deefdfSMatthew G. Knepley { 70d9deefdfSMatthew G. Knepley PetscInt bound = numCells*numCorners, coff; 71d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 72d9deefdfSMatthew G. Knepley 73d9deefdfSMatthew G. Knepley PetscFunctionBegin; 74d9deefdfSMatthew G. Knepley for (coff = 0; coff < bound; coff += numCorners) { 75d9deefdfSMatthew G. Knepley ierr = DMPlexInvertCell(dim, numCorners, &cells[coff]);CHKERRQ(ierr); 76d9deefdfSMatthew G. Knepley } 77d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 78d9deefdfSMatthew G. Knepley } 79d9deefdfSMatthew G. Knepley 80d9deefdfSMatthew G. Knepley #undef __FUNCT__ 81d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexTriangleSetOptions" 82d9deefdfSMatthew G. Knepley /*@ 83d9deefdfSMatthew G. Knepley DMPlexTriangleSetOptions - Set the options used for the Triangle mesh generator 84d9deefdfSMatthew G. Knepley 85d9deefdfSMatthew G. Knepley Not Collective 86d9deefdfSMatthew G. Knepley 87d9deefdfSMatthew G. Knepley Inputs Parameters: 88d9deefdfSMatthew G. Knepley + dm - The DMPlex object 89d9deefdfSMatthew G. Knepley - opts - The command line options 90d9deefdfSMatthew G. Knepley 91d9deefdfSMatthew G. Knepley Level: developer 92d9deefdfSMatthew G. Knepley 93d9deefdfSMatthew G. Knepley .keywords: mesh, points 94d9deefdfSMatthew G. Knepley .seealso: DMPlexTetgenSetOptions(), DMPlexGenerate() 95d9deefdfSMatthew G. Knepley @*/ 96d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexTriangleSetOptions(DM dm, const char *opts) 97d9deefdfSMatthew G. Knepley { 98d9deefdfSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 99d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 100d9deefdfSMatthew G. Knepley 101d9deefdfSMatthew G. Knepley PetscFunctionBegin; 102d9deefdfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 103d9deefdfSMatthew G. Knepley PetscValidPointer(opts, 2); 104*606ac3a5SMatthew G. Knepley ierr = PetscFree(mesh->triangleOpts);CHKERRQ(ierr); 105*606ac3a5SMatthew G. Knepley ierr = PetscStrallocpy(opts, &mesh->triangleOpts);CHKERRQ(ierr); 106d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 107d9deefdfSMatthew G. Knepley } 108d9deefdfSMatthew G. Knepley 109d9deefdfSMatthew G. Knepley #undef __FUNCT__ 110d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexTetgenSetOptions" 111d9deefdfSMatthew G. Knepley /*@ 112d9deefdfSMatthew G. Knepley DMPlexTetgenSetOptions - Set the options used for the Tetgen mesh generator 113d9deefdfSMatthew G. Knepley 114d9deefdfSMatthew G. Knepley Not Collective 115d9deefdfSMatthew G. Knepley 116d9deefdfSMatthew G. Knepley Inputs Parameters: 117d9deefdfSMatthew G. Knepley + dm - The DMPlex object 118d9deefdfSMatthew G. Knepley - opts - The command line options 119d9deefdfSMatthew G. Knepley 120d9deefdfSMatthew G. Knepley Level: developer 121d9deefdfSMatthew G. Knepley 122d9deefdfSMatthew G. Knepley .keywords: mesh, points 123d9deefdfSMatthew G. Knepley .seealso: DMPlexTriangleSetOptions(), DMPlexGenerate() 124d9deefdfSMatthew G. Knepley @*/ 125d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexTetgenSetOptions(DM dm, const char *opts) 126d9deefdfSMatthew G. Knepley { 127d9deefdfSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 128d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 129d9deefdfSMatthew G. Knepley 130d9deefdfSMatthew G. Knepley PetscFunctionBegin; 131d9deefdfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 132d9deefdfSMatthew G. Knepley PetscValidPointer(opts, 2); 133*606ac3a5SMatthew G. Knepley ierr = PetscFree(mesh->tetgenOpts);CHKERRQ(ierr); 134*606ac3a5SMatthew G. Knepley ierr = PetscStrallocpy(opts, &mesh->tetgenOpts);CHKERRQ(ierr); 135d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 136d9deefdfSMatthew G. Knepley } 137d9deefdfSMatthew G. Knepley 138d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TRIANGLE) 139d9deefdfSMatthew G. Knepley #include <triangle.h> 140d9deefdfSMatthew G. Knepley 141d9deefdfSMatthew G. Knepley #undef __FUNCT__ 142d9deefdfSMatthew G. Knepley #define __FUNCT__ "InitInput_Triangle" 143d9deefdfSMatthew G. Knepley PetscErrorCode InitInput_Triangle(struct triangulateio *inputCtx) 144d9deefdfSMatthew G. Knepley { 145d9deefdfSMatthew G. Knepley PetscFunctionBegin; 146d9deefdfSMatthew G. Knepley inputCtx->numberofpoints = 0; 147d9deefdfSMatthew G. Knepley inputCtx->numberofpointattributes = 0; 148d9deefdfSMatthew G. Knepley inputCtx->pointlist = NULL; 149d9deefdfSMatthew G. Knepley inputCtx->pointattributelist = NULL; 150d9deefdfSMatthew G. Knepley inputCtx->pointmarkerlist = NULL; 151d9deefdfSMatthew G. Knepley inputCtx->numberofsegments = 0; 152d9deefdfSMatthew G. Knepley inputCtx->segmentlist = NULL; 153d9deefdfSMatthew G. Knepley inputCtx->segmentmarkerlist = NULL; 154d9deefdfSMatthew G. Knepley inputCtx->numberoftriangleattributes = 0; 155d9deefdfSMatthew G. Knepley inputCtx->trianglelist = NULL; 156d9deefdfSMatthew G. Knepley inputCtx->numberofholes = 0; 157d9deefdfSMatthew G. Knepley inputCtx->holelist = NULL; 158d9deefdfSMatthew G. Knepley inputCtx->numberofregions = 0; 159d9deefdfSMatthew G. Knepley inputCtx->regionlist = NULL; 160d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 161d9deefdfSMatthew G. Knepley } 162d9deefdfSMatthew G. Knepley 163d9deefdfSMatthew G. Knepley #undef __FUNCT__ 164d9deefdfSMatthew G. Knepley #define __FUNCT__ "InitOutput_Triangle" 165d9deefdfSMatthew G. Knepley PetscErrorCode InitOutput_Triangle(struct triangulateio *outputCtx) 166d9deefdfSMatthew G. Knepley { 167d9deefdfSMatthew G. Knepley PetscFunctionBegin; 168d9deefdfSMatthew G. Knepley outputCtx->numberofpoints = 0; 169d9deefdfSMatthew G. Knepley outputCtx->pointlist = NULL; 170d9deefdfSMatthew G. Knepley outputCtx->pointattributelist = NULL; 171d9deefdfSMatthew G. Knepley outputCtx->pointmarkerlist = NULL; 172d9deefdfSMatthew G. Knepley outputCtx->numberoftriangles = 0; 173d9deefdfSMatthew G. Knepley outputCtx->trianglelist = NULL; 174d9deefdfSMatthew G. Knepley outputCtx->triangleattributelist = NULL; 175d9deefdfSMatthew G. Knepley outputCtx->neighborlist = NULL; 176d9deefdfSMatthew G. Knepley outputCtx->segmentlist = NULL; 177d9deefdfSMatthew G. Knepley outputCtx->segmentmarkerlist = NULL; 178d9deefdfSMatthew G. Knepley outputCtx->numberofedges = 0; 179d9deefdfSMatthew G. Knepley outputCtx->edgelist = NULL; 180d9deefdfSMatthew G. Knepley outputCtx->edgemarkerlist = NULL; 181d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 182d9deefdfSMatthew G. Knepley } 183d9deefdfSMatthew G. Knepley 184d9deefdfSMatthew G. Knepley #undef __FUNCT__ 185d9deefdfSMatthew G. Knepley #define __FUNCT__ "FiniOutput_Triangle" 186d9deefdfSMatthew G. Knepley PetscErrorCode FiniOutput_Triangle(struct triangulateio *outputCtx) 187d9deefdfSMatthew G. Knepley { 188d9deefdfSMatthew G. Knepley PetscFunctionBegin; 189d9deefdfSMatthew G. Knepley free(outputCtx->pointlist); 190d9deefdfSMatthew G. Knepley free(outputCtx->pointmarkerlist); 191d9deefdfSMatthew G. Knepley free(outputCtx->segmentlist); 192d9deefdfSMatthew G. Knepley free(outputCtx->segmentmarkerlist); 193d9deefdfSMatthew G. Knepley free(outputCtx->edgelist); 194d9deefdfSMatthew G. Knepley free(outputCtx->edgemarkerlist); 195d9deefdfSMatthew G. Knepley free(outputCtx->trianglelist); 196d9deefdfSMatthew G. Knepley free(outputCtx->neighborlist); 197d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 198d9deefdfSMatthew G. Knepley } 199d9deefdfSMatthew G. Knepley 200d9deefdfSMatthew G. Knepley #undef __FUNCT__ 201d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexGenerate_Triangle" 202d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexGenerate_Triangle(DM boundary, PetscBool interpolate, DM *dm) 203d9deefdfSMatthew G. Knepley { 204d9deefdfSMatthew G. Knepley MPI_Comm comm; 205d9deefdfSMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) boundary->data; 206d9deefdfSMatthew G. Knepley PetscInt dim = 2; 207d9deefdfSMatthew G. Knepley const PetscBool createConvexHull = PETSC_FALSE; 208d9deefdfSMatthew G. Knepley const PetscBool constrained = PETSC_FALSE; 209d9deefdfSMatthew G. Knepley struct triangulateio in; 210d9deefdfSMatthew G. Knepley struct triangulateio out; 211d9deefdfSMatthew G. Knepley PetscInt vStart, vEnd, v, eStart, eEnd, e; 212d9deefdfSMatthew G. Knepley PetscMPIInt rank; 213d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 214d9deefdfSMatthew G. Knepley 215d9deefdfSMatthew G. Knepley PetscFunctionBegin; 216d9deefdfSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)boundary,&comm);CHKERRQ(ierr); 217d9deefdfSMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 218d9deefdfSMatthew G. Knepley ierr = InitInput_Triangle(&in);CHKERRQ(ierr); 219d9deefdfSMatthew G. Knepley ierr = InitOutput_Triangle(&out);CHKERRQ(ierr); 220d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepthStratum(boundary, 0, &vStart, &vEnd);CHKERRQ(ierr); 221d9deefdfSMatthew G. Knepley 222d9deefdfSMatthew G. Knepley in.numberofpoints = vEnd - vStart; 223d9deefdfSMatthew G. Knepley if (in.numberofpoints > 0) { 224d9deefdfSMatthew G. Knepley PetscSection coordSection; 225d9deefdfSMatthew G. Knepley Vec coordinates; 226d9deefdfSMatthew G. Knepley PetscScalar *array; 227d9deefdfSMatthew G. Knepley 228d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofpoints*dim, &in.pointlist);CHKERRQ(ierr); 229d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofpoints, &in.pointmarkerlist);CHKERRQ(ierr); 230d9deefdfSMatthew G. Knepley ierr = DMGetCoordinatesLocal(boundary, &coordinates);CHKERRQ(ierr); 231d9deefdfSMatthew G. Knepley ierr = DMGetCoordinateSection(boundary, &coordSection);CHKERRQ(ierr); 232d9deefdfSMatthew G. Knepley ierr = VecGetArray(coordinates, &array);CHKERRQ(ierr); 233d9deefdfSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 234d9deefdfSMatthew G. Knepley const PetscInt idx = v - vStart; 235d9deefdfSMatthew G. Knepley PetscInt off, d; 236d9deefdfSMatthew G. Knepley 237d9deefdfSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 238d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) { 239d9deefdfSMatthew G. Knepley in.pointlist[idx*dim + d] = PetscRealPart(array[off+d]); 240d9deefdfSMatthew G. Knepley } 241d9deefdfSMatthew G. Knepley ierr = DMPlexGetLabelValue(boundary, "marker", v, &in.pointmarkerlist[idx]);CHKERRQ(ierr); 242d9deefdfSMatthew G. Knepley } 243d9deefdfSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &array);CHKERRQ(ierr); 244d9deefdfSMatthew G. Knepley } 245d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(boundary, 0, &eStart, &eEnd);CHKERRQ(ierr); 246d9deefdfSMatthew G. Knepley in.numberofsegments = eEnd - eStart; 247d9deefdfSMatthew G. Knepley if (in.numberofsegments > 0) { 248d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofsegments*2, &in.segmentlist);CHKERRQ(ierr); 249d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofsegments, &in.segmentmarkerlist);CHKERRQ(ierr); 250d9deefdfSMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 251d9deefdfSMatthew G. Knepley const PetscInt idx = e - eStart; 252d9deefdfSMatthew G. Knepley const PetscInt *cone; 253d9deefdfSMatthew G. Knepley 254d9deefdfSMatthew G. Knepley ierr = DMPlexGetCone(boundary, e, &cone);CHKERRQ(ierr); 255d9deefdfSMatthew G. Knepley 256d9deefdfSMatthew G. Knepley in.segmentlist[idx*2+0] = cone[0] - vStart; 257d9deefdfSMatthew G. Knepley in.segmentlist[idx*2+1] = cone[1] - vStart; 258d9deefdfSMatthew G. Knepley 259d9deefdfSMatthew G. Knepley ierr = DMPlexGetLabelValue(boundary, "marker", e, &in.segmentmarkerlist[idx]);CHKERRQ(ierr); 260d9deefdfSMatthew G. Knepley } 261d9deefdfSMatthew G. Knepley } 262d9deefdfSMatthew G. Knepley #if 0 /* Do not currently support holes */ 263d9deefdfSMatthew G. Knepley PetscReal *holeCoords; 264d9deefdfSMatthew G. Knepley PetscInt h, d; 265d9deefdfSMatthew G. Knepley 266d9deefdfSMatthew G. Knepley ierr = DMPlexGetHoles(boundary, &in.numberofholes, &holeCords);CHKERRQ(ierr); 267d9deefdfSMatthew G. Knepley if (in.numberofholes > 0) { 268d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofholes*dim, &in.holelist);CHKERRQ(ierr); 269d9deefdfSMatthew G. Knepley for (h = 0; h < in.numberofholes; ++h) { 270d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) { 271d9deefdfSMatthew G. Knepley in.holelist[h*dim+d] = holeCoords[h*dim+d]; 272d9deefdfSMatthew G. Knepley } 273d9deefdfSMatthew G. Knepley } 274d9deefdfSMatthew G. Knepley } 275d9deefdfSMatthew G. Knepley #endif 276d9deefdfSMatthew G. Knepley if (!rank) { 277d9deefdfSMatthew G. Knepley char args[32]; 278d9deefdfSMatthew G. Knepley 279d9deefdfSMatthew G. Knepley /* Take away 'Q' for verbose output */ 280d9deefdfSMatthew G. Knepley ierr = PetscStrcpy(args, "pqezQ");CHKERRQ(ierr); 281d9deefdfSMatthew G. Knepley if (createConvexHull) {ierr = PetscStrcat(args, "c");CHKERRQ(ierr);} 282d9deefdfSMatthew G. Knepley if (constrained) {ierr = PetscStrcpy(args, "zepDQ");CHKERRQ(ierr);} 283d9deefdfSMatthew G. Knepley if (mesh->triangleOpts) {triangulate(mesh->triangleOpts, &in, &out, NULL);} 284d9deefdfSMatthew G. Knepley else {triangulate(args, &in, &out, NULL);} 285d9deefdfSMatthew G. Knepley } 286d9deefdfSMatthew G. Knepley ierr = PetscFree(in.pointlist);CHKERRQ(ierr); 287d9deefdfSMatthew G. Knepley ierr = PetscFree(in.pointmarkerlist);CHKERRQ(ierr); 288d9deefdfSMatthew G. Knepley ierr = PetscFree(in.segmentlist);CHKERRQ(ierr); 289d9deefdfSMatthew G. Knepley ierr = PetscFree(in.segmentmarkerlist);CHKERRQ(ierr); 290d9deefdfSMatthew G. Knepley ierr = PetscFree(in.holelist);CHKERRQ(ierr); 291d9deefdfSMatthew G. Knepley 292d9deefdfSMatthew G. Knepley { 293d9deefdfSMatthew G. Knepley const PetscInt numCorners = 3; 294d9deefdfSMatthew G. Knepley const PetscInt numCells = out.numberoftriangles; 295d9deefdfSMatthew G. Knepley const PetscInt numVertices = out.numberofpoints; 296d9deefdfSMatthew G. Knepley const int *cells = out.trianglelist; 297d9deefdfSMatthew G. Knepley const double *meshCoords = out.pointlist; 298d9deefdfSMatthew G. Knepley 299d9deefdfSMatthew G. Knepley ierr = DMPlexCreateFromCellList(comm, dim, numCells, numVertices, numCorners, interpolate, cells, dim, meshCoords, dm);CHKERRQ(ierr); 300d9deefdfSMatthew G. Knepley /* Set labels */ 301d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 302d9deefdfSMatthew G. Knepley if (out.pointmarkerlist[v]) { 303d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dm, "marker", v+numCells, out.pointmarkerlist[v]);CHKERRQ(ierr); 304d9deefdfSMatthew G. Knepley } 305d9deefdfSMatthew G. Knepley } 306d9deefdfSMatthew G. Knepley if (interpolate) { 307d9deefdfSMatthew G. Knepley for (e = 0; e < out.numberofedges; e++) { 308d9deefdfSMatthew G. Knepley if (out.edgemarkerlist[e]) { 309d9deefdfSMatthew G. Knepley const PetscInt vertices[2] = {out.edgelist[e*2+0]+numCells, out.edgelist[e*2+1]+numCells}; 310d9deefdfSMatthew G. Knepley const PetscInt *edges; 311d9deefdfSMatthew G. Knepley PetscInt numEdges; 312d9deefdfSMatthew G. Knepley 313d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dm, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 314d9deefdfSMatthew G. Knepley if (numEdges != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Two vertices must cover only one edge, not %D", numEdges); 315d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dm, "marker", edges[0], out.edgemarkerlist[e]);CHKERRQ(ierr); 316d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dm, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 317d9deefdfSMatthew G. Knepley } 318d9deefdfSMatthew G. Knepley } 319d9deefdfSMatthew G. Knepley } 320d9deefdfSMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*dm, PETSC_FALSE);CHKERRQ(ierr); 321d9deefdfSMatthew G. Knepley } 322d9deefdfSMatthew G. Knepley #if 0 /* Do not currently support holes */ 323d9deefdfSMatthew G. Knepley ierr = DMPlexCopyHoles(*dm, boundary);CHKERRQ(ierr); 324d9deefdfSMatthew G. Knepley #endif 325d9deefdfSMatthew G. Knepley ierr = FiniOutput_Triangle(&out);CHKERRQ(ierr); 326d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 327d9deefdfSMatthew G. Knepley } 328d9deefdfSMatthew G. Knepley 329d9deefdfSMatthew G. Knepley #undef __FUNCT__ 330d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexRefine_Triangle" 331d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexRefine_Triangle(DM dm, double *maxVolumes, DM *dmRefined) 332d9deefdfSMatthew G. Knepley { 333d9deefdfSMatthew G. Knepley MPI_Comm comm; 334d9deefdfSMatthew G. Knepley PetscInt dim = 2; 335d9deefdfSMatthew G. Knepley struct triangulateio in; 336d9deefdfSMatthew G. Knepley struct triangulateio out; 337d9deefdfSMatthew G. Knepley PetscInt vStart, vEnd, v, cStart, cEnd, c, depth, depthGlobal; 338d9deefdfSMatthew G. Knepley PetscMPIInt rank; 339d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 340d9deefdfSMatthew G. Knepley 341d9deefdfSMatthew G. Knepley PetscFunctionBegin; 342d9deefdfSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 343d9deefdfSMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 344d9deefdfSMatthew G. Knepley ierr = InitInput_Triangle(&in);CHKERRQ(ierr); 345d9deefdfSMatthew G. Knepley ierr = InitOutput_Triangle(&out);CHKERRQ(ierr); 346d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 347d9deefdfSMatthew G. Knepley ierr = MPI_Allreduce(&depth, &depthGlobal, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); 348d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 349d9deefdfSMatthew G. Knepley 350d9deefdfSMatthew G. Knepley in.numberofpoints = vEnd - vStart; 351d9deefdfSMatthew G. Knepley if (in.numberofpoints > 0) { 352d9deefdfSMatthew G. Knepley PetscSection coordSection; 353d9deefdfSMatthew G. Knepley Vec coordinates; 354d9deefdfSMatthew G. Knepley PetscScalar *array; 355d9deefdfSMatthew G. Knepley 356d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofpoints*dim, &in.pointlist);CHKERRQ(ierr); 357d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofpoints, &in.pointmarkerlist);CHKERRQ(ierr); 358d9deefdfSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 359d9deefdfSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 360d9deefdfSMatthew G. Knepley ierr = VecGetArray(coordinates, &array);CHKERRQ(ierr); 361d9deefdfSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 362d9deefdfSMatthew G. Knepley const PetscInt idx = v - vStart; 363d9deefdfSMatthew G. Knepley PetscInt off, d; 364d9deefdfSMatthew G. Knepley 365d9deefdfSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 366d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) { 367d9deefdfSMatthew G. Knepley in.pointlist[idx*dim + d] = PetscRealPart(array[off+d]); 368d9deefdfSMatthew G. Knepley } 369d9deefdfSMatthew G. Knepley ierr = DMPlexGetLabelValue(dm, "marker", v, &in.pointmarkerlist[idx]);CHKERRQ(ierr); 370d9deefdfSMatthew G. Knepley } 371d9deefdfSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &array);CHKERRQ(ierr); 372d9deefdfSMatthew G. Knepley } 373d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 374d9deefdfSMatthew G. Knepley 375d9deefdfSMatthew G. Knepley in.numberofcorners = 3; 376d9deefdfSMatthew G. Knepley in.numberoftriangles = cEnd - cStart; 377d9deefdfSMatthew G. Knepley 378d9deefdfSMatthew G. Knepley in.trianglearealist = (double*) maxVolumes; 379d9deefdfSMatthew G. Knepley if (in.numberoftriangles > 0) { 380d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberoftriangles*in.numberofcorners, &in.trianglelist);CHKERRQ(ierr); 381d9deefdfSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 382d9deefdfSMatthew G. Knepley const PetscInt idx = c - cStart; 383d9deefdfSMatthew G. Knepley PetscInt *closure = NULL; 384d9deefdfSMatthew G. Knepley PetscInt closureSize; 385d9deefdfSMatthew G. Knepley 386d9deefdfSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 387d9deefdfSMatthew G. Knepley if ((closureSize != 4) && (closureSize != 7)) SETERRQ1(comm, PETSC_ERR_ARG_WRONG, "Mesh has cell which is not a triangle, %D vertices in closure", closureSize); 388d9deefdfSMatthew G. Knepley for (v = 0; v < 3; ++v) { 389d9deefdfSMatthew G. Knepley in.trianglelist[idx*in.numberofcorners + v] = closure[(v+closureSize-3)*2] - vStart; 390d9deefdfSMatthew G. Knepley } 391d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 392d9deefdfSMatthew G. Knepley } 393d9deefdfSMatthew G. Knepley } 394d9deefdfSMatthew G. Knepley /* TODO: Segment markers are missing on input */ 395d9deefdfSMatthew G. Knepley #if 0 /* Do not currently support holes */ 396d9deefdfSMatthew G. Knepley PetscReal *holeCoords; 397d9deefdfSMatthew G. Knepley PetscInt h, d; 398d9deefdfSMatthew G. Knepley 399d9deefdfSMatthew G. Knepley ierr = DMPlexGetHoles(boundary, &in.numberofholes, &holeCords);CHKERRQ(ierr); 400d9deefdfSMatthew G. Knepley if (in.numberofholes > 0) { 401d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofholes*dim, &in.holelist);CHKERRQ(ierr); 402d9deefdfSMatthew G. Knepley for (h = 0; h < in.numberofholes; ++h) { 403d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) { 404d9deefdfSMatthew G. Knepley in.holelist[h*dim+d] = holeCoords[h*dim+d]; 405d9deefdfSMatthew G. Knepley } 406d9deefdfSMatthew G. Knepley } 407d9deefdfSMatthew G. Knepley } 408d9deefdfSMatthew G. Knepley #endif 409d9deefdfSMatthew G. Knepley if (!rank) { 410d9deefdfSMatthew G. Knepley char args[32]; 411d9deefdfSMatthew G. Knepley 412d9deefdfSMatthew G. Knepley /* Take away 'Q' for verbose output */ 413d9deefdfSMatthew G. Knepley ierr = PetscStrcpy(args, "pqezQra");CHKERRQ(ierr); 414d9deefdfSMatthew G. Knepley triangulate(args, &in, &out, NULL); 415d9deefdfSMatthew G. Knepley } 416d9deefdfSMatthew G. Knepley ierr = PetscFree(in.pointlist);CHKERRQ(ierr); 417d9deefdfSMatthew G. Knepley ierr = PetscFree(in.pointmarkerlist);CHKERRQ(ierr); 418d9deefdfSMatthew G. Knepley ierr = PetscFree(in.segmentlist);CHKERRQ(ierr); 419d9deefdfSMatthew G. Knepley ierr = PetscFree(in.segmentmarkerlist);CHKERRQ(ierr); 420d9deefdfSMatthew G. Knepley ierr = PetscFree(in.trianglelist);CHKERRQ(ierr); 421d9deefdfSMatthew G. Knepley 422d9deefdfSMatthew G. Knepley { 423d9deefdfSMatthew G. Knepley const PetscInt numCorners = 3; 424d9deefdfSMatthew G. Knepley const PetscInt numCells = out.numberoftriangles; 425d9deefdfSMatthew G. Knepley const PetscInt numVertices = out.numberofpoints; 426d9deefdfSMatthew G. Knepley const int *cells = out.trianglelist; 427d9deefdfSMatthew G. Knepley const double *meshCoords = out.pointlist; 428d9deefdfSMatthew G. Knepley PetscBool interpolate = depthGlobal > 1 ? PETSC_TRUE : PETSC_FALSE; 429d9deefdfSMatthew G. Knepley 430d9deefdfSMatthew G. Knepley ierr = DMPlexCreateFromCellList(comm, dim, numCells, numVertices, numCorners, interpolate, cells, dim, meshCoords, dmRefined);CHKERRQ(ierr); 431d9deefdfSMatthew G. Knepley /* Set labels */ 432d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 433d9deefdfSMatthew G. Knepley if (out.pointmarkerlist[v]) { 434d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dmRefined, "marker", v+numCells, out.pointmarkerlist[v]);CHKERRQ(ierr); 435d9deefdfSMatthew G. Knepley } 436d9deefdfSMatthew G. Knepley } 437d9deefdfSMatthew G. Knepley if (interpolate) { 438d9deefdfSMatthew G. Knepley PetscInt e; 439d9deefdfSMatthew G. Knepley 440d9deefdfSMatthew G. Knepley for (e = 0; e < out.numberofedges; e++) { 441d9deefdfSMatthew G. Knepley if (out.edgemarkerlist[e]) { 442d9deefdfSMatthew G. Knepley const PetscInt vertices[2] = {out.edgelist[e*2+0]+numCells, out.edgelist[e*2+1]+numCells}; 443d9deefdfSMatthew G. Knepley const PetscInt *edges; 444d9deefdfSMatthew G. Knepley PetscInt numEdges; 445d9deefdfSMatthew G. Knepley 446d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dmRefined, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 447d9deefdfSMatthew G. Knepley if (numEdges != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Two vertices must cover only one edge, not %D", numEdges); 448d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dmRefined, "marker", edges[0], out.edgemarkerlist[e]);CHKERRQ(ierr); 449d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dmRefined, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 450d9deefdfSMatthew G. Knepley } 451d9deefdfSMatthew G. Knepley } 452d9deefdfSMatthew G. Knepley } 453d9deefdfSMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*dmRefined, PETSC_FALSE);CHKERRQ(ierr); 454d9deefdfSMatthew G. Knepley } 455d9deefdfSMatthew G. Knepley #if 0 /* Do not currently support holes */ 456d9deefdfSMatthew G. Knepley ierr = DMPlexCopyHoles(*dm, boundary);CHKERRQ(ierr); 457d9deefdfSMatthew G. Knepley #endif 458d9deefdfSMatthew G. Knepley ierr = FiniOutput_Triangle(&out);CHKERRQ(ierr); 459d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 460d9deefdfSMatthew G. Knepley } 461d9deefdfSMatthew G. Knepley #endif /* PETSC_HAVE_TRIANGLE */ 462d9deefdfSMatthew G. Knepley 463d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TETGEN) 464d9deefdfSMatthew G. Knepley #include <tetgen.h> 465d9deefdfSMatthew G. Knepley #undef __FUNCT__ 466d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexGenerate_Tetgen" 467d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexGenerate_Tetgen(DM boundary, PetscBool interpolate, DM *dm) 468d9deefdfSMatthew G. Knepley { 469d9deefdfSMatthew G. Knepley MPI_Comm comm; 470d9deefdfSMatthew G. Knepley const PetscInt dim = 3; 471d9deefdfSMatthew G. Knepley ::tetgenio in; 472d9deefdfSMatthew G. Knepley ::tetgenio out; 473d9deefdfSMatthew G. Knepley PetscInt vStart, vEnd, v, fStart, fEnd, f; 474d9deefdfSMatthew G. Knepley PetscMPIInt rank; 475d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 476d9deefdfSMatthew G. Knepley 477d9deefdfSMatthew G. Knepley PetscFunctionBegin; 478d9deefdfSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)boundary,&comm);CHKERRQ(ierr); 479d9deefdfSMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 480d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepthStratum(boundary, 0, &vStart, &vEnd);CHKERRQ(ierr); 481d9deefdfSMatthew G. Knepley in.numberofpoints = vEnd - vStart; 482d9deefdfSMatthew G. Knepley if (in.numberofpoints > 0) { 483d9deefdfSMatthew G. Knepley PetscSection coordSection; 484d9deefdfSMatthew G. Knepley Vec coordinates; 485d9deefdfSMatthew G. Knepley PetscScalar *array; 486d9deefdfSMatthew G. Knepley 487d9deefdfSMatthew G. Knepley in.pointlist = new double[in.numberofpoints*dim]; 488d9deefdfSMatthew G. Knepley in.pointmarkerlist = new int[in.numberofpoints]; 489d9deefdfSMatthew G. Knepley 490d9deefdfSMatthew G. Knepley ierr = DMGetCoordinatesLocal(boundary, &coordinates);CHKERRQ(ierr); 491d9deefdfSMatthew G. Knepley ierr = DMGetCoordinateSection(boundary, &coordSection);CHKERRQ(ierr); 492d9deefdfSMatthew G. Knepley ierr = VecGetArray(coordinates, &array);CHKERRQ(ierr); 493d9deefdfSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 494d9deefdfSMatthew G. Knepley const PetscInt idx = v - vStart; 495d9deefdfSMatthew G. Knepley PetscInt off, d; 496d9deefdfSMatthew G. Knepley 497d9deefdfSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 498d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) in.pointlist[idx*dim + d] = PetscRealPart(array[off+d]); 499d9deefdfSMatthew G. Knepley ierr = DMPlexGetLabelValue(boundary, "marker", v, &in.pointmarkerlist[idx]);CHKERRQ(ierr); 500d9deefdfSMatthew G. Knepley } 501d9deefdfSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &array);CHKERRQ(ierr); 502d9deefdfSMatthew G. Knepley } 503d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(boundary, 0, &fStart, &fEnd);CHKERRQ(ierr); 504d9deefdfSMatthew G. Knepley 505d9deefdfSMatthew G. Knepley in.numberoffacets = fEnd - fStart; 506d9deefdfSMatthew G. Knepley if (in.numberoffacets > 0) { 507d9deefdfSMatthew G. Knepley in.facetlist = new tetgenio::facet[in.numberoffacets]; 508d9deefdfSMatthew G. Knepley in.facetmarkerlist = new int[in.numberoffacets]; 509d9deefdfSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 510d9deefdfSMatthew G. Knepley const PetscInt idx = f - fStart; 511d9deefdfSMatthew G. Knepley PetscInt *points = NULL, numPoints, p, numVertices = 0, v; 512d9deefdfSMatthew G. Knepley 513d9deefdfSMatthew G. Knepley in.facetlist[idx].numberofpolygons = 1; 514d9deefdfSMatthew G. Knepley in.facetlist[idx].polygonlist = new tetgenio::polygon[in.facetlist[idx].numberofpolygons]; 515d9deefdfSMatthew G. Knepley in.facetlist[idx].numberofholes = 0; 516d9deefdfSMatthew G. Knepley in.facetlist[idx].holelist = NULL; 517d9deefdfSMatthew G. Knepley 518d9deefdfSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(boundary, f, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 519d9deefdfSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 520d9deefdfSMatthew G. Knepley const PetscInt point = points[p]; 521d9deefdfSMatthew G. Knepley if ((point >= vStart) && (point < vEnd)) points[numVertices++] = point; 522d9deefdfSMatthew G. Knepley } 523d9deefdfSMatthew G. Knepley 524d9deefdfSMatthew G. Knepley tetgenio::polygon *poly = in.facetlist[idx].polygonlist; 525d9deefdfSMatthew G. Knepley poly->numberofvertices = numVertices; 526d9deefdfSMatthew G. Knepley poly->vertexlist = new int[poly->numberofvertices]; 527d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 528d9deefdfSMatthew G. Knepley const PetscInt vIdx = points[v] - vStart; 529d9deefdfSMatthew G. Knepley poly->vertexlist[v] = vIdx; 530d9deefdfSMatthew G. Knepley } 531d9deefdfSMatthew G. Knepley ierr = DMPlexGetLabelValue(boundary, "marker", f, &in.facetmarkerlist[idx]);CHKERRQ(ierr); 532d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(boundary, f, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 533d9deefdfSMatthew G. Knepley } 534d9deefdfSMatthew G. Knepley } 535d9deefdfSMatthew G. Knepley if (!rank) { 536d9deefdfSMatthew G. Knepley char args[32]; 537d9deefdfSMatthew G. Knepley 538d9deefdfSMatthew G. Knepley /* Take away 'Q' for verbose output */ 539d9deefdfSMatthew G. Knepley ierr = PetscStrcpy(args, "pqezQ");CHKERRQ(ierr); 540d9deefdfSMatthew G. Knepley if (mesh->tetgenOpts) {::tetrahedralize(mesh->tetgenOpts, &in, &out);} 541d9deefdfSMatthew G. Knepley else {::tetrahedralize(args, &in, &out);} 542d9deefdfSMatthew G. Knepley } 543d9deefdfSMatthew G. Knepley { 544d9deefdfSMatthew G. Knepley const PetscInt numCorners = 4; 545d9deefdfSMatthew G. Knepley const PetscInt numCells = out.numberoftetrahedra; 546d9deefdfSMatthew G. Knepley const PetscInt numVertices = out.numberofpoints; 547d9deefdfSMatthew G. Knepley const double *meshCoords = out.pointlist; 548d9deefdfSMatthew G. Knepley int *cells = out.tetrahedronlist; 549d9deefdfSMatthew G. Knepley 550d9deefdfSMatthew G. Knepley ierr = DMPlexInvertCells_Internal(dim, numCells, numCorners, cells);CHKERRQ(ierr); 551d9deefdfSMatthew G. Knepley ierr = DMPlexCreateFromCellList(comm, dim, numCells, numVertices, numCorners, interpolate, cells, dim, meshCoords, dm);CHKERRQ(ierr); 552d9deefdfSMatthew G. Knepley /* Set labels */ 553d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 554d9deefdfSMatthew G. Knepley if (out.pointmarkerlist[v]) { 555d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dm, "marker", v+numCells, out.pointmarkerlist[v]);CHKERRQ(ierr); 556d9deefdfSMatthew G. Knepley } 557d9deefdfSMatthew G. Knepley } 558d9deefdfSMatthew G. Knepley if (interpolate) { 559d9deefdfSMatthew G. Knepley PetscInt e; 560d9deefdfSMatthew G. Knepley 561d9deefdfSMatthew G. Knepley for (e = 0; e < out.numberofedges; e++) { 562d9deefdfSMatthew G. Knepley if (out.edgemarkerlist[e]) { 563d9deefdfSMatthew G. Knepley const PetscInt vertices[2] = {out.edgelist[e*2+0]+numCells, out.edgelist[e*2+1]+numCells}; 564d9deefdfSMatthew G. Knepley const PetscInt *edges; 565d9deefdfSMatthew G. Knepley PetscInt numEdges; 566d9deefdfSMatthew G. Knepley 567d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dm, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 568d9deefdfSMatthew G. Knepley if (numEdges != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Two vertices must cover only one edge, not %D", numEdges); 569d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dm, "marker", edges[0], out.edgemarkerlist[e]);CHKERRQ(ierr); 570d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dm, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 571d9deefdfSMatthew G. Knepley } 572d9deefdfSMatthew G. Knepley } 573d9deefdfSMatthew G. Knepley for (f = 0; f < out.numberoftrifaces; f++) { 574d9deefdfSMatthew G. Knepley if (out.trifacemarkerlist[f]) { 575d9deefdfSMatthew G. Knepley const PetscInt vertices[3] = {out.trifacelist[f*3+0]+numCells, out.trifacelist[f*3+1]+numCells, out.trifacelist[f*3+2]+numCells}; 576d9deefdfSMatthew G. Knepley const PetscInt *faces; 577d9deefdfSMatthew G. Knepley PetscInt numFaces; 578d9deefdfSMatthew G. Knepley 579d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dm, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 580d9deefdfSMatthew G. Knepley if (numFaces != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Three vertices must cover only one face, not %D", numFaces); 581d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dm, "marker", faces[0], out.trifacemarkerlist[f]);CHKERRQ(ierr); 582d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dm, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 583d9deefdfSMatthew G. Knepley } 584d9deefdfSMatthew G. Knepley } 585d9deefdfSMatthew G. Knepley } 586d9deefdfSMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*dm, PETSC_FALSE);CHKERRQ(ierr); 587d9deefdfSMatthew G. Knepley } 588d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 589d9deefdfSMatthew G. Knepley } 590d9deefdfSMatthew G. Knepley 591d9deefdfSMatthew G. Knepley #undef __FUNCT__ 592d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexRefine_Tetgen" 593d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexRefine_Tetgen(DM dm, double *maxVolumes, DM *dmRefined) 594d9deefdfSMatthew G. Knepley { 595d9deefdfSMatthew G. Knepley MPI_Comm comm; 596d9deefdfSMatthew G. Knepley const PetscInt dim = 3; 597d9deefdfSMatthew G. Knepley ::tetgenio in; 598d9deefdfSMatthew G. Knepley ::tetgenio out; 599d9deefdfSMatthew G. Knepley PetscInt vStart, vEnd, v, cStart, cEnd, c, depth, depthGlobal; 600d9deefdfSMatthew G. Knepley PetscMPIInt rank; 601d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 602d9deefdfSMatthew G. Knepley 603d9deefdfSMatthew G. Knepley PetscFunctionBegin; 604d9deefdfSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 605d9deefdfSMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 606d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 607d9deefdfSMatthew G. Knepley ierr = MPI_Allreduce(&depth, &depthGlobal, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); 608d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 609d9deefdfSMatthew G. Knepley 610d9deefdfSMatthew G. Knepley in.numberofpoints = vEnd - vStart; 611d9deefdfSMatthew G. Knepley if (in.numberofpoints > 0) { 612d9deefdfSMatthew G. Knepley PetscSection coordSection; 613d9deefdfSMatthew G. Knepley Vec coordinates; 614d9deefdfSMatthew G. Knepley PetscScalar *array; 615d9deefdfSMatthew G. Knepley 616d9deefdfSMatthew G. Knepley in.pointlist = new double[in.numberofpoints*dim]; 617d9deefdfSMatthew G. Knepley in.pointmarkerlist = new int[in.numberofpoints]; 618d9deefdfSMatthew G. Knepley 619d9deefdfSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 620d9deefdfSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 621d9deefdfSMatthew G. Knepley ierr = VecGetArray(coordinates, &array);CHKERRQ(ierr); 622d9deefdfSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 623d9deefdfSMatthew G. Knepley const PetscInt idx = v - vStart; 624d9deefdfSMatthew G. Knepley PetscInt off, d; 625d9deefdfSMatthew G. Knepley 626d9deefdfSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 627d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) in.pointlist[idx*dim + d] = PetscRealPart(array[off+d]); 628d9deefdfSMatthew G. Knepley ierr = DMPlexGetLabelValue(dm, "marker", v, &in.pointmarkerlist[idx]);CHKERRQ(ierr); 629d9deefdfSMatthew G. Knepley } 630d9deefdfSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &array);CHKERRQ(ierr); 631d9deefdfSMatthew G. Knepley } 632d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 633d9deefdfSMatthew G. Knepley 634d9deefdfSMatthew G. Knepley in.numberofcorners = 4; 635d9deefdfSMatthew G. Knepley in.numberoftetrahedra = cEnd - cStart; 636d9deefdfSMatthew G. Knepley in.tetrahedronvolumelist = (double*) maxVolumes; 637d9deefdfSMatthew G. Knepley if (in.numberoftetrahedra > 0) { 638d9deefdfSMatthew G. Knepley in.tetrahedronlist = new int[in.numberoftetrahedra*in.numberofcorners]; 639d9deefdfSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 640d9deefdfSMatthew G. Knepley const PetscInt idx = c - cStart; 641d9deefdfSMatthew G. Knepley PetscInt *closure = NULL; 642d9deefdfSMatthew G. Knepley PetscInt closureSize; 643d9deefdfSMatthew G. Knepley 644d9deefdfSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 645d9deefdfSMatthew G. Knepley if ((closureSize != 5) && (closureSize != 15)) SETERRQ1(comm, PETSC_ERR_ARG_WRONG, "Mesh has cell which is not a tetrahedron, %D vertices in closure", closureSize); 646d9deefdfSMatthew G. Knepley for (v = 0; v < 4; ++v) { 647d9deefdfSMatthew G. Knepley in.tetrahedronlist[idx*in.numberofcorners + v] = closure[(v+closureSize-4)*2] - vStart; 648d9deefdfSMatthew G. Knepley } 649d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 650d9deefdfSMatthew G. Knepley } 651d9deefdfSMatthew G. Knepley } 652d9deefdfSMatthew G. Knepley /* TODO: Put in boundary faces with markers */ 653d9deefdfSMatthew G. Knepley if (!rank) { 654d9deefdfSMatthew G. Knepley char args[32]; 655d9deefdfSMatthew G. Knepley 656d9deefdfSMatthew G. Knepley /* Take away 'Q' for verbose output */ 657d9deefdfSMatthew G. Knepley /*ierr = PetscStrcpy(args, "qezQra");CHKERRQ(ierr); */ 658d9deefdfSMatthew G. Knepley ierr = PetscStrcpy(args, "qezraVVVV");CHKERRQ(ierr); 659d9deefdfSMatthew G. Knepley ::tetrahedralize(args, &in, &out); 660d9deefdfSMatthew G. Knepley } 661d9deefdfSMatthew G. Knepley in.tetrahedronvolumelist = NULL; 662d9deefdfSMatthew G. Knepley 663d9deefdfSMatthew G. Knepley { 664d9deefdfSMatthew G. Knepley const PetscInt numCorners = 4; 665d9deefdfSMatthew G. Knepley const PetscInt numCells = out.numberoftetrahedra; 666d9deefdfSMatthew G. Knepley const PetscInt numVertices = out.numberofpoints; 667d9deefdfSMatthew G. Knepley const double *meshCoords = out.pointlist; 668d9deefdfSMatthew G. Knepley int *cells = out.tetrahedronlist; 669d9deefdfSMatthew G. Knepley 670d9deefdfSMatthew G. Knepley PetscBool interpolate = depthGlobal > 1 ? PETSC_TRUE : PETSC_FALSE; 671d9deefdfSMatthew G. Knepley 672d9deefdfSMatthew G. Knepley ierr = DMPlexInvertCells_Internal(dim, numCells, numCorners, cells);CHKERRQ(ierr); 673d9deefdfSMatthew G. Knepley ierr = DMPlexCreateFromCellList(comm, dim, numCells, numVertices, numCorners, interpolate, cells, dim, meshCoords, dmRefined);CHKERRQ(ierr); 674d9deefdfSMatthew G. Knepley /* Set labels */ 675d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 676d9deefdfSMatthew G. Knepley if (out.pointmarkerlist[v]) { 677d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dmRefined, "marker", v+numCells, out.pointmarkerlist[v]);CHKERRQ(ierr); 678d9deefdfSMatthew G. Knepley } 679d9deefdfSMatthew G. Knepley } 680d9deefdfSMatthew G. Knepley if (interpolate) { 681d9deefdfSMatthew G. Knepley PetscInt e, f; 682d9deefdfSMatthew G. Knepley 683d9deefdfSMatthew G. Knepley for (e = 0; e < out.numberofedges; e++) { 684d9deefdfSMatthew G. Knepley if (out.edgemarkerlist[e]) { 685d9deefdfSMatthew G. Knepley const PetscInt vertices[2] = {out.edgelist[e*2+0]+numCells, out.edgelist[e*2+1]+numCells}; 686d9deefdfSMatthew G. Knepley const PetscInt *edges; 687d9deefdfSMatthew G. Knepley PetscInt numEdges; 688d9deefdfSMatthew G. Knepley 689d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dmRefined, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 690d9deefdfSMatthew G. Knepley if (numEdges != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Two vertices must cover only one edge, not %D", numEdges); 691d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dmRefined, "marker", edges[0], out.edgemarkerlist[e]);CHKERRQ(ierr); 692d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dmRefined, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 693d9deefdfSMatthew G. Knepley } 694d9deefdfSMatthew G. Knepley } 695d9deefdfSMatthew G. Knepley for (f = 0; f < out.numberoftrifaces; f++) { 696d9deefdfSMatthew G. Knepley if (out.trifacemarkerlist[f]) { 697d9deefdfSMatthew G. Knepley const PetscInt vertices[3] = {out.trifacelist[f*3+0]+numCells, out.trifacelist[f*3+1]+numCells, out.trifacelist[f*3+2]+numCells}; 698d9deefdfSMatthew G. Knepley const PetscInt *faces; 699d9deefdfSMatthew G. Knepley PetscInt numFaces; 700d9deefdfSMatthew G. Knepley 701d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dmRefined, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 702d9deefdfSMatthew G. Knepley if (numFaces != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Three vertices must cover only one face, not %D", numFaces); 703d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dmRefined, "marker", faces[0], out.trifacemarkerlist[f]);CHKERRQ(ierr); 704d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dmRefined, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 705d9deefdfSMatthew G. Knepley } 706d9deefdfSMatthew G. Knepley } 707d9deefdfSMatthew G. Knepley } 708d9deefdfSMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*dmRefined, PETSC_FALSE);CHKERRQ(ierr); 709d9deefdfSMatthew G. Knepley } 710d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 711d9deefdfSMatthew G. Knepley } 712d9deefdfSMatthew G. Knepley #endif /* PETSC_HAVE_TETGEN */ 713d9deefdfSMatthew G. Knepley 714d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_CTETGEN) 715d9deefdfSMatthew G. Knepley #include <ctetgen.h> 716d9deefdfSMatthew G. Knepley 717d9deefdfSMatthew G. Knepley #undef __FUNCT__ 718d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexGenerate_CTetgen" 719d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexGenerate_CTetgen(DM boundary, PetscBool interpolate, DM *dm) 720d9deefdfSMatthew G. Knepley { 721d9deefdfSMatthew G. Knepley MPI_Comm comm; 722d9deefdfSMatthew G. Knepley const PetscInt dim = 3; 723d9deefdfSMatthew G. Knepley PLC *in, *out; 724d9deefdfSMatthew G. Knepley PetscInt verbose = 0, vStart, vEnd, v, fStart, fEnd, f; 725d9deefdfSMatthew G. Knepley PetscMPIInt rank; 726d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 727d9deefdfSMatthew G. Knepley 728d9deefdfSMatthew G. Knepley PetscFunctionBegin; 729d9deefdfSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)boundary,&comm);CHKERRQ(ierr); 730d9deefdfSMatthew G. Knepley ierr = PetscOptionsGetInt(((PetscObject) boundary)->prefix, "-ctetgen_verbose", &verbose, NULL);CHKERRQ(ierr); 731d9deefdfSMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 732d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepthStratum(boundary, 0, &vStart, &vEnd);CHKERRQ(ierr); 733d9deefdfSMatthew G. Knepley ierr = PLCCreate(&in);CHKERRQ(ierr); 734d9deefdfSMatthew G. Knepley ierr = PLCCreate(&out);CHKERRQ(ierr); 735d9deefdfSMatthew G. Knepley 736d9deefdfSMatthew G. Knepley in->numberofpoints = vEnd - vStart; 737d9deefdfSMatthew G. Knepley if (in->numberofpoints > 0) { 738d9deefdfSMatthew G. Knepley PetscSection coordSection; 739d9deefdfSMatthew G. Knepley Vec coordinates; 740d9deefdfSMatthew G. Knepley PetscScalar *array; 741d9deefdfSMatthew G. Knepley 742d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberofpoints*dim, &in->pointlist);CHKERRQ(ierr); 743d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberofpoints, &in->pointmarkerlist);CHKERRQ(ierr); 744d9deefdfSMatthew G. Knepley ierr = DMGetCoordinatesLocal(boundary, &coordinates);CHKERRQ(ierr); 745d9deefdfSMatthew G. Knepley ierr = DMGetCoordinateSection(boundary, &coordSection);CHKERRQ(ierr); 746d9deefdfSMatthew G. Knepley ierr = VecGetArray(coordinates, &array);CHKERRQ(ierr); 747d9deefdfSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 748d9deefdfSMatthew G. Knepley const PetscInt idx = v - vStart; 749d9deefdfSMatthew G. Knepley PetscInt off, d, m; 750d9deefdfSMatthew G. Knepley 751d9deefdfSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 752d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) { 753d9deefdfSMatthew G. Knepley in->pointlist[idx*dim + d] = PetscRealPart(array[off+d]); 754d9deefdfSMatthew G. Knepley } 755d9deefdfSMatthew G. Knepley ierr = DMPlexGetLabelValue(boundary, "marker", v, &m);CHKERRQ(ierr); 756d9deefdfSMatthew G. Knepley 757d9deefdfSMatthew G. Knepley in->pointmarkerlist[idx] = (int) m; 758d9deefdfSMatthew G. Knepley } 759d9deefdfSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &array);CHKERRQ(ierr); 760d9deefdfSMatthew G. Knepley } 761d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(boundary, 0, &fStart, &fEnd);CHKERRQ(ierr); 762d9deefdfSMatthew G. Knepley 763d9deefdfSMatthew G. Knepley in->numberoffacets = fEnd - fStart; 764d9deefdfSMatthew G. Knepley if (in->numberoffacets > 0) { 765d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberoffacets, &in->facetlist);CHKERRQ(ierr); 766d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberoffacets, &in->facetmarkerlist);CHKERRQ(ierr); 767d9deefdfSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 768d9deefdfSMatthew G. Knepley const PetscInt idx = f - fStart; 769d9deefdfSMatthew G. Knepley PetscInt *points = NULL, numPoints, p, numVertices = 0, v, m; 770d9deefdfSMatthew G. Knepley polygon *poly; 771d9deefdfSMatthew G. Knepley 772d9deefdfSMatthew G. Knepley in->facetlist[idx].numberofpolygons = 1; 773d9deefdfSMatthew G. Knepley 774d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->facetlist[idx].numberofpolygons, &in->facetlist[idx].polygonlist);CHKERRQ(ierr); 775d9deefdfSMatthew G. Knepley 776d9deefdfSMatthew G. Knepley in->facetlist[idx].numberofholes = 0; 777d9deefdfSMatthew G. Knepley in->facetlist[idx].holelist = NULL; 778d9deefdfSMatthew G. Knepley 779d9deefdfSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(boundary, f, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 780d9deefdfSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 781d9deefdfSMatthew G. Knepley const PetscInt point = points[p]; 782d9deefdfSMatthew G. Knepley if ((point >= vStart) && (point < vEnd)) points[numVertices++] = point; 783d9deefdfSMatthew G. Knepley } 784d9deefdfSMatthew G. Knepley 785d9deefdfSMatthew G. Knepley poly = in->facetlist[idx].polygonlist; 786d9deefdfSMatthew G. Knepley poly->numberofvertices = numVertices; 787d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(poly->numberofvertices, &poly->vertexlist);CHKERRQ(ierr); 788d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 789d9deefdfSMatthew G. Knepley const PetscInt vIdx = points[v] - vStart; 790d9deefdfSMatthew G. Knepley poly->vertexlist[v] = vIdx; 791d9deefdfSMatthew G. Knepley } 792d9deefdfSMatthew G. Knepley ierr = DMPlexGetLabelValue(boundary, "marker", f, &m);CHKERRQ(ierr); 793d9deefdfSMatthew G. Knepley in->facetmarkerlist[idx] = (int) m; 794d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(boundary, f, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 795d9deefdfSMatthew G. Knepley } 796d9deefdfSMatthew G. Knepley } 797d9deefdfSMatthew G. Knepley if (!rank) { 798d9deefdfSMatthew G. Knepley TetGenOpts t; 799d9deefdfSMatthew G. Knepley 800d9deefdfSMatthew G. Knepley ierr = TetGenOptsInitialize(&t);CHKERRQ(ierr); 801d9deefdfSMatthew G. Knepley t.in = boundary; /* Should go away */ 802d9deefdfSMatthew G. Knepley t.plc = 1; 803d9deefdfSMatthew G. Knepley t.quality = 1; 804d9deefdfSMatthew G. Knepley t.edgesout = 1; 805d9deefdfSMatthew G. Knepley t.zeroindex = 1; 806d9deefdfSMatthew G. Knepley t.quiet = 1; 807d9deefdfSMatthew G. Knepley t.verbose = verbose; 808d9deefdfSMatthew G. Knepley ierr = TetGenCheckOpts(&t);CHKERRQ(ierr); 809d9deefdfSMatthew G. Knepley ierr = TetGenTetrahedralize(&t, in, out);CHKERRQ(ierr); 810d9deefdfSMatthew G. Knepley } 811d9deefdfSMatthew G. Knepley { 812d9deefdfSMatthew G. Knepley const PetscInt numCorners = 4; 813d9deefdfSMatthew G. Knepley const PetscInt numCells = out->numberoftetrahedra; 814d9deefdfSMatthew G. Knepley const PetscInt numVertices = out->numberofpoints; 815d9deefdfSMatthew G. Knepley const double *meshCoords = out->pointlist; 816d9deefdfSMatthew G. Knepley int *cells = out->tetrahedronlist; 817d9deefdfSMatthew G. Knepley 818d9deefdfSMatthew G. Knepley ierr = DMPlexInvertCells_Internal(dim, numCells, numCorners, cells);CHKERRQ(ierr); 819d9deefdfSMatthew G. Knepley ierr = DMPlexCreateFromCellList(comm, dim, numCells, numVertices, numCorners, interpolate, cells, dim, meshCoords, dm);CHKERRQ(ierr); 820d9deefdfSMatthew G. Knepley /* Set labels */ 821d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 822d9deefdfSMatthew G. Knepley if (out->pointmarkerlist[v]) { 823d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dm, "marker", v+numCells, out->pointmarkerlist[v]);CHKERRQ(ierr); 824d9deefdfSMatthew G. Knepley } 825d9deefdfSMatthew G. Knepley } 826d9deefdfSMatthew G. Knepley if (interpolate) { 827d9deefdfSMatthew G. Knepley PetscInt e; 828d9deefdfSMatthew G. Knepley 829d9deefdfSMatthew G. Knepley for (e = 0; e < out->numberofedges; e++) { 830d9deefdfSMatthew G. Knepley if (out->edgemarkerlist[e]) { 831d9deefdfSMatthew G. Knepley const PetscInt vertices[2] = {out->edgelist[e*2+0]+numCells, out->edgelist[e*2+1]+numCells}; 832d9deefdfSMatthew G. Knepley const PetscInt *edges; 833d9deefdfSMatthew G. Knepley PetscInt numEdges; 834d9deefdfSMatthew G. Knepley 835d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dm, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 836d9deefdfSMatthew G. Knepley if (numEdges != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Two vertices must cover only one edge, not %D", numEdges); 837d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dm, "marker", edges[0], out->edgemarkerlist[e]);CHKERRQ(ierr); 838d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dm, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 839d9deefdfSMatthew G. Knepley } 840d9deefdfSMatthew G. Knepley } 841d9deefdfSMatthew G. Knepley for (f = 0; f < out->numberoftrifaces; f++) { 842d9deefdfSMatthew G. Knepley if (out->trifacemarkerlist[f]) { 843d9deefdfSMatthew G. Knepley const PetscInt vertices[3] = {out->trifacelist[f*3+0]+numCells, out->trifacelist[f*3+1]+numCells, out->trifacelist[f*3+2]+numCells}; 844d9deefdfSMatthew G. Knepley const PetscInt *faces; 845d9deefdfSMatthew G. Knepley PetscInt numFaces; 846d9deefdfSMatthew G. Knepley 847d9deefdfSMatthew G. Knepley ierr = DMPlexGetFullJoin(*dm, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 848d9deefdfSMatthew G. Knepley if (numFaces != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Three vertices must cover only one face, not %D", numFaces); 849d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dm, "marker", faces[0], out->trifacemarkerlist[f]);CHKERRQ(ierr); 850d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dm, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 851d9deefdfSMatthew G. Knepley } 852d9deefdfSMatthew G. Knepley } 853d9deefdfSMatthew G. Knepley } 854d9deefdfSMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*dm, PETSC_FALSE);CHKERRQ(ierr); 855d9deefdfSMatthew G. Knepley } 856d9deefdfSMatthew G. Knepley 857d9deefdfSMatthew G. Knepley ierr = PLCDestroy(&in);CHKERRQ(ierr); 858d9deefdfSMatthew G. Knepley ierr = PLCDestroy(&out);CHKERRQ(ierr); 859d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 860d9deefdfSMatthew G. Knepley } 861d9deefdfSMatthew G. Knepley 862d9deefdfSMatthew G. Knepley #undef __FUNCT__ 863d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexRefine_CTetgen" 864d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexRefine_CTetgen(DM dm, PetscReal *maxVolumes, DM *dmRefined) 865d9deefdfSMatthew G. Knepley { 866d9deefdfSMatthew G. Knepley MPI_Comm comm; 867d9deefdfSMatthew G. Knepley const PetscInt dim = 3; 868d9deefdfSMatthew G. Knepley PLC *in, *out; 869d9deefdfSMatthew G. Knepley PetscInt verbose = 0, vStart, vEnd, v, cStart, cEnd, c, depth, depthGlobal; 870d9deefdfSMatthew G. Knepley PetscMPIInt rank; 871d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 872d9deefdfSMatthew G. Knepley 873d9deefdfSMatthew G. Knepley PetscFunctionBegin; 874d9deefdfSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 875d9deefdfSMatthew G. Knepley ierr = PetscOptionsGetInt(((PetscObject) dm)->prefix, "-ctetgen_verbose", &verbose, NULL);CHKERRQ(ierr); 876d9deefdfSMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 877d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 878d9deefdfSMatthew G. Knepley ierr = MPI_Allreduce(&depth, &depthGlobal, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); 879d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 880d9deefdfSMatthew G. Knepley ierr = PLCCreate(&in);CHKERRQ(ierr); 881d9deefdfSMatthew G. Knepley ierr = PLCCreate(&out);CHKERRQ(ierr); 882d9deefdfSMatthew G. Knepley 883d9deefdfSMatthew G. Knepley in->numberofpoints = vEnd - vStart; 884d9deefdfSMatthew G. Knepley if (in->numberofpoints > 0) { 885d9deefdfSMatthew G. Knepley PetscSection coordSection; 886d9deefdfSMatthew G. Knepley Vec coordinates; 887d9deefdfSMatthew G. Knepley PetscScalar *array; 888d9deefdfSMatthew G. Knepley 889d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberofpoints*dim, &in->pointlist);CHKERRQ(ierr); 890d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberofpoints, &in->pointmarkerlist);CHKERRQ(ierr); 891d9deefdfSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 892d9deefdfSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 893d9deefdfSMatthew G. Knepley ierr = VecGetArray(coordinates, &array);CHKERRQ(ierr); 894d9deefdfSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 895d9deefdfSMatthew G. Knepley const PetscInt idx = v - vStart; 896d9deefdfSMatthew G. Knepley PetscInt off, d, m; 897d9deefdfSMatthew G. Knepley 898d9deefdfSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 899d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) { 900d9deefdfSMatthew G. Knepley in->pointlist[idx*dim + d] = PetscRealPart(array[off+d]); 901d9deefdfSMatthew G. Knepley } 902d9deefdfSMatthew G. Knepley ierr = DMPlexGetLabelValue(dm, "marker", v, &m);CHKERRQ(ierr); 903d9deefdfSMatthew G. Knepley 904d9deefdfSMatthew G. Knepley in->pointmarkerlist[idx] = (int) m; 905d9deefdfSMatthew G. Knepley } 906d9deefdfSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &array);CHKERRQ(ierr); 907d9deefdfSMatthew G. Knepley } 908d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 909d9deefdfSMatthew G. Knepley 910d9deefdfSMatthew G. Knepley in->numberofcorners = 4; 911d9deefdfSMatthew G. Knepley in->numberoftetrahedra = cEnd - cStart; 912d9deefdfSMatthew G. Knepley in->tetrahedronvolumelist = maxVolumes; 913d9deefdfSMatthew G. Knepley if (in->numberoftetrahedra > 0) { 914d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberoftetrahedra*in->numberofcorners, &in->tetrahedronlist);CHKERRQ(ierr); 915d9deefdfSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 916d9deefdfSMatthew G. Knepley const PetscInt idx = c - cStart; 917d9deefdfSMatthew G. Knepley PetscInt *closure = NULL; 918d9deefdfSMatthew G. Knepley PetscInt closureSize; 919d9deefdfSMatthew G. Knepley 920d9deefdfSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 921d9deefdfSMatthew G. Knepley if ((closureSize != 5) && (closureSize != 15)) SETERRQ1(comm, PETSC_ERR_ARG_WRONG, "Mesh has cell which is not a tetrahedron, %D vertices in closure", closureSize); 922d9deefdfSMatthew G. Knepley for (v = 0; v < 4; ++v) { 923d9deefdfSMatthew G. Knepley in->tetrahedronlist[idx*in->numberofcorners + v] = closure[(v+closureSize-4)*2] - vStart; 924d9deefdfSMatthew G. Knepley } 925d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 926d9deefdfSMatthew G. Knepley } 927d9deefdfSMatthew G. Knepley } 928d9deefdfSMatthew G. Knepley if (!rank) { 929d9deefdfSMatthew G. Knepley TetGenOpts t; 930d9deefdfSMatthew G. Knepley 931d9deefdfSMatthew G. Knepley ierr = TetGenOptsInitialize(&t);CHKERRQ(ierr); 932d9deefdfSMatthew G. Knepley 933d9deefdfSMatthew G. Knepley t.in = dm; /* Should go away */ 934d9deefdfSMatthew G. Knepley t.refine = 1; 935d9deefdfSMatthew G. Knepley t.varvolume = 1; 936d9deefdfSMatthew G. Knepley t.quality = 1; 937d9deefdfSMatthew G. Knepley t.edgesout = 1; 938d9deefdfSMatthew G. Knepley t.zeroindex = 1; 939d9deefdfSMatthew G. Knepley t.quiet = 1; 940d9deefdfSMatthew G. Knepley t.verbose = verbose; /* Change this */ 941d9deefdfSMatthew G. Knepley 942d9deefdfSMatthew G. Knepley ierr = TetGenCheckOpts(&t);CHKERRQ(ierr); 943d9deefdfSMatthew G. Knepley ierr = TetGenTetrahedralize(&t, in, out);CHKERRQ(ierr); 944d9deefdfSMatthew G. Knepley } 945d9deefdfSMatthew G. Knepley { 946d9deefdfSMatthew G. Knepley const PetscInt numCorners = 4; 947d9deefdfSMatthew G. Knepley const PetscInt numCells = out->numberoftetrahedra; 948d9deefdfSMatthew G. Knepley const PetscInt numVertices = out->numberofpoints; 949d9deefdfSMatthew G. Knepley const double *meshCoords = out->pointlist; 950d9deefdfSMatthew G. Knepley int *cells = out->tetrahedronlist; 951d9deefdfSMatthew G. Knepley PetscBool interpolate = depthGlobal > 1 ? PETSC_TRUE : PETSC_FALSE; 952d9deefdfSMatthew G. Knepley 953d9deefdfSMatthew G. Knepley ierr = DMPlexInvertCells_Internal(dim, numCells, numCorners, cells);CHKERRQ(ierr); 954d9deefdfSMatthew G. Knepley ierr = DMPlexCreateFromCellList(comm, dim, numCells, numVertices, numCorners, interpolate, cells, dim, meshCoords, dmRefined);CHKERRQ(ierr); 955d9deefdfSMatthew G. Knepley /* Set labels */ 956d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 957d9deefdfSMatthew G. Knepley if (out->pointmarkerlist[v]) { 958d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dmRefined, "marker", v+numCells, out->pointmarkerlist[v]);CHKERRQ(ierr); 959d9deefdfSMatthew G. Knepley } 960d9deefdfSMatthew G. Knepley } 961d9deefdfSMatthew G. Knepley if (interpolate) { 962d9deefdfSMatthew G. Knepley PetscInt e, f; 963d9deefdfSMatthew G. Knepley 964d9deefdfSMatthew G. Knepley for (e = 0; e < out->numberofedges; e++) { 965d9deefdfSMatthew G. Knepley if (out->edgemarkerlist[e]) { 966d9deefdfSMatthew G. Knepley const PetscInt vertices[2] = {out->edgelist[e*2+0]+numCells, out->edgelist[e*2+1]+numCells}; 967d9deefdfSMatthew G. Knepley const PetscInt *edges; 968d9deefdfSMatthew G. Knepley PetscInt numEdges; 969d9deefdfSMatthew G. Knepley 970d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dmRefined, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 971d9deefdfSMatthew G. Knepley if (numEdges != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Two vertices must cover only one edge, not %D", numEdges); 972d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dmRefined, "marker", edges[0], out->edgemarkerlist[e]);CHKERRQ(ierr); 973d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dmRefined, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 974d9deefdfSMatthew G. Knepley } 975d9deefdfSMatthew G. Knepley } 976d9deefdfSMatthew G. Knepley for (f = 0; f < out->numberoftrifaces; f++) { 977d9deefdfSMatthew G. Knepley if (out->trifacemarkerlist[f]) { 978d9deefdfSMatthew G. Knepley const PetscInt vertices[3] = {out->trifacelist[f*3+0]+numCells, out->trifacelist[f*3+1]+numCells, out->trifacelist[f*3+2]+numCells}; 979d9deefdfSMatthew G. Knepley const PetscInt *faces; 980d9deefdfSMatthew G. Knepley PetscInt numFaces; 981d9deefdfSMatthew G. Knepley 982d9deefdfSMatthew G. Knepley ierr = DMPlexGetFullJoin(*dmRefined, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 983d9deefdfSMatthew G. Knepley if (numFaces != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Three vertices must cover only one face, not %D", numFaces); 984d9deefdfSMatthew G. Knepley ierr = DMPlexSetLabelValue(*dmRefined, "marker", faces[0], out->trifacemarkerlist[f]);CHKERRQ(ierr); 985d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dmRefined, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 986d9deefdfSMatthew G. Knepley } 987d9deefdfSMatthew G. Knepley } 988d9deefdfSMatthew G. Knepley } 989d9deefdfSMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*dmRefined, PETSC_FALSE);CHKERRQ(ierr); 990d9deefdfSMatthew G. Knepley } 991d9deefdfSMatthew G. Knepley ierr = PLCDestroy(&in);CHKERRQ(ierr); 992d9deefdfSMatthew G. Knepley ierr = PLCDestroy(&out);CHKERRQ(ierr); 993d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 994d9deefdfSMatthew G. Knepley } 995d9deefdfSMatthew G. Knepley #endif /* PETSC_HAVE_CTETGEN */ 996d9deefdfSMatthew G. Knepley 997d9deefdfSMatthew G. Knepley #undef __FUNCT__ 998d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexGenerate" 999d9deefdfSMatthew G. Knepley /*@C 1000d9deefdfSMatthew G. Knepley DMPlexGenerate - Generates a mesh. 1001d9deefdfSMatthew G. Knepley 1002d9deefdfSMatthew G. Knepley Not Collective 1003d9deefdfSMatthew G. Knepley 1004d9deefdfSMatthew G. Knepley Input Parameters: 1005d9deefdfSMatthew G. Knepley + boundary - The DMPlex boundary object 1006d9deefdfSMatthew G. Knepley . name - The mesh generation package name 1007d9deefdfSMatthew G. Knepley - interpolate - Flag to create intermediate mesh elements 1008d9deefdfSMatthew G. Knepley 1009d9deefdfSMatthew G. Knepley Output Parameter: 1010d9deefdfSMatthew G. Knepley . mesh - The DMPlex object 1011d9deefdfSMatthew G. Knepley 1012d9deefdfSMatthew G. Knepley Level: intermediate 1013d9deefdfSMatthew G. Knepley 1014d9deefdfSMatthew G. Knepley .keywords: mesh, elements 1015d9deefdfSMatthew G. Knepley .seealso: DMPlexCreate(), DMRefine() 1016d9deefdfSMatthew G. Knepley @*/ 1017d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexGenerate(DM boundary, const char name[], PetscBool interpolate, DM *mesh) 1018d9deefdfSMatthew G. Knepley { 1019d9deefdfSMatthew G. Knepley PetscInt dim; 1020d9deefdfSMatthew G. Knepley char genname[1024]; 1021d9deefdfSMatthew G. Knepley PetscBool isTriangle = PETSC_FALSE, isTetgen = PETSC_FALSE, isCTetgen = PETSC_FALSE, flg; 1022d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 1023d9deefdfSMatthew G. Knepley 1024d9deefdfSMatthew G. Knepley PetscFunctionBegin; 1025d9deefdfSMatthew G. Knepley PetscValidHeaderSpecific(boundary, DM_CLASSID, 1); 1026d9deefdfSMatthew G. Knepley PetscValidLogicalCollectiveBool(boundary, interpolate, 2); 1027d9deefdfSMatthew G. Knepley ierr = DMGetDimension(boundary, &dim);CHKERRQ(ierr); 1028d9deefdfSMatthew G. Knepley ierr = PetscOptionsGetString(((PetscObject) boundary)->prefix, "-dm_plex_generator", genname, 1024, &flg);CHKERRQ(ierr); 1029d9deefdfSMatthew G. Knepley if (flg) name = genname; 1030d9deefdfSMatthew G. Knepley if (name) { 1031d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "triangle", &isTriangle);CHKERRQ(ierr); 1032d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "tetgen", &isTetgen);CHKERRQ(ierr); 1033d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "ctetgen", &isCTetgen);CHKERRQ(ierr); 1034d9deefdfSMatthew G. Knepley } 1035d9deefdfSMatthew G. Knepley switch (dim) { 1036d9deefdfSMatthew G. Knepley case 1: 1037d9deefdfSMatthew G. Knepley if (!name || isTriangle) { 1038d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TRIANGLE) 1039d9deefdfSMatthew G. Knepley ierr = DMPlexGenerate_Triangle(boundary, interpolate, mesh);CHKERRQ(ierr); 1040d9deefdfSMatthew G. Knepley #else 1041d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Mesh generation needs external package support.\nPlease reconfigure with --download-triangle."); 1042d9deefdfSMatthew G. Knepley #endif 1043d9deefdfSMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Unknown 2D mesh generation package %s", name); 1044d9deefdfSMatthew G. Knepley break; 1045d9deefdfSMatthew G. Knepley case 2: 1046d9deefdfSMatthew G. Knepley if (!name || isCTetgen) { 1047d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_CTETGEN) 1048d9deefdfSMatthew G. Knepley ierr = DMPlexGenerate_CTetgen(boundary, interpolate, mesh);CHKERRQ(ierr); 1049d9deefdfSMatthew G. Knepley #else 1050d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "CTetgen needs external package support.\nPlease reconfigure with --download-ctetgen."); 1051d9deefdfSMatthew G. Knepley #endif 1052d9deefdfSMatthew G. Knepley } else if (isTetgen) { 1053d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TETGEN) 1054d9deefdfSMatthew G. Knepley ierr = DMPlexGenerate_Tetgen(boundary, interpolate, mesh);CHKERRQ(ierr); 1055d9deefdfSMatthew G. Knepley #else 1056d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Tetgen needs external package support.\nPlease reconfigure with --with-c-language=cxx --download-tetgen."); 1057d9deefdfSMatthew G. Knepley #endif 1058d9deefdfSMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Unknown 3D mesh generation package %s", name); 1059d9deefdfSMatthew G. Knepley break; 1060d9deefdfSMatthew G. Knepley default: 1061d9deefdfSMatthew G. Knepley SETERRQ1(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Mesh generation for a dimension %d boundary is not supported.", dim); 1062d9deefdfSMatthew G. Knepley } 1063d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1064d9deefdfSMatthew G. Knepley } 1065d9deefdfSMatthew G. Knepley 1066d9deefdfSMatthew G. Knepley #undef __FUNCT__ 1067d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMRefine_Plex" 1068d9deefdfSMatthew G. Knepley PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 1069d9deefdfSMatthew G. Knepley { 1070d9deefdfSMatthew G. Knepley PetscReal refinementLimit; 1071d9deefdfSMatthew G. Knepley PetscInt dim, cStart, cEnd; 1072d9deefdfSMatthew G. Knepley char genname[1024], *name = NULL; 1073d9deefdfSMatthew G. Knepley PetscBool isUniform, isTriangle = PETSC_FALSE, isTetgen = PETSC_FALSE, isCTetgen = PETSC_FALSE, flg; 1074d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 1075d9deefdfSMatthew G. Knepley 1076d9deefdfSMatthew G. Knepley PetscFunctionBegin; 1077d9deefdfSMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 1078d9deefdfSMatthew G. Knepley if (isUniform) { 1079d9deefdfSMatthew G. Knepley CellRefiner cellRefiner; 1080d9deefdfSMatthew G. Knepley 1081d9deefdfSMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 1082d9deefdfSMatthew G. Knepley ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr); 1083d9deefdfSMatthew G. Knepley ierr = DMPlexCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 1084d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1085d9deefdfSMatthew G. Knepley } 1086d9deefdfSMatthew G. Knepley ierr = DMPlexGetRefinementLimit(dm, &refinementLimit);CHKERRQ(ierr); 1087d9deefdfSMatthew G. Knepley if (refinementLimit == 0.0) PetscFunctionReturn(0); 1088d9deefdfSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1089d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1090d9deefdfSMatthew G. Knepley ierr = PetscOptionsGetString(((PetscObject) dm)->prefix, "-dm_plex_generator", genname, 1024, &flg);CHKERRQ(ierr); 1091d9deefdfSMatthew G. Knepley if (flg) name = genname; 1092d9deefdfSMatthew G. Knepley if (name) { 1093d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "triangle", &isTriangle);CHKERRQ(ierr); 1094d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "tetgen", &isTetgen);CHKERRQ(ierr); 1095d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "ctetgen", &isCTetgen);CHKERRQ(ierr); 1096d9deefdfSMatthew G. Knepley } 1097d9deefdfSMatthew G. Knepley switch (dim) { 1098d9deefdfSMatthew G. Knepley case 2: 1099d9deefdfSMatthew G. Knepley if (!name || isTriangle) { 1100d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TRIANGLE) 1101d9deefdfSMatthew G. Knepley double *maxVolumes; 1102d9deefdfSMatthew G. Knepley PetscInt c; 1103d9deefdfSMatthew G. Knepley 1104d9deefdfSMatthew G. Knepley ierr = PetscMalloc1((cEnd - cStart), &maxVolumes);CHKERRQ(ierr); 1105d9deefdfSMatthew G. Knepley for (c = 0; c < cEnd-cStart; ++c) maxVolumes[c] = refinementLimit; 1106d9deefdfSMatthew G. Knepley ierr = DMPlexRefine_Triangle(dm, maxVolumes, dmRefined);CHKERRQ(ierr); 1107d9deefdfSMatthew G. Knepley ierr = PetscFree(maxVolumes);CHKERRQ(ierr); 1108d9deefdfSMatthew G. Knepley #else 1109d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Mesh refinement needs external package support.\nPlease reconfigure with --download-triangle."); 1110d9deefdfSMatthew G. Knepley #endif 1111d9deefdfSMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unknown 2D mesh generation package %s", name); 1112d9deefdfSMatthew G. Knepley break; 1113d9deefdfSMatthew G. Knepley case 3: 1114d9deefdfSMatthew G. Knepley if (!name || isCTetgen) { 1115d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_CTETGEN) 1116d9deefdfSMatthew G. Knepley PetscReal *maxVolumes; 1117d9deefdfSMatthew G. Knepley PetscInt c; 1118d9deefdfSMatthew G. Knepley 1119d9deefdfSMatthew G. Knepley ierr = PetscMalloc1((cEnd - cStart), &maxVolumes);CHKERRQ(ierr); 1120d9deefdfSMatthew G. Knepley for (c = 0; c < cEnd-cStart; ++c) maxVolumes[c] = refinementLimit; 1121d9deefdfSMatthew G. Knepley ierr = DMPlexRefine_CTetgen(dm, maxVolumes, dmRefined);CHKERRQ(ierr); 1122d9deefdfSMatthew G. Knepley #else 1123d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "CTetgen needs external package support.\nPlease reconfigure with --download-ctetgen."); 1124d9deefdfSMatthew G. Knepley #endif 1125d9deefdfSMatthew G. Knepley } else if (isTetgen) { 1126d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TETGEN) 1127d9deefdfSMatthew G. Knepley double *maxVolumes; 1128d9deefdfSMatthew G. Knepley PetscInt c; 1129d9deefdfSMatthew G. Knepley 1130d9deefdfSMatthew G. Knepley ierr = PetscMalloc1((cEnd - cStart), &maxVolumes);CHKERRQ(ierr); 1131d9deefdfSMatthew G. Knepley for (c = 0; c < cEnd-cStart; ++c) maxVolumes[c] = refinementLimit; 1132d9deefdfSMatthew G. Knepley ierr = DMPlexRefine_Tetgen(dm, maxVolumes, dmRefined);CHKERRQ(ierr); 1133d9deefdfSMatthew G. Knepley #else 1134d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Tetgen needs external package support.\nPlease reconfigure with --with-c-language=cxx --download-tetgen."); 1135d9deefdfSMatthew G. Knepley #endif 1136d9deefdfSMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unknown 3D mesh generation package %s", name); 1137d9deefdfSMatthew G. Knepley break; 1138d9deefdfSMatthew G. Knepley default: 1139d9deefdfSMatthew G. Knepley SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Mesh refinement in dimension %d is not supported.", dim); 1140d9deefdfSMatthew G. Knepley } 1141d9deefdfSMatthew G. Knepley ierr = DMPlexCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 1142d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1143d9deefdfSMatthew G. Knepley } 1144d9deefdfSMatthew G. Knepley 1145d9deefdfSMatthew G. Knepley #undef __FUNCT__ 1146d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMRefineHierarchy_Plex" 1147d9deefdfSMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 1148d9deefdfSMatthew G. Knepley { 1149d9deefdfSMatthew G. Knepley DM cdm = dm; 1150d9deefdfSMatthew G. Knepley PetscInt r; 1151d9deefdfSMatthew G. Knepley PetscBool isUniform; 1152d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 1153d9deefdfSMatthew G. Knepley 1154d9deefdfSMatthew G. Knepley PetscFunctionBegin; 1155d9deefdfSMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 1156d9deefdfSMatthew G. Knepley if (!isUniform) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Non-uniform refinement is incompatible with the hierarchy"); 1157d9deefdfSMatthew G. Knepley for (r = 0; r < nlevels; ++r) { 1158d9deefdfSMatthew G. Knepley CellRefiner cellRefiner; 1159d9deefdfSMatthew G. Knepley 1160d9deefdfSMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr); 1161d9deefdfSMatthew G. Knepley ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr); 1162d9deefdfSMatthew G. Knepley ierr = DMPlexSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 1163d9deefdfSMatthew G. Knepley cdm = dmRefined[r]; 1164d9deefdfSMatthew G. Knepley } 1165d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1166d9deefdfSMatthew G. Knepley } 1167d9deefdfSMatthew G. Knepley 1168d9deefdfSMatthew G. Knepley #undef __FUNCT__ 1169d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMCoarsen_Plex" 1170d9deefdfSMatthew G. Knepley PetscErrorCode DMCoarsen_Plex(DM dm, MPI_Comm comm, DM *dmCoarsened) 1171d9deefdfSMatthew G. Knepley { 1172d9deefdfSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 1173d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 1174d9deefdfSMatthew G. Knepley 1175d9deefdfSMatthew G. Knepley PetscFunctionBegin; 1176d9deefdfSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) mesh->coarseMesh);CHKERRQ(ierr); 1177d9deefdfSMatthew G. Knepley *dmCoarsened = mesh->coarseMesh; 1178d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1179d9deefdfSMatthew G. Knepley } 1180