1af0996ceSBarry Smith #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); 104606ac3a5SMatthew G. Knepley ierr = PetscFree(mesh->triangleOpts);CHKERRQ(ierr); 105606ac3a5SMatthew 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); 133606ac3a5SMatthew G. Knepley ierr = PetscFree(mesh->tetgenOpts);CHKERRQ(ierr); 134606ac3a5SMatthew 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; 209d988aadeSMatthew G. Knepley const char *labelName = "marker"; 210d9deefdfSMatthew G. Knepley struct triangulateio in; 211d9deefdfSMatthew G. Knepley struct triangulateio out; 212d988aadeSMatthew G. Knepley DMLabel label; 213d9deefdfSMatthew G. Knepley PetscInt vStart, vEnd, v, eStart, eEnd, e; 214d9deefdfSMatthew G. Knepley PetscMPIInt rank; 215d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 216d9deefdfSMatthew G. Knepley 217d9deefdfSMatthew G. Knepley PetscFunctionBegin; 218d9deefdfSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)boundary,&comm);CHKERRQ(ierr); 219d9deefdfSMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 220d9deefdfSMatthew G. Knepley ierr = InitInput_Triangle(&in);CHKERRQ(ierr); 221d9deefdfSMatthew G. Knepley ierr = InitOutput_Triangle(&out);CHKERRQ(ierr); 222d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepthStratum(boundary, 0, &vStart, &vEnd);CHKERRQ(ierr); 223c58f1c22SToby Isaac ierr = DMGetLabel(boundary, labelName, &label);CHKERRQ(ierr); 224d9deefdfSMatthew G. Knepley 225d9deefdfSMatthew G. Knepley in.numberofpoints = vEnd - vStart; 226d9deefdfSMatthew G. Knepley if (in.numberofpoints > 0) { 227d9deefdfSMatthew G. Knepley PetscSection coordSection; 228d9deefdfSMatthew G. Knepley Vec coordinates; 229d9deefdfSMatthew G. Knepley PetscScalar *array; 230d9deefdfSMatthew G. Knepley 231d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofpoints*dim, &in.pointlist);CHKERRQ(ierr); 232d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofpoints, &in.pointmarkerlist);CHKERRQ(ierr); 233d9deefdfSMatthew G. Knepley ierr = DMGetCoordinatesLocal(boundary, &coordinates);CHKERRQ(ierr); 234d9deefdfSMatthew G. Knepley ierr = DMGetCoordinateSection(boundary, &coordSection);CHKERRQ(ierr); 235d9deefdfSMatthew G. Knepley ierr = VecGetArray(coordinates, &array);CHKERRQ(ierr); 236d9deefdfSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 237d9deefdfSMatthew G. Knepley const PetscInt idx = v - vStart; 238d9deefdfSMatthew G. Knepley PetscInt off, d; 239d9deefdfSMatthew G. Knepley 240d9deefdfSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 241d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) { 242d9deefdfSMatthew G. Knepley in.pointlist[idx*dim + d] = PetscRealPart(array[off+d]); 243d9deefdfSMatthew G. Knepley } 244d988aadeSMatthew G. Knepley if (label) {ierr = DMLabelGetValue(label, v, &in.pointmarkerlist[idx]);CHKERRQ(ierr);} 245d9deefdfSMatthew G. Knepley } 246d9deefdfSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &array);CHKERRQ(ierr); 247d9deefdfSMatthew G. Knepley } 248d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(boundary, 0, &eStart, &eEnd);CHKERRQ(ierr); 249d9deefdfSMatthew G. Knepley in.numberofsegments = eEnd - eStart; 250d9deefdfSMatthew G. Knepley if (in.numberofsegments > 0) { 251d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofsegments*2, &in.segmentlist);CHKERRQ(ierr); 252d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofsegments, &in.segmentmarkerlist);CHKERRQ(ierr); 253d9deefdfSMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 254d9deefdfSMatthew G. Knepley const PetscInt idx = e - eStart; 255d9deefdfSMatthew G. Knepley const PetscInt *cone; 256d9deefdfSMatthew G. Knepley 257d9deefdfSMatthew G. Knepley ierr = DMPlexGetCone(boundary, e, &cone);CHKERRQ(ierr); 258d9deefdfSMatthew G. Knepley 259d9deefdfSMatthew G. Knepley in.segmentlist[idx*2+0] = cone[0] - vStart; 260d9deefdfSMatthew G. Knepley in.segmentlist[idx*2+1] = cone[1] - vStart; 261d9deefdfSMatthew G. Knepley 262d988aadeSMatthew G. Knepley if (label) {ierr = DMLabelGetValue(label, e, &in.segmentmarkerlist[idx]);CHKERRQ(ierr);} 263d9deefdfSMatthew G. Knepley } 264d9deefdfSMatthew G. Knepley } 265d9deefdfSMatthew G. Knepley #if 0 /* Do not currently support holes */ 266d9deefdfSMatthew G. Knepley PetscReal *holeCoords; 267d9deefdfSMatthew G. Knepley PetscInt h, d; 268d9deefdfSMatthew G. Knepley 269d9deefdfSMatthew G. Knepley ierr = DMPlexGetHoles(boundary, &in.numberofholes, &holeCords);CHKERRQ(ierr); 270d9deefdfSMatthew G. Knepley if (in.numberofholes > 0) { 271d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofholes*dim, &in.holelist);CHKERRQ(ierr); 272d9deefdfSMatthew G. Knepley for (h = 0; h < in.numberofholes; ++h) { 273d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) { 274d9deefdfSMatthew G. Knepley in.holelist[h*dim+d] = holeCoords[h*dim+d]; 275d9deefdfSMatthew G. Knepley } 276d9deefdfSMatthew G. Knepley } 277d9deefdfSMatthew G. Knepley } 278d9deefdfSMatthew G. Knepley #endif 279d9deefdfSMatthew G. Knepley if (!rank) { 280d9deefdfSMatthew G. Knepley char args[32]; 281d9deefdfSMatthew G. Knepley 282d9deefdfSMatthew G. Knepley /* Take away 'Q' for verbose output */ 283d9deefdfSMatthew G. Knepley ierr = PetscStrcpy(args, "pqezQ");CHKERRQ(ierr); 284d9deefdfSMatthew G. Knepley if (createConvexHull) {ierr = PetscStrcat(args, "c");CHKERRQ(ierr);} 285d9deefdfSMatthew G. Knepley if (constrained) {ierr = PetscStrcpy(args, "zepDQ");CHKERRQ(ierr);} 286d9deefdfSMatthew G. Knepley if (mesh->triangleOpts) {triangulate(mesh->triangleOpts, &in, &out, NULL);} 287d9deefdfSMatthew G. Knepley else {triangulate(args, &in, &out, NULL);} 288d9deefdfSMatthew G. Knepley } 289d9deefdfSMatthew G. Knepley ierr = PetscFree(in.pointlist);CHKERRQ(ierr); 290d9deefdfSMatthew G. Knepley ierr = PetscFree(in.pointmarkerlist);CHKERRQ(ierr); 291d9deefdfSMatthew G. Knepley ierr = PetscFree(in.segmentlist);CHKERRQ(ierr); 292d9deefdfSMatthew G. Knepley ierr = PetscFree(in.segmentmarkerlist);CHKERRQ(ierr); 293d9deefdfSMatthew G. Knepley ierr = PetscFree(in.holelist);CHKERRQ(ierr); 294d9deefdfSMatthew G. Knepley 295d9deefdfSMatthew G. Knepley { 296d988aadeSMatthew G. Knepley DMLabel glabel = NULL; 297d9deefdfSMatthew G. Knepley const PetscInt numCorners = 3; 298d9deefdfSMatthew G. Knepley const PetscInt numCells = out.numberoftriangles; 299d9deefdfSMatthew G. Knepley const PetscInt numVertices = out.numberofpoints; 300d9deefdfSMatthew G. Knepley const int *cells = out.trianglelist; 301d9deefdfSMatthew G. Knepley const double *meshCoords = out.pointlist; 302d9deefdfSMatthew G. Knepley 303d9deefdfSMatthew G. Knepley ierr = DMPlexCreateFromCellList(comm, dim, numCells, numVertices, numCorners, interpolate, cells, dim, meshCoords, dm);CHKERRQ(ierr); 304c58f1c22SToby Isaac if (label) {ierr = DMCreateLabel(*dm, labelName); ierr = DMGetLabel(*dm, labelName, &glabel);} 305d9deefdfSMatthew G. Knepley /* Set labels */ 306d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 307d9deefdfSMatthew G. Knepley if (out.pointmarkerlist[v]) { 308d988aadeSMatthew G. Knepley if (glabel) {ierr = DMLabelSetValue(glabel, v+numCells, out.pointmarkerlist[v]);CHKERRQ(ierr);} 309d9deefdfSMatthew G. Knepley } 310d9deefdfSMatthew G. Knepley } 311d9deefdfSMatthew G. Knepley if (interpolate) { 312d9deefdfSMatthew G. Knepley for (e = 0; e < out.numberofedges; e++) { 313d9deefdfSMatthew G. Knepley if (out.edgemarkerlist[e]) { 314d9deefdfSMatthew G. Knepley const PetscInt vertices[2] = {out.edgelist[e*2+0]+numCells, out.edgelist[e*2+1]+numCells}; 315d9deefdfSMatthew G. Knepley const PetscInt *edges; 316d9deefdfSMatthew G. Knepley PetscInt numEdges; 317d9deefdfSMatthew G. Knepley 318d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dm, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 319d9deefdfSMatthew G. Knepley if (numEdges != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Two vertices must cover only one edge, not %D", numEdges); 320d988aadeSMatthew G. Knepley if (glabel) {ierr = DMLabelSetValue(glabel, edges[0], out.edgemarkerlist[e]);CHKERRQ(ierr);} 321d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dm, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 322d9deefdfSMatthew G. Knepley } 323d9deefdfSMatthew G. Knepley } 324d9deefdfSMatthew G. Knepley } 325d9deefdfSMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*dm, PETSC_FALSE);CHKERRQ(ierr); 326d9deefdfSMatthew G. Knepley } 327d9deefdfSMatthew G. Knepley #if 0 /* Do not currently support holes */ 328d9deefdfSMatthew G. Knepley ierr = DMPlexCopyHoles(*dm, boundary);CHKERRQ(ierr); 329d9deefdfSMatthew G. Knepley #endif 330d9deefdfSMatthew G. Knepley ierr = FiniOutput_Triangle(&out);CHKERRQ(ierr); 331d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 332d9deefdfSMatthew G. Knepley } 333d9deefdfSMatthew G. Knepley 334d9deefdfSMatthew G. Knepley #undef __FUNCT__ 335d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexRefine_Triangle" 336d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexRefine_Triangle(DM dm, double *maxVolumes, DM *dmRefined) 337d9deefdfSMatthew G. Knepley { 338d9deefdfSMatthew G. Knepley MPI_Comm comm; 339d9deefdfSMatthew G. Knepley PetscInt dim = 2; 340d988aadeSMatthew G. Knepley const char *labelName = "marker"; 341d9deefdfSMatthew G. Knepley struct triangulateio in; 342d9deefdfSMatthew G. Knepley struct triangulateio out; 343d988aadeSMatthew G. Knepley DMLabel label; 344d9deefdfSMatthew G. Knepley PetscInt vStart, vEnd, v, cStart, cEnd, c, depth, depthGlobal; 345d9deefdfSMatthew G. Knepley PetscMPIInt rank; 346d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 347d9deefdfSMatthew G. Knepley 348d9deefdfSMatthew G. Knepley PetscFunctionBegin; 349d9deefdfSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 350d9deefdfSMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 351d9deefdfSMatthew G. Knepley ierr = InitInput_Triangle(&in);CHKERRQ(ierr); 352d9deefdfSMatthew G. Knepley ierr = InitOutput_Triangle(&out);CHKERRQ(ierr); 353d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 354b2566f29SBarry Smith ierr = MPIU_Allreduce(&depth, &depthGlobal, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); 355d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 356c58f1c22SToby Isaac ierr = DMGetLabel(dm, labelName, &label);CHKERRQ(ierr); 357d9deefdfSMatthew G. Knepley 358d9deefdfSMatthew G. Knepley in.numberofpoints = vEnd - vStart; 359d9deefdfSMatthew G. Knepley if (in.numberofpoints > 0) { 360d9deefdfSMatthew G. Knepley PetscSection coordSection; 361d9deefdfSMatthew G. Knepley Vec coordinates; 362d9deefdfSMatthew G. Knepley PetscScalar *array; 363d9deefdfSMatthew G. Knepley 364d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofpoints*dim, &in.pointlist);CHKERRQ(ierr); 365d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofpoints, &in.pointmarkerlist);CHKERRQ(ierr); 366d9deefdfSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 367d9deefdfSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 368d9deefdfSMatthew G. Knepley ierr = VecGetArray(coordinates, &array);CHKERRQ(ierr); 369d9deefdfSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 370d9deefdfSMatthew G. Knepley const PetscInt idx = v - vStart; 371d9deefdfSMatthew G. Knepley PetscInt off, d; 372d9deefdfSMatthew G. Knepley 373d9deefdfSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 374d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) { 375d9deefdfSMatthew G. Knepley in.pointlist[idx*dim + d] = PetscRealPart(array[off+d]); 376d9deefdfSMatthew G. Knepley } 377d988aadeSMatthew G. Knepley if (label) {ierr = DMLabelGetValue(label, v, &in.pointmarkerlist[idx]);CHKERRQ(ierr);} 378d9deefdfSMatthew G. Knepley } 379d9deefdfSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &array);CHKERRQ(ierr); 380d9deefdfSMatthew G. Knepley } 381d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 382d9deefdfSMatthew G. Knepley 383d9deefdfSMatthew G. Knepley in.numberofcorners = 3; 384d9deefdfSMatthew G. Knepley in.numberoftriangles = cEnd - cStart; 385d9deefdfSMatthew G. Knepley 386d9deefdfSMatthew G. Knepley in.trianglearealist = (double*) maxVolumes; 387d9deefdfSMatthew G. Knepley if (in.numberoftriangles > 0) { 388d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberoftriangles*in.numberofcorners, &in.trianglelist);CHKERRQ(ierr); 389d9deefdfSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 390d9deefdfSMatthew G. Knepley const PetscInt idx = c - cStart; 391d9deefdfSMatthew G. Knepley PetscInt *closure = NULL; 392d9deefdfSMatthew G. Knepley PetscInt closureSize; 393d9deefdfSMatthew G. Knepley 394d9deefdfSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 395d9deefdfSMatthew 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); 396d9deefdfSMatthew G. Knepley for (v = 0; v < 3; ++v) { 397d9deefdfSMatthew G. Knepley in.trianglelist[idx*in.numberofcorners + v] = closure[(v+closureSize-3)*2] - vStart; 398d9deefdfSMatthew G. Knepley } 399d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 400d9deefdfSMatthew G. Knepley } 401d9deefdfSMatthew G. Knepley } 402d9deefdfSMatthew G. Knepley /* TODO: Segment markers are missing on input */ 403d9deefdfSMatthew G. Knepley #if 0 /* Do not currently support holes */ 404d9deefdfSMatthew G. Knepley PetscReal *holeCoords; 405d9deefdfSMatthew G. Knepley PetscInt h, d; 406d9deefdfSMatthew G. Knepley 407d9deefdfSMatthew G. Knepley ierr = DMPlexGetHoles(boundary, &in.numberofholes, &holeCords);CHKERRQ(ierr); 408d9deefdfSMatthew G. Knepley if (in.numberofholes > 0) { 409d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in.numberofholes*dim, &in.holelist);CHKERRQ(ierr); 410d9deefdfSMatthew G. Knepley for (h = 0; h < in.numberofholes; ++h) { 411d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) { 412d9deefdfSMatthew G. Knepley in.holelist[h*dim+d] = holeCoords[h*dim+d]; 413d9deefdfSMatthew G. Knepley } 414d9deefdfSMatthew G. Knepley } 415d9deefdfSMatthew G. Knepley } 416d9deefdfSMatthew G. Knepley #endif 417d9deefdfSMatthew G. Knepley if (!rank) { 418d9deefdfSMatthew G. Knepley char args[32]; 419d9deefdfSMatthew G. Knepley 420d9deefdfSMatthew G. Knepley /* Take away 'Q' for verbose output */ 421d9deefdfSMatthew G. Knepley ierr = PetscStrcpy(args, "pqezQra");CHKERRQ(ierr); 422d9deefdfSMatthew G. Knepley triangulate(args, &in, &out, NULL); 423d9deefdfSMatthew G. Knepley } 424d9deefdfSMatthew G. Knepley ierr = PetscFree(in.pointlist);CHKERRQ(ierr); 425d9deefdfSMatthew G. Knepley ierr = PetscFree(in.pointmarkerlist);CHKERRQ(ierr); 426d9deefdfSMatthew G. Knepley ierr = PetscFree(in.segmentlist);CHKERRQ(ierr); 427d9deefdfSMatthew G. Knepley ierr = PetscFree(in.segmentmarkerlist);CHKERRQ(ierr); 428d9deefdfSMatthew G. Knepley ierr = PetscFree(in.trianglelist);CHKERRQ(ierr); 429d9deefdfSMatthew G. Knepley 430d9deefdfSMatthew G. Knepley { 431d988aadeSMatthew G. Knepley DMLabel rlabel = NULL; 432d9deefdfSMatthew G. Knepley const PetscInt numCorners = 3; 433d9deefdfSMatthew G. Knepley const PetscInt numCells = out.numberoftriangles; 434d9deefdfSMatthew G. Knepley const PetscInt numVertices = out.numberofpoints; 435d9deefdfSMatthew G. Knepley const int *cells = out.trianglelist; 436d9deefdfSMatthew G. Knepley const double *meshCoords = out.pointlist; 437d9deefdfSMatthew G. Knepley PetscBool interpolate = depthGlobal > 1 ? PETSC_TRUE : PETSC_FALSE; 438d9deefdfSMatthew G. Knepley 439d9deefdfSMatthew G. Knepley ierr = DMPlexCreateFromCellList(comm, dim, numCells, numVertices, numCorners, interpolate, cells, dim, meshCoords, dmRefined);CHKERRQ(ierr); 440c58f1c22SToby Isaac if (label) {ierr = DMCreateLabel(*dmRefined, labelName); ierr = DMGetLabel(*dmRefined, labelName, &rlabel);} 441d9deefdfSMatthew G. Knepley /* Set labels */ 442d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 443d9deefdfSMatthew G. Knepley if (out.pointmarkerlist[v]) { 444d988aadeSMatthew G. Knepley if (rlabel) {ierr = DMLabelSetValue(rlabel, v+numCells, out.pointmarkerlist[v]);CHKERRQ(ierr);} 445d9deefdfSMatthew G. Knepley } 446d9deefdfSMatthew G. Knepley } 447d9deefdfSMatthew G. Knepley if (interpolate) { 448d9deefdfSMatthew G. Knepley PetscInt e; 449d9deefdfSMatthew G. Knepley 450d9deefdfSMatthew G. Knepley for (e = 0; e < out.numberofedges; e++) { 451d9deefdfSMatthew G. Knepley if (out.edgemarkerlist[e]) { 452d9deefdfSMatthew G. Knepley const PetscInt vertices[2] = {out.edgelist[e*2+0]+numCells, out.edgelist[e*2+1]+numCells}; 453d9deefdfSMatthew G. Knepley const PetscInt *edges; 454d9deefdfSMatthew G. Knepley PetscInt numEdges; 455d9deefdfSMatthew G. Knepley 456d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dmRefined, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 457d9deefdfSMatthew G. Knepley if (numEdges != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Two vertices must cover only one edge, not %D", numEdges); 458d988aadeSMatthew G. Knepley if (rlabel) {ierr = DMLabelSetValue(rlabel, edges[0], out.edgemarkerlist[e]);CHKERRQ(ierr);} 459d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dmRefined, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 460d9deefdfSMatthew G. Knepley } 461d9deefdfSMatthew G. Knepley } 462d9deefdfSMatthew G. Knepley } 463d9deefdfSMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*dmRefined, PETSC_FALSE);CHKERRQ(ierr); 464d9deefdfSMatthew G. Knepley } 465d9deefdfSMatthew G. Knepley #if 0 /* Do not currently support holes */ 466d9deefdfSMatthew G. Knepley ierr = DMPlexCopyHoles(*dm, boundary);CHKERRQ(ierr); 467d9deefdfSMatthew G. Knepley #endif 468d9deefdfSMatthew G. Knepley ierr = FiniOutput_Triangle(&out);CHKERRQ(ierr); 469d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 470d9deefdfSMatthew G. Knepley } 471d9deefdfSMatthew G. Knepley #endif /* PETSC_HAVE_TRIANGLE */ 472d9deefdfSMatthew G. Knepley 473d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TETGEN) 474d9deefdfSMatthew G. Knepley #include <tetgen.h> 475d9deefdfSMatthew G. Knepley #undef __FUNCT__ 476d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexGenerate_Tetgen" 477d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexGenerate_Tetgen(DM boundary, PetscBool interpolate, DM *dm) 478d9deefdfSMatthew G. Knepley { 479d9deefdfSMatthew G. Knepley MPI_Comm comm; 4803d8f7108SMatthew G. Knepley DM_Plex *mesh = (DM_Plex *) boundary->data; 481d9deefdfSMatthew G. Knepley const PetscInt dim = 3; 482d988aadeSMatthew G. Knepley const char *labelName = "marker"; 483d9deefdfSMatthew G. Knepley ::tetgenio in; 484d9deefdfSMatthew G. Knepley ::tetgenio out; 485d988aadeSMatthew G. Knepley DMLabel label; 486d9deefdfSMatthew G. Knepley PetscInt vStart, vEnd, v, fStart, fEnd, f; 487d9deefdfSMatthew G. Knepley PetscMPIInt rank; 488d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 489d9deefdfSMatthew G. Knepley 490d9deefdfSMatthew G. Knepley PetscFunctionBegin; 491d9deefdfSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)boundary,&comm);CHKERRQ(ierr); 492d9deefdfSMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 493d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepthStratum(boundary, 0, &vStart, &vEnd);CHKERRQ(ierr); 494c58f1c22SToby Isaac ierr = DMGetLabel(boundary, labelName, &label);CHKERRQ(ierr); 495d988aadeSMatthew G. Knepley 496d9deefdfSMatthew G. Knepley in.numberofpoints = vEnd - vStart; 497d9deefdfSMatthew G. Knepley if (in.numberofpoints > 0) { 498d9deefdfSMatthew G. Knepley PetscSection coordSection; 499d9deefdfSMatthew G. Knepley Vec coordinates; 500d9deefdfSMatthew G. Knepley PetscScalar *array; 501d9deefdfSMatthew G. Knepley 502d9deefdfSMatthew G. Knepley in.pointlist = new double[in.numberofpoints*dim]; 503d9deefdfSMatthew G. Knepley in.pointmarkerlist = new int[in.numberofpoints]; 504d9deefdfSMatthew G. Knepley 505d9deefdfSMatthew G. Knepley ierr = DMGetCoordinatesLocal(boundary, &coordinates);CHKERRQ(ierr); 506d9deefdfSMatthew G. Knepley ierr = DMGetCoordinateSection(boundary, &coordSection);CHKERRQ(ierr); 507d9deefdfSMatthew G. Knepley ierr = VecGetArray(coordinates, &array);CHKERRQ(ierr); 508d9deefdfSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 509d9deefdfSMatthew G. Knepley const PetscInt idx = v - vStart; 510d9deefdfSMatthew G. Knepley PetscInt off, d; 511d9deefdfSMatthew G. Knepley 512d9deefdfSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 513d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) in.pointlist[idx*dim + d] = PetscRealPart(array[off+d]); 514d988aadeSMatthew G. Knepley if (label) {ierr = DMLabelGetValue(label, v, &in.pointmarkerlist[idx]);CHKERRQ(ierr);} 515d9deefdfSMatthew G. Knepley } 516d9deefdfSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &array);CHKERRQ(ierr); 517d9deefdfSMatthew G. Knepley } 518d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(boundary, 0, &fStart, &fEnd);CHKERRQ(ierr); 519d9deefdfSMatthew G. Knepley 520d9deefdfSMatthew G. Knepley in.numberoffacets = fEnd - fStart; 521d9deefdfSMatthew G. Knepley if (in.numberoffacets > 0) { 522d9deefdfSMatthew G. Knepley in.facetlist = new tetgenio::facet[in.numberoffacets]; 523d9deefdfSMatthew G. Knepley in.facetmarkerlist = new int[in.numberoffacets]; 524d9deefdfSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 525d9deefdfSMatthew G. Knepley const PetscInt idx = f - fStart; 526d9deefdfSMatthew G. Knepley PetscInt *points = NULL, numPoints, p, numVertices = 0, v; 527d9deefdfSMatthew G. Knepley 528d9deefdfSMatthew G. Knepley in.facetlist[idx].numberofpolygons = 1; 529d9deefdfSMatthew G. Knepley in.facetlist[idx].polygonlist = new tetgenio::polygon[in.facetlist[idx].numberofpolygons]; 530d9deefdfSMatthew G. Knepley in.facetlist[idx].numberofholes = 0; 531d9deefdfSMatthew G. Knepley in.facetlist[idx].holelist = NULL; 532d9deefdfSMatthew G. Knepley 533d9deefdfSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(boundary, f, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 534d9deefdfSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 535d9deefdfSMatthew G. Knepley const PetscInt point = points[p]; 536d9deefdfSMatthew G. Knepley if ((point >= vStart) && (point < vEnd)) points[numVertices++] = point; 537d9deefdfSMatthew G. Knepley } 538d9deefdfSMatthew G. Knepley 539d9deefdfSMatthew G. Knepley tetgenio::polygon *poly = in.facetlist[idx].polygonlist; 540d9deefdfSMatthew G. Knepley poly->numberofvertices = numVertices; 541d9deefdfSMatthew G. Knepley poly->vertexlist = new int[poly->numberofvertices]; 542d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 543d9deefdfSMatthew G. Knepley const PetscInt vIdx = points[v] - vStart; 544d9deefdfSMatthew G. Knepley poly->vertexlist[v] = vIdx; 545d9deefdfSMatthew G. Knepley } 546d988aadeSMatthew G. Knepley if (label) {ierr = DMLabelGetValue(label, f, &in.facetmarkerlist[idx]);CHKERRQ(ierr);} 547d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(boundary, f, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 548d9deefdfSMatthew G. Knepley } 549d9deefdfSMatthew G. Knepley } 550d9deefdfSMatthew G. Knepley if (!rank) { 551d9deefdfSMatthew G. Knepley char args[32]; 552d9deefdfSMatthew G. Knepley 553d9deefdfSMatthew G. Knepley /* Take away 'Q' for verbose output */ 554d9deefdfSMatthew G. Knepley ierr = PetscStrcpy(args, "pqezQ");CHKERRQ(ierr); 555d9deefdfSMatthew G. Knepley if (mesh->tetgenOpts) {::tetrahedralize(mesh->tetgenOpts, &in, &out);} 556d9deefdfSMatthew G. Knepley else {::tetrahedralize(args, &in, &out);} 557d9deefdfSMatthew G. Knepley } 558d9deefdfSMatthew G. Knepley { 559d988aadeSMatthew G. Knepley DMLabel glabel = NULL; 560d9deefdfSMatthew G. Knepley const PetscInt numCorners = 4; 561d9deefdfSMatthew G. Knepley const PetscInt numCells = out.numberoftetrahedra; 562d9deefdfSMatthew G. Knepley const PetscInt numVertices = out.numberofpoints; 563d9deefdfSMatthew G. Knepley const double *meshCoords = out.pointlist; 564d9deefdfSMatthew G. Knepley int *cells = out.tetrahedronlist; 565d9deefdfSMatthew G. Knepley 566d9deefdfSMatthew G. Knepley ierr = DMPlexInvertCells_Internal(dim, numCells, numCorners, cells);CHKERRQ(ierr); 567d9deefdfSMatthew G. Knepley ierr = DMPlexCreateFromCellList(comm, dim, numCells, numVertices, numCorners, interpolate, cells, dim, meshCoords, dm);CHKERRQ(ierr); 568c58f1c22SToby Isaac if (label) {ierr = DMCreateLabel(*dm, labelName); ierr = DMGetLabel(*dm, labelName, &glabel);} 569d9deefdfSMatthew G. Knepley /* Set labels */ 570d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 571d9deefdfSMatthew G. Knepley if (out.pointmarkerlist[v]) { 572d988aadeSMatthew G. Knepley if (glabel) {ierr = DMLabelSetValue(glabel, v+numCells, out.pointmarkerlist[v]);CHKERRQ(ierr);} 573d9deefdfSMatthew G. Knepley } 574d9deefdfSMatthew G. Knepley } 575d9deefdfSMatthew G. Knepley if (interpolate) { 576d9deefdfSMatthew G. Knepley PetscInt e; 577d9deefdfSMatthew G. Knepley 578d9deefdfSMatthew G. Knepley for (e = 0; e < out.numberofedges; e++) { 579d9deefdfSMatthew G. Knepley if (out.edgemarkerlist[e]) { 580d9deefdfSMatthew G. Knepley const PetscInt vertices[2] = {out.edgelist[e*2+0]+numCells, out.edgelist[e*2+1]+numCells}; 581d9deefdfSMatthew G. Knepley const PetscInt *edges; 582d9deefdfSMatthew G. Knepley PetscInt numEdges; 583d9deefdfSMatthew G. Knepley 584d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dm, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 585d9deefdfSMatthew G. Knepley if (numEdges != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Two vertices must cover only one edge, not %D", numEdges); 586d988aadeSMatthew G. Knepley if (glabel) {ierr = DMLabelSetValue(glabel, edges[0], out.edgemarkerlist[e]);CHKERRQ(ierr);} 587d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dm, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 588d9deefdfSMatthew G. Knepley } 589d9deefdfSMatthew G. Knepley } 590d9deefdfSMatthew G. Knepley for (f = 0; f < out.numberoftrifaces; f++) { 591d9deefdfSMatthew G. Knepley if (out.trifacemarkerlist[f]) { 592d9deefdfSMatthew G. Knepley const PetscInt vertices[3] = {out.trifacelist[f*3+0]+numCells, out.trifacelist[f*3+1]+numCells, out.trifacelist[f*3+2]+numCells}; 593d9deefdfSMatthew G. Knepley const PetscInt *faces; 594d9deefdfSMatthew G. Knepley PetscInt numFaces; 595d9deefdfSMatthew G. Knepley 596d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dm, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 597d9deefdfSMatthew G. Knepley if (numFaces != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Three vertices must cover only one face, not %D", numFaces); 59835b814a0SMatthew G. Knepley if (glabel) {ierr = DMLabelSetValue(glabel, faces[0], out.trifacemarkerlist[f]);CHKERRQ(ierr);} 599d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dm, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 600d9deefdfSMatthew G. Knepley } 601d9deefdfSMatthew G. Knepley } 602d9deefdfSMatthew G. Knepley } 603d9deefdfSMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*dm, PETSC_FALSE);CHKERRQ(ierr); 604d9deefdfSMatthew G. Knepley } 605d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 606d9deefdfSMatthew G. Knepley } 607d9deefdfSMatthew G. Knepley 608d9deefdfSMatthew G. Knepley #undef __FUNCT__ 609d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexRefine_Tetgen" 610d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexRefine_Tetgen(DM dm, double *maxVolumes, DM *dmRefined) 611d9deefdfSMatthew G. Knepley { 612d9deefdfSMatthew G. Knepley MPI_Comm comm; 613d9deefdfSMatthew G. Knepley const PetscInt dim = 3; 614d988aadeSMatthew G. Knepley const char *labelName = "marker"; 615d9deefdfSMatthew G. Knepley ::tetgenio in; 616d9deefdfSMatthew G. Knepley ::tetgenio out; 617d988aadeSMatthew G. Knepley DMLabel label; 618d9deefdfSMatthew G. Knepley PetscInt vStart, vEnd, v, cStart, cEnd, c, depth, depthGlobal; 619d9deefdfSMatthew G. Knepley PetscMPIInt rank; 620d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 621d9deefdfSMatthew G. Knepley 622d9deefdfSMatthew G. Knepley PetscFunctionBegin; 623d9deefdfSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 624d9deefdfSMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 625d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 626b2566f29SBarry Smith ierr = MPIU_Allreduce(&depth, &depthGlobal, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); 627d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 628c58f1c22SToby Isaac ierr = DMGetLabel(dm, labelName, &label);CHKERRQ(ierr); 629d9deefdfSMatthew G. Knepley 630d9deefdfSMatthew G. Knepley in.numberofpoints = vEnd - vStart; 631d9deefdfSMatthew G. Knepley if (in.numberofpoints > 0) { 632d9deefdfSMatthew G. Knepley PetscSection coordSection; 633d9deefdfSMatthew G. Knepley Vec coordinates; 634d9deefdfSMatthew G. Knepley PetscScalar *array; 635d9deefdfSMatthew G. Knepley 636d9deefdfSMatthew G. Knepley in.pointlist = new double[in.numberofpoints*dim]; 637d9deefdfSMatthew G. Knepley in.pointmarkerlist = new int[in.numberofpoints]; 638d9deefdfSMatthew G. Knepley 639d9deefdfSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 640d9deefdfSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 641d9deefdfSMatthew G. Knepley ierr = VecGetArray(coordinates, &array);CHKERRQ(ierr); 642d9deefdfSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 643d9deefdfSMatthew G. Knepley const PetscInt idx = v - vStart; 644d9deefdfSMatthew G. Knepley PetscInt off, d; 645d9deefdfSMatthew G. Knepley 646d9deefdfSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 647d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) in.pointlist[idx*dim + d] = PetscRealPart(array[off+d]); 648d988aadeSMatthew G. Knepley if (label) {ierr = DMLabelGetValue(label, v, &in.pointmarkerlist[idx]);CHKERRQ(ierr);} 649d9deefdfSMatthew G. Knepley } 650d9deefdfSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &array);CHKERRQ(ierr); 651d9deefdfSMatthew G. Knepley } 652d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 653d9deefdfSMatthew G. Knepley 654d9deefdfSMatthew G. Knepley in.numberofcorners = 4; 655d9deefdfSMatthew G. Knepley in.numberoftetrahedra = cEnd - cStart; 656d9deefdfSMatthew G. Knepley in.tetrahedronvolumelist = (double*) maxVolumes; 657d9deefdfSMatthew G. Knepley if (in.numberoftetrahedra > 0) { 658d9deefdfSMatthew G. Knepley in.tetrahedronlist = new int[in.numberoftetrahedra*in.numberofcorners]; 659d9deefdfSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 660d9deefdfSMatthew G. Knepley const PetscInt idx = c - cStart; 661d9deefdfSMatthew G. Knepley PetscInt *closure = NULL; 662d9deefdfSMatthew G. Knepley PetscInt closureSize; 663d9deefdfSMatthew G. Knepley 664d9deefdfSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 665d9deefdfSMatthew 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); 666d9deefdfSMatthew G. Knepley for (v = 0; v < 4; ++v) { 667d9deefdfSMatthew G. Knepley in.tetrahedronlist[idx*in.numberofcorners + v] = closure[(v+closureSize-4)*2] - vStart; 668d9deefdfSMatthew G. Knepley } 669d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 670d9deefdfSMatthew G. Knepley } 671d9deefdfSMatthew G. Knepley } 672d9deefdfSMatthew G. Knepley /* TODO: Put in boundary faces with markers */ 673d9deefdfSMatthew G. Knepley if (!rank) { 674d9deefdfSMatthew G. Knepley char args[32]; 675d9deefdfSMatthew G. Knepley 676d9deefdfSMatthew G. Knepley /* Take away 'Q' for verbose output */ 677d9deefdfSMatthew G. Knepley /*ierr = PetscStrcpy(args, "qezQra");CHKERRQ(ierr); */ 678d9deefdfSMatthew G. Knepley ierr = PetscStrcpy(args, "qezraVVVV");CHKERRQ(ierr); 679d9deefdfSMatthew G. Knepley ::tetrahedralize(args, &in, &out); 680d9deefdfSMatthew G. Knepley } 681d9deefdfSMatthew G. Knepley in.tetrahedronvolumelist = NULL; 682d9deefdfSMatthew G. Knepley 683d9deefdfSMatthew G. Knepley { 684d988aadeSMatthew G. Knepley DMLabel rlabel = NULL; 685d9deefdfSMatthew G. Knepley const PetscInt numCorners = 4; 686d9deefdfSMatthew G. Knepley const PetscInt numCells = out.numberoftetrahedra; 687d9deefdfSMatthew G. Knepley const PetscInt numVertices = out.numberofpoints; 688d9deefdfSMatthew G. Knepley const double *meshCoords = out.pointlist; 689d9deefdfSMatthew G. Knepley int *cells = out.tetrahedronlist; 690d9deefdfSMatthew G. Knepley 691d9deefdfSMatthew G. Knepley PetscBool interpolate = depthGlobal > 1 ? PETSC_TRUE : PETSC_FALSE; 692d9deefdfSMatthew G. Knepley 693d9deefdfSMatthew G. Knepley ierr = DMPlexInvertCells_Internal(dim, numCells, numCorners, cells);CHKERRQ(ierr); 694d9deefdfSMatthew G. Knepley ierr = DMPlexCreateFromCellList(comm, dim, numCells, numVertices, numCorners, interpolate, cells, dim, meshCoords, dmRefined);CHKERRQ(ierr); 695c58f1c22SToby Isaac if (label) {ierr = DMCreateLabel(*dmRefined, labelName); ierr = DMGetLabel(*dmRefined, labelName, &rlabel);} 696d9deefdfSMatthew G. Knepley /* Set labels */ 697d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 698d9deefdfSMatthew G. Knepley if (out.pointmarkerlist[v]) { 699d988aadeSMatthew G. Knepley if (rlabel) {ierr = DMLabelSetValue(rlabel, v+numCells, out.pointmarkerlist[v]);CHKERRQ(ierr);} 700d9deefdfSMatthew G. Knepley } 701d9deefdfSMatthew G. Knepley } 702d9deefdfSMatthew G. Knepley if (interpolate) { 703d9deefdfSMatthew G. Knepley PetscInt e, f; 704d9deefdfSMatthew G. Knepley 705d9deefdfSMatthew G. Knepley for (e = 0; e < out.numberofedges; e++) { 706d9deefdfSMatthew G. Knepley if (out.edgemarkerlist[e]) { 707d9deefdfSMatthew G. Knepley const PetscInt vertices[2] = {out.edgelist[e*2+0]+numCells, out.edgelist[e*2+1]+numCells}; 708d9deefdfSMatthew G. Knepley const PetscInt *edges; 709d9deefdfSMatthew G. Knepley PetscInt numEdges; 710d9deefdfSMatthew G. Knepley 711d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dmRefined, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 712d9deefdfSMatthew G. Knepley if (numEdges != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Two vertices must cover only one edge, not %D", numEdges); 713d988aadeSMatthew G. Knepley if (rlabel) {ierr = DMLabelSetValue(rlabel, edges[0], out.edgemarkerlist[e]);CHKERRQ(ierr);} 714d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dmRefined, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 715d9deefdfSMatthew G. Knepley } 716d9deefdfSMatthew G. Knepley } 717d9deefdfSMatthew G. Knepley for (f = 0; f < out.numberoftrifaces; f++) { 718d9deefdfSMatthew G. Knepley if (out.trifacemarkerlist[f]) { 719d9deefdfSMatthew G. Knepley const PetscInt vertices[3] = {out.trifacelist[f*3+0]+numCells, out.trifacelist[f*3+1]+numCells, out.trifacelist[f*3+2]+numCells}; 720d9deefdfSMatthew G. Knepley const PetscInt *faces; 721d9deefdfSMatthew G. Knepley PetscInt numFaces; 722d9deefdfSMatthew G. Knepley 723d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dmRefined, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 724d9deefdfSMatthew G. Knepley if (numFaces != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Three vertices must cover only one face, not %D", numFaces); 725d988aadeSMatthew G. Knepley if (rlabel) {ierr = DMLabelSetValue(rlabel, faces[0], out.trifacemarkerlist[f]);CHKERRQ(ierr);} 726d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dmRefined, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 727d9deefdfSMatthew G. Knepley } 728d9deefdfSMatthew G. Knepley } 729d9deefdfSMatthew G. Knepley } 730d9deefdfSMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*dmRefined, PETSC_FALSE);CHKERRQ(ierr); 731d9deefdfSMatthew G. Knepley } 732d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 733d9deefdfSMatthew G. Knepley } 734d9deefdfSMatthew G. Knepley #endif /* PETSC_HAVE_TETGEN */ 735d9deefdfSMatthew G. Knepley 736d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_CTETGEN) 737d9deefdfSMatthew G. Knepley #include <ctetgen.h> 738d9deefdfSMatthew G. Knepley 739d9deefdfSMatthew G. Knepley #undef __FUNCT__ 740d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexGenerate_CTetgen" 741d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexGenerate_CTetgen(DM boundary, PetscBool interpolate, DM *dm) 742d9deefdfSMatthew G. Knepley { 743d9deefdfSMatthew G. Knepley MPI_Comm comm; 744d9deefdfSMatthew G. Knepley const PetscInt dim = 3; 745d988aadeSMatthew G. Knepley const char *labelName = "marker"; 746d9deefdfSMatthew G. Knepley PLC *in, *out; 747d988aadeSMatthew G. Knepley DMLabel label; 748d9deefdfSMatthew G. Knepley PetscInt verbose = 0, vStart, vEnd, v, fStart, fEnd, f; 749d9deefdfSMatthew G. Knepley PetscMPIInt rank; 750d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 751d9deefdfSMatthew G. Knepley 752d9deefdfSMatthew G. Knepley PetscFunctionBegin; 753d9deefdfSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)boundary,&comm);CHKERRQ(ierr); 754c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,((PetscObject) boundary)->prefix, "-ctetgen_verbose", &verbose, NULL);CHKERRQ(ierr); 755d9deefdfSMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 756d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepthStratum(boundary, 0, &vStart, &vEnd);CHKERRQ(ierr); 757c58f1c22SToby Isaac ierr = DMGetLabel(boundary, labelName, &label);CHKERRQ(ierr); 758d9deefdfSMatthew G. Knepley ierr = PLCCreate(&in);CHKERRQ(ierr); 759d9deefdfSMatthew G. Knepley ierr = PLCCreate(&out);CHKERRQ(ierr); 760d9deefdfSMatthew G. Knepley 761d9deefdfSMatthew G. Knepley in->numberofpoints = vEnd - vStart; 762d9deefdfSMatthew G. Knepley if (in->numberofpoints > 0) { 763d9deefdfSMatthew G. Knepley PetscSection coordSection; 764d9deefdfSMatthew G. Knepley Vec coordinates; 765d9deefdfSMatthew G. Knepley PetscScalar *array; 766d9deefdfSMatthew G. Knepley 767d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberofpoints*dim, &in->pointlist);CHKERRQ(ierr); 768d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberofpoints, &in->pointmarkerlist);CHKERRQ(ierr); 769d9deefdfSMatthew G. Knepley ierr = DMGetCoordinatesLocal(boundary, &coordinates);CHKERRQ(ierr); 770d9deefdfSMatthew G. Knepley ierr = DMGetCoordinateSection(boundary, &coordSection);CHKERRQ(ierr); 771d9deefdfSMatthew G. Knepley ierr = VecGetArray(coordinates, &array);CHKERRQ(ierr); 772d9deefdfSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 773d9deefdfSMatthew G. Knepley const PetscInt idx = v - vStart; 774a9a51d2cSMatthew G. Knepley PetscInt off, d, m = -1; 775d9deefdfSMatthew G. Knepley 776d9deefdfSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 777d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) { 778d9deefdfSMatthew G. Knepley in->pointlist[idx*dim + d] = PetscRealPart(array[off+d]); 779d9deefdfSMatthew G. Knepley } 780d988aadeSMatthew G. Knepley if (label) {ierr = DMLabelGetValue(label, v, &m);CHKERRQ(ierr);} 781d9deefdfSMatthew G. Knepley 782d9deefdfSMatthew G. Knepley in->pointmarkerlist[idx] = (int) m; 783d9deefdfSMatthew G. Knepley } 784d9deefdfSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &array);CHKERRQ(ierr); 785d9deefdfSMatthew G. Knepley } 786d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(boundary, 0, &fStart, &fEnd);CHKERRQ(ierr); 787d9deefdfSMatthew G. Knepley 788d9deefdfSMatthew G. Knepley in->numberoffacets = fEnd - fStart; 789d9deefdfSMatthew G. Knepley if (in->numberoffacets > 0) { 790d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberoffacets, &in->facetlist);CHKERRQ(ierr); 791d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberoffacets, &in->facetmarkerlist);CHKERRQ(ierr); 792d9deefdfSMatthew G. Knepley for (f = fStart; f < fEnd; ++f) { 793d9deefdfSMatthew G. Knepley const PetscInt idx = f - fStart; 794a9a51d2cSMatthew G. Knepley PetscInt *points = NULL, numPoints, p, numVertices = 0, v, m = -1; 795d9deefdfSMatthew G. Knepley polygon *poly; 796d9deefdfSMatthew G. Knepley 797d9deefdfSMatthew G. Knepley in->facetlist[idx].numberofpolygons = 1; 798d9deefdfSMatthew G. Knepley 799d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->facetlist[idx].numberofpolygons, &in->facetlist[idx].polygonlist);CHKERRQ(ierr); 800d9deefdfSMatthew G. Knepley 801d9deefdfSMatthew G. Knepley in->facetlist[idx].numberofholes = 0; 802d9deefdfSMatthew G. Knepley in->facetlist[idx].holelist = NULL; 803d9deefdfSMatthew G. Knepley 804d9deefdfSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(boundary, f, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 805d9deefdfSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 806d9deefdfSMatthew G. Knepley const PetscInt point = points[p]; 807d9deefdfSMatthew G. Knepley if ((point >= vStart) && (point < vEnd)) points[numVertices++] = point; 808d9deefdfSMatthew G. Knepley } 809d9deefdfSMatthew G. Knepley 810d9deefdfSMatthew G. Knepley poly = in->facetlist[idx].polygonlist; 811d9deefdfSMatthew G. Knepley poly->numberofvertices = numVertices; 812d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(poly->numberofvertices, &poly->vertexlist);CHKERRQ(ierr); 813d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 814d9deefdfSMatthew G. Knepley const PetscInt vIdx = points[v] - vStart; 815d9deefdfSMatthew G. Knepley poly->vertexlist[v] = vIdx; 816d9deefdfSMatthew G. Knepley } 817d988aadeSMatthew G. Knepley if (label) {ierr = DMLabelGetValue(label, f, &m);CHKERRQ(ierr);} 818d9deefdfSMatthew G. Knepley in->facetmarkerlist[idx] = (int) m; 819d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(boundary, f, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 820d9deefdfSMatthew G. Knepley } 821d9deefdfSMatthew G. Knepley } 822d9deefdfSMatthew G. Knepley if (!rank) { 823d9deefdfSMatthew G. Knepley TetGenOpts t; 824d9deefdfSMatthew G. Knepley 825d9deefdfSMatthew G. Knepley ierr = TetGenOptsInitialize(&t);CHKERRQ(ierr); 826d9deefdfSMatthew G. Knepley t.in = boundary; /* Should go away */ 827d9deefdfSMatthew G. Knepley t.plc = 1; 828d9deefdfSMatthew G. Knepley t.quality = 1; 829d9deefdfSMatthew G. Knepley t.edgesout = 1; 830d9deefdfSMatthew G. Knepley t.zeroindex = 1; 831d9deefdfSMatthew G. Knepley t.quiet = 1; 832d9deefdfSMatthew G. Knepley t.verbose = verbose; 833d9deefdfSMatthew G. Knepley ierr = TetGenCheckOpts(&t);CHKERRQ(ierr); 834d9deefdfSMatthew G. Knepley ierr = TetGenTetrahedralize(&t, in, out);CHKERRQ(ierr); 835d9deefdfSMatthew G. Knepley } 836d9deefdfSMatthew G. Knepley { 837d988aadeSMatthew G. Knepley DMLabel glabel = NULL; 838d9deefdfSMatthew G. Knepley const PetscInt numCorners = 4; 839d9deefdfSMatthew G. Knepley const PetscInt numCells = out->numberoftetrahedra; 840d9deefdfSMatthew G. Knepley const PetscInt numVertices = out->numberofpoints; 841e9ccc142SToby Isaac double *meshCoords; 842d9deefdfSMatthew G. Knepley int *cells = out->tetrahedronlist; 843d9deefdfSMatthew G. Knepley 844e9ccc142SToby Isaac if (sizeof (PetscReal) == sizeof (double)) { 845e9ccc142SToby Isaac meshCoords = (double *) out->pointlist; 846e9ccc142SToby Isaac } 847e9ccc142SToby Isaac else { 848e9ccc142SToby Isaac PetscInt i; 849e9ccc142SToby Isaac 850e9ccc142SToby Isaac ierr = PetscMalloc1(3 * numVertices,&meshCoords);CHKERRQ(ierr); 851e9ccc142SToby Isaac for (i = 0; i < 3 * numVertices; i++) { 852e9ccc142SToby Isaac meshCoords[i] = (PetscReal) out->pointlist[i]; 853e9ccc142SToby Isaac } 854e9ccc142SToby Isaac } 855e9ccc142SToby Isaac 856d9deefdfSMatthew G. Knepley ierr = DMPlexInvertCells_Internal(dim, numCells, numCorners, cells);CHKERRQ(ierr); 857d9deefdfSMatthew G. Knepley ierr = DMPlexCreateFromCellList(comm, dim, numCells, numVertices, numCorners, interpolate, cells, dim, meshCoords, dm);CHKERRQ(ierr); 858e9ccc142SToby Isaac if (sizeof (PetscReal) != sizeof (double)) { 859e9ccc142SToby Isaac ierr = PetscFree(meshCoords);CHKERRQ(ierr); 860e9ccc142SToby Isaac } 861c58f1c22SToby Isaac if (label) {ierr = DMCreateLabel(*dm, labelName); ierr = DMGetLabel(*dm, labelName, &glabel);} 862d9deefdfSMatthew G. Knepley /* Set labels */ 863d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 864d9deefdfSMatthew G. Knepley if (out->pointmarkerlist[v]) { 865d988aadeSMatthew G. Knepley if (glabel) {ierr = DMLabelSetValue(glabel, v+numCells, out->pointmarkerlist[v]);CHKERRQ(ierr);} 866d9deefdfSMatthew G. Knepley } 867d9deefdfSMatthew G. Knepley } 868d9deefdfSMatthew G. Knepley if (interpolate) { 869d9deefdfSMatthew G. Knepley PetscInt e; 870d9deefdfSMatthew G. Knepley 871d9deefdfSMatthew G. Knepley for (e = 0; e < out->numberofedges; e++) { 872d9deefdfSMatthew G. Knepley if (out->edgemarkerlist[e]) { 873d9deefdfSMatthew G. Knepley const PetscInt vertices[2] = {out->edgelist[e*2+0]+numCells, out->edgelist[e*2+1]+numCells}; 874d9deefdfSMatthew G. Knepley const PetscInt *edges; 875d9deefdfSMatthew G. Knepley PetscInt numEdges; 876d9deefdfSMatthew G. Knepley 877d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dm, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 878d9deefdfSMatthew G. Knepley if (numEdges != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Two vertices must cover only one edge, not %D", numEdges); 879d988aadeSMatthew G. Knepley if (glabel) {ierr = DMLabelSetValue(glabel, edges[0], out->edgemarkerlist[e]);CHKERRQ(ierr);} 880d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dm, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 881d9deefdfSMatthew G. Knepley } 882d9deefdfSMatthew G. Knepley } 883d9deefdfSMatthew G. Knepley for (f = 0; f < out->numberoftrifaces; f++) { 884d9deefdfSMatthew G. Knepley if (out->trifacemarkerlist[f]) { 885d9deefdfSMatthew G. Knepley const PetscInt vertices[3] = {out->trifacelist[f*3+0]+numCells, out->trifacelist[f*3+1]+numCells, out->trifacelist[f*3+2]+numCells}; 886d9deefdfSMatthew G. Knepley const PetscInt *faces; 887d9deefdfSMatthew G. Knepley PetscInt numFaces; 888d9deefdfSMatthew G. Knepley 889d9deefdfSMatthew G. Knepley ierr = DMPlexGetFullJoin(*dm, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 890d9deefdfSMatthew G. Knepley if (numFaces != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Three vertices must cover only one face, not %D", numFaces); 891d988aadeSMatthew G. Knepley if (glabel) {ierr = DMLabelSetValue(glabel, faces[0], out->trifacemarkerlist[f]);CHKERRQ(ierr);} 892d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dm, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 893d9deefdfSMatthew G. Knepley } 894d9deefdfSMatthew G. Knepley } 895d9deefdfSMatthew G. Knepley } 896d9deefdfSMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*dm, PETSC_FALSE);CHKERRQ(ierr); 897d9deefdfSMatthew G. Knepley } 898d9deefdfSMatthew G. Knepley 899d9deefdfSMatthew G. Knepley ierr = PLCDestroy(&in);CHKERRQ(ierr); 900d9deefdfSMatthew G. Knepley ierr = PLCDestroy(&out);CHKERRQ(ierr); 901d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 902d9deefdfSMatthew G. Knepley } 903d9deefdfSMatthew G. Knepley 904d9deefdfSMatthew G. Knepley #undef __FUNCT__ 905d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexRefine_CTetgen" 906d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexRefine_CTetgen(DM dm, PetscReal *maxVolumes, DM *dmRefined) 907d9deefdfSMatthew G. Knepley { 908d9deefdfSMatthew G. Knepley MPI_Comm comm; 909d9deefdfSMatthew G. Knepley const PetscInt dim = 3; 910d988aadeSMatthew G. Knepley const char *labelName = "marker"; 911d9deefdfSMatthew G. Knepley PLC *in, *out; 912d988aadeSMatthew G. Knepley DMLabel label; 913d9deefdfSMatthew G. Knepley PetscInt verbose = 0, vStart, vEnd, v, cStart, cEnd, c, depth, depthGlobal; 914d9deefdfSMatthew G. Knepley PetscMPIInt rank; 915d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 916d9deefdfSMatthew G. Knepley 917d9deefdfSMatthew G. Knepley PetscFunctionBegin; 918d9deefdfSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 919c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,((PetscObject) dm)->prefix, "-ctetgen_verbose", &verbose, NULL);CHKERRQ(ierr); 920d9deefdfSMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 921d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 922b2566f29SBarry Smith ierr = MPIU_Allreduce(&depth, &depthGlobal, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); 923d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 924c58f1c22SToby Isaac ierr = DMGetLabel(dm, labelName, &label);CHKERRQ(ierr); 925d9deefdfSMatthew G. Knepley ierr = PLCCreate(&in);CHKERRQ(ierr); 926d9deefdfSMatthew G. Knepley ierr = PLCCreate(&out);CHKERRQ(ierr); 927d9deefdfSMatthew G. Knepley 928d9deefdfSMatthew G. Knepley in->numberofpoints = vEnd - vStart; 929d9deefdfSMatthew G. Knepley if (in->numberofpoints > 0) { 930d9deefdfSMatthew G. Knepley PetscSection coordSection; 931d9deefdfSMatthew G. Knepley Vec coordinates; 932d9deefdfSMatthew G. Knepley PetscScalar *array; 933d9deefdfSMatthew G. Knepley 934d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberofpoints*dim, &in->pointlist);CHKERRQ(ierr); 935d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberofpoints, &in->pointmarkerlist);CHKERRQ(ierr); 936d9deefdfSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 937d9deefdfSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 938d9deefdfSMatthew G. Knepley ierr = VecGetArray(coordinates, &array);CHKERRQ(ierr); 939d9deefdfSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 940d9deefdfSMatthew G. Knepley const PetscInt idx = v - vStart; 941a9a51d2cSMatthew G. Knepley PetscInt off, d, m = -1; 942d9deefdfSMatthew G. Knepley 943d9deefdfSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 944d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) { 945d9deefdfSMatthew G. Knepley in->pointlist[idx*dim + d] = PetscRealPart(array[off+d]); 946d9deefdfSMatthew G. Knepley } 947d988aadeSMatthew G. Knepley if (label) {ierr = DMLabelGetValue(label, v, &m);CHKERRQ(ierr);} 948d9deefdfSMatthew G. Knepley 949d9deefdfSMatthew G. Knepley in->pointmarkerlist[idx] = (int) m; 950d9deefdfSMatthew G. Knepley } 951d9deefdfSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &array);CHKERRQ(ierr); 952d9deefdfSMatthew G. Knepley } 953d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 954d9deefdfSMatthew G. Knepley 955d9deefdfSMatthew G. Knepley in->numberofcorners = 4; 956d9deefdfSMatthew G. Knepley in->numberoftetrahedra = cEnd - cStart; 957d9deefdfSMatthew G. Knepley in->tetrahedronvolumelist = maxVolumes; 958d9deefdfSMatthew G. Knepley if (in->numberoftetrahedra > 0) { 959d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberoftetrahedra*in->numberofcorners, &in->tetrahedronlist);CHKERRQ(ierr); 960d9deefdfSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 961d9deefdfSMatthew G. Knepley const PetscInt idx = c - cStart; 962d9deefdfSMatthew G. Knepley PetscInt *closure = NULL; 963d9deefdfSMatthew G. Knepley PetscInt closureSize; 964d9deefdfSMatthew G. Knepley 965d9deefdfSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 966d9deefdfSMatthew 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); 967d9deefdfSMatthew G. Knepley for (v = 0; v < 4; ++v) { 968d9deefdfSMatthew G. Knepley in->tetrahedronlist[idx*in->numberofcorners + v] = closure[(v+closureSize-4)*2] - vStart; 969d9deefdfSMatthew G. Knepley } 970d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 971d9deefdfSMatthew G. Knepley } 972d9deefdfSMatthew G. Knepley } 973d9deefdfSMatthew G. Knepley if (!rank) { 974d9deefdfSMatthew G. Knepley TetGenOpts t; 975d9deefdfSMatthew G. Knepley 976d9deefdfSMatthew G. Knepley ierr = TetGenOptsInitialize(&t);CHKERRQ(ierr); 977d9deefdfSMatthew G. Knepley 978d9deefdfSMatthew G. Knepley t.in = dm; /* Should go away */ 979d9deefdfSMatthew G. Knepley t.refine = 1; 980d9deefdfSMatthew G. Knepley t.varvolume = 1; 981d9deefdfSMatthew G. Knepley t.quality = 1; 982d9deefdfSMatthew G. Knepley t.edgesout = 1; 983d9deefdfSMatthew G. Knepley t.zeroindex = 1; 984d9deefdfSMatthew G. Knepley t.quiet = 1; 985d9deefdfSMatthew G. Knepley t.verbose = verbose; /* Change this */ 986d9deefdfSMatthew G. Knepley 987d9deefdfSMatthew G. Knepley ierr = TetGenCheckOpts(&t);CHKERRQ(ierr); 988d9deefdfSMatthew G. Knepley ierr = TetGenTetrahedralize(&t, in, out);CHKERRQ(ierr); 989d9deefdfSMatthew G. Knepley } 990d9deefdfSMatthew G. Knepley { 991d988aadeSMatthew G. Knepley DMLabel rlabel = NULL; 992d9deefdfSMatthew G. Knepley const PetscInt numCorners = 4; 993d9deefdfSMatthew G. Knepley const PetscInt numCells = out->numberoftetrahedra; 994d9deefdfSMatthew G. Knepley const PetscInt numVertices = out->numberofpoints; 995e9ccc142SToby Isaac double *meshCoords; 996d9deefdfSMatthew G. Knepley int *cells = out->tetrahedronlist; 997d9deefdfSMatthew G. Knepley PetscBool interpolate = depthGlobal > 1 ? PETSC_TRUE : PETSC_FALSE; 998d9deefdfSMatthew G. Knepley 999e9ccc142SToby Isaac if (sizeof (PetscReal) == sizeof (double)) { 1000e9ccc142SToby Isaac meshCoords = (double *) out->pointlist; 1001e9ccc142SToby Isaac } 1002e9ccc142SToby Isaac else { 1003e9ccc142SToby Isaac PetscInt i; 1004e9ccc142SToby Isaac 1005e9ccc142SToby Isaac ierr = PetscMalloc1(3 * numVertices,&meshCoords);CHKERRQ(ierr); 1006e9ccc142SToby Isaac for (i = 0; i < 3 * numVertices; i++) { 1007e9ccc142SToby Isaac meshCoords[i] = (PetscReal) out->pointlist[i]; 1008e9ccc142SToby Isaac } 1009e9ccc142SToby Isaac } 1010e9ccc142SToby Isaac 1011d9deefdfSMatthew G. Knepley ierr = DMPlexInvertCells_Internal(dim, numCells, numCorners, cells);CHKERRQ(ierr); 1012d9deefdfSMatthew G. Knepley ierr = DMPlexCreateFromCellList(comm, dim, numCells, numVertices, numCorners, interpolate, cells, dim, meshCoords, dmRefined);CHKERRQ(ierr); 1013e9ccc142SToby Isaac if (sizeof (PetscReal) != sizeof (double)) { 1014e9ccc142SToby Isaac ierr = PetscFree(meshCoords);CHKERRQ(ierr); 1015e9ccc142SToby Isaac } 1016c58f1c22SToby Isaac if (label) {ierr = DMCreateLabel(*dmRefined, labelName); ierr = DMGetLabel(*dmRefined, labelName, &rlabel);} 1017d9deefdfSMatthew G. Knepley /* Set labels */ 1018d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 1019d9deefdfSMatthew G. Knepley if (out->pointmarkerlist[v]) { 1020d988aadeSMatthew G. Knepley if (rlabel) {ierr = DMLabelSetValue(rlabel, v+numCells, out->pointmarkerlist[v]);CHKERRQ(ierr);} 1021d9deefdfSMatthew G. Knepley } 1022d9deefdfSMatthew G. Knepley } 1023d9deefdfSMatthew G. Knepley if (interpolate) { 1024d9deefdfSMatthew G. Knepley PetscInt e, f; 1025d9deefdfSMatthew G. Knepley 1026d9deefdfSMatthew G. Knepley for (e = 0; e < out->numberofedges; e++) { 1027d9deefdfSMatthew G. Knepley if (out->edgemarkerlist[e]) { 1028d9deefdfSMatthew G. Knepley const PetscInt vertices[2] = {out->edgelist[e*2+0]+numCells, out->edgelist[e*2+1]+numCells}; 1029d9deefdfSMatthew G. Knepley const PetscInt *edges; 1030d9deefdfSMatthew G. Knepley PetscInt numEdges; 1031d9deefdfSMatthew G. Knepley 1032d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dmRefined, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 1033d9deefdfSMatthew G. Knepley if (numEdges != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Two vertices must cover only one edge, not %D", numEdges); 1034d988aadeSMatthew G. Knepley if (rlabel) {ierr = DMLabelSetValue(rlabel, edges[0], out->edgemarkerlist[e]);CHKERRQ(ierr);} 1035d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dmRefined, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 1036d9deefdfSMatthew G. Knepley } 1037d9deefdfSMatthew G. Knepley } 1038d9deefdfSMatthew G. Knepley for (f = 0; f < out->numberoftrifaces; f++) { 1039d9deefdfSMatthew G. Knepley if (out->trifacemarkerlist[f]) { 1040d9deefdfSMatthew G. Knepley const PetscInt vertices[3] = {out->trifacelist[f*3+0]+numCells, out->trifacelist[f*3+1]+numCells, out->trifacelist[f*3+2]+numCells}; 1041d9deefdfSMatthew G. Knepley const PetscInt *faces; 1042d9deefdfSMatthew G. Knepley PetscInt numFaces; 1043d9deefdfSMatthew G. Knepley 1044d9deefdfSMatthew G. Knepley ierr = DMPlexGetFullJoin(*dmRefined, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 1045d9deefdfSMatthew G. Knepley if (numFaces != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Three vertices must cover only one face, not %D", numFaces); 1046d988aadeSMatthew G. Knepley if (rlabel) {ierr = DMLabelSetValue(rlabel, faces[0], out->trifacemarkerlist[f]);CHKERRQ(ierr);} 1047d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dmRefined, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 1048d9deefdfSMatthew G. Knepley } 1049d9deefdfSMatthew G. Knepley } 1050d9deefdfSMatthew G. Knepley } 1051d9deefdfSMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*dmRefined, PETSC_FALSE);CHKERRQ(ierr); 1052d9deefdfSMatthew G. Knepley } 1053d9deefdfSMatthew G. Knepley ierr = PLCDestroy(&in);CHKERRQ(ierr); 1054d9deefdfSMatthew G. Knepley ierr = PLCDestroy(&out);CHKERRQ(ierr); 1055d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1056d9deefdfSMatthew G. Knepley } 1057d9deefdfSMatthew G. Knepley #endif /* PETSC_HAVE_CTETGEN */ 1058d9deefdfSMatthew G. Knepley 1059d9deefdfSMatthew G. Knepley #undef __FUNCT__ 1060d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexGenerate" 1061d9deefdfSMatthew G. Knepley /*@C 1062d9deefdfSMatthew G. Knepley DMPlexGenerate - Generates a mesh. 1063d9deefdfSMatthew G. Knepley 1064d9deefdfSMatthew G. Knepley Not Collective 1065d9deefdfSMatthew G. Knepley 1066d9deefdfSMatthew G. Knepley Input Parameters: 1067d9deefdfSMatthew G. Knepley + boundary - The DMPlex boundary object 1068d9deefdfSMatthew G. Knepley . name - The mesh generation package name 1069d9deefdfSMatthew G. Knepley - interpolate - Flag to create intermediate mesh elements 1070d9deefdfSMatthew G. Knepley 1071d9deefdfSMatthew G. Knepley Output Parameter: 1072d9deefdfSMatthew G. Knepley . mesh - The DMPlex object 1073d9deefdfSMatthew G. Knepley 1074d9deefdfSMatthew G. Knepley Level: intermediate 1075d9deefdfSMatthew G. Knepley 1076d9deefdfSMatthew G. Knepley .keywords: mesh, elements 1077d9deefdfSMatthew G. Knepley .seealso: DMPlexCreate(), DMRefine() 1078d9deefdfSMatthew G. Knepley @*/ 1079d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexGenerate(DM boundary, const char name[], PetscBool interpolate, DM *mesh) 1080d9deefdfSMatthew G. Knepley { 1081d9deefdfSMatthew G. Knepley PetscInt dim; 1082d9deefdfSMatthew G. Knepley char genname[1024]; 1083d9deefdfSMatthew G. Knepley PetscBool isTriangle = PETSC_FALSE, isTetgen = PETSC_FALSE, isCTetgen = PETSC_FALSE, flg; 1084d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 1085d9deefdfSMatthew G. Knepley 1086d9deefdfSMatthew G. Knepley PetscFunctionBegin; 1087d9deefdfSMatthew G. Knepley PetscValidHeaderSpecific(boundary, DM_CLASSID, 1); 1088d9deefdfSMatthew G. Knepley PetscValidLogicalCollectiveBool(boundary, interpolate, 2); 1089d9deefdfSMatthew G. Knepley ierr = DMGetDimension(boundary, &dim);CHKERRQ(ierr); 1090c5929fdfSBarry Smith ierr = PetscOptionsGetString(((PetscObject) boundary)->options,((PetscObject) boundary)->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 1: 1099d9deefdfSMatthew G. Knepley if (!name || isTriangle) { 1100d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TRIANGLE) 1101d9deefdfSMatthew G. Knepley ierr = DMPlexGenerate_Triangle(boundary, interpolate, mesh);CHKERRQ(ierr); 1102d9deefdfSMatthew G. Knepley #else 1103d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Mesh generation needs external package support.\nPlease reconfigure with --download-triangle."); 1104d9deefdfSMatthew G. Knepley #endif 1105d9deefdfSMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Unknown 2D mesh generation package %s", name); 1106d9deefdfSMatthew G. Knepley break; 1107d9deefdfSMatthew G. Knepley case 2: 1108d9deefdfSMatthew G. Knepley if (!name || isCTetgen) { 1109d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_CTETGEN) 1110d9deefdfSMatthew G. Knepley ierr = DMPlexGenerate_CTetgen(boundary, interpolate, mesh);CHKERRQ(ierr); 1111d9deefdfSMatthew G. Knepley #else 1112d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "CTetgen needs external package support.\nPlease reconfigure with --download-ctetgen."); 1113d9deefdfSMatthew G. Knepley #endif 1114d9deefdfSMatthew G. Knepley } else if (isTetgen) { 1115d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TETGEN) 1116d9deefdfSMatthew G. Knepley ierr = DMPlexGenerate_Tetgen(boundary, interpolate, mesh);CHKERRQ(ierr); 1117d9deefdfSMatthew G. Knepley #else 11182ca110d9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Tetgen needs external package support.\nPlease reconfigure with --download-tetgen."); 1119d9deefdfSMatthew G. Knepley #endif 1120d9deefdfSMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Unknown 3D mesh generation package %s", name); 1121d9deefdfSMatthew G. Knepley break; 1122d9deefdfSMatthew G. Knepley default: 1123d9deefdfSMatthew G. Knepley SETERRQ1(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Mesh generation for a dimension %d boundary is not supported.", dim); 1124d9deefdfSMatthew G. Knepley } 1125d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1126d9deefdfSMatthew G. Knepley } 1127d9deefdfSMatthew G. Knepley 1128d9deefdfSMatthew G. Knepley #undef __FUNCT__ 1129*713918a9SToby Isaac #define __FUNCT__ "DMRefine_Plex_Label" 1130*713918a9SToby Isaac static PetscErrorCode DMRefine_Plex_Label(DM dm, DMLabel adaptLabel, PetscInt cStart, PetscInt cEnd, PetscReal maxVolumes[]) 1131*713918a9SToby Isaac { 1132*713918a9SToby Isaac PetscInt dim, c; 1133*713918a9SToby Isaac PetscReal refRatio; 1134*713918a9SToby Isaac PetscErrorCode ierr; 1135*713918a9SToby Isaac 1136*713918a9SToby Isaac PetscFunctionBegin; 1137*713918a9SToby Isaac ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 1138*713918a9SToby Isaac refRatio = (PetscReal) ((PetscInt) 1 << dim); 1139*713918a9SToby Isaac for (c = cStart; c < cEnd; c++) { 1140*713918a9SToby Isaac PetscReal vol; 1141*713918a9SToby Isaac PetscInt i, closureSize = 0; 1142*713918a9SToby Isaac PetscInt *closure = NULL; 1143*713918a9SToby Isaac PetscBool anyRefine = PETSC_FALSE; 1144*713918a9SToby Isaac PetscBool anyCoarsen = PETSC_FALSE; 1145*713918a9SToby Isaac 1146*713918a9SToby Isaac ierr = DMPlexGetTransitiveClosure(dm,c,PETSC_TRUE,&closureSize,&closure);CHKERRQ(ierr); 1147*713918a9SToby Isaac ierr = DMPlexRestoreTransitiveClosure(dm,c,PETSC_TRUE,&closureSize,&closure);CHKERRQ(ierr); 1148*713918a9SToby Isaac 1149*713918a9SToby Isaac ierr = DMPlexComputeCellGeometryFVM(dm,c,&vol,NULL,NULL);CHKERRQ(ierr); 1150*713918a9SToby Isaac for (i = 0; i < closureSize; i++) { 1151*713918a9SToby Isaac PetscInt point = closure[2 * i], refFlag; 1152*713918a9SToby Isaac 1153*713918a9SToby Isaac ierr = DMLabelGetValue(adaptLabel,point,&refFlag);CHKERRQ(ierr); 1154*713918a9SToby Isaac switch (refFlag) { 1155*713918a9SToby Isaac case DM_ADAPT_REFINE: 1156*713918a9SToby Isaac anyRefine = PETSC_TRUE; 1157*713918a9SToby Isaac break; 1158*713918a9SToby Isaac case DM_ADAPT_COARSEN: 1159*713918a9SToby Isaac anyCoarsen = PETSC_TRUE; 1160*713918a9SToby Isaac break; 1161*713918a9SToby Isaac case DM_ADAPT_KEEP: 1162*713918a9SToby Isaac break; 1163*713918a9SToby Isaac default: 1164*713918a9SToby Isaac SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"DMPlex does not support refinement flag %D\n",refFlag); 1165*713918a9SToby Isaac break; 1166*713918a9SToby Isaac } 1167*713918a9SToby Isaac if (anyRefine) break; 1168*713918a9SToby Isaac } 1169*713918a9SToby Isaac if (anyRefine) { 1170*713918a9SToby Isaac maxVolumes[c - cStart] = vol / refRatio; 1171*713918a9SToby Isaac } else if (anyCoarsen) { 1172*713918a9SToby Isaac maxVolumes[c - cStart] = vol * refRatio; 1173*713918a9SToby Isaac } else { 1174*713918a9SToby Isaac maxVolumes[c - cStart] = vol; 1175*713918a9SToby Isaac } 1176*713918a9SToby Isaac } 1177*713918a9SToby Isaac PetscFunctionReturn(0); 1178*713918a9SToby Isaac } 1179*713918a9SToby Isaac 1180*713918a9SToby Isaac #undef __FUNCT__ 1181d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMRefine_Plex" 1182*713918a9SToby Isaac static PetscErrorCode DMRefine_Plex_Internal(DM dm, MPI_Comm comm, DMLabel adaptLabel, DM *dmRefined) 1183d9deefdfSMatthew G. Knepley { 1184b28003e6SMatthew G. Knepley PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *); 1185d9deefdfSMatthew G. Knepley PetscReal refinementLimit; 1186d9deefdfSMatthew G. Knepley PetscInt dim, cStart, cEnd; 1187d9deefdfSMatthew G. Knepley char genname[1024], *name = NULL; 118836447a5eSToby Isaac PetscBool isUniform, isTriangle = PETSC_FALSE, isTetgen = PETSC_FALSE, isCTetgen = PETSC_FALSE, flg, localized; 1189d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 1190d9deefdfSMatthew G. Knepley 1191d9deefdfSMatthew G. Knepley PetscFunctionBegin; 119236447a5eSToby Isaac ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 1193d9deefdfSMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 1194d9deefdfSMatthew G. Knepley if (isUniform) { 1195d9deefdfSMatthew G. Knepley CellRefiner cellRefiner; 1196d9deefdfSMatthew G. Knepley 1197d9deefdfSMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 1198d9deefdfSMatthew G. Knepley ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr); 1199a6ba4734SToby Isaac ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 120036447a5eSToby Isaac if (localized) { 120136447a5eSToby Isaac ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr); 120236447a5eSToby Isaac } 1203d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1204d9deefdfSMatthew G. Knepley } 1205d9deefdfSMatthew G. Knepley ierr = DMPlexGetRefinementLimit(dm, &refinementLimit);CHKERRQ(ierr); 1206b28003e6SMatthew G. Knepley ierr = DMPlexGetRefinementFunction(dm, &refinementFunc);CHKERRQ(ierr); 1207b28003e6SMatthew G. Knepley if (refinementLimit == 0.0 && !refinementFunc) PetscFunctionReturn(0); 1208d9deefdfSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1209d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1210c5929fdfSBarry Smith ierr = PetscOptionsGetString(((PetscObject) dm)->options,((PetscObject) dm)->prefix, "-dm_plex_generator", genname, 1024, &flg);CHKERRQ(ierr); 1211d9deefdfSMatthew G. Knepley if (flg) name = genname; 1212d9deefdfSMatthew G. Knepley if (name) { 1213d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "triangle", &isTriangle);CHKERRQ(ierr); 1214d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "tetgen", &isTetgen);CHKERRQ(ierr); 1215d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "ctetgen", &isCTetgen);CHKERRQ(ierr); 1216d9deefdfSMatthew G. Knepley } 1217d9deefdfSMatthew G. Knepley switch (dim) { 1218d9deefdfSMatthew G. Knepley case 2: 1219d9deefdfSMatthew G. Knepley if (!name || isTriangle) { 1220d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TRIANGLE) 1221d9deefdfSMatthew G. Knepley double *maxVolumes; 1222d9deefdfSMatthew G. Knepley PetscInt c; 1223d9deefdfSMatthew G. Knepley 1224854ce69bSBarry Smith ierr = PetscMalloc1(cEnd - cStart, &maxVolumes);CHKERRQ(ierr); 1225*713918a9SToby Isaac if (adaptLabel) { 1226*713918a9SToby Isaac ierr = DMRefine_Plex_Label(dm,adaptLabel,cStart,cEnd,maxVolumes);CHKERRQ(ierr); 1227*713918a9SToby Isaac } else if (refinementFunc) { 1228b28003e6SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1229b28003e6SMatthew G. Knepley PetscReal vol, centroid[3]; 1230e9ccc142SToby Isaac PetscReal maxVol; 1231b28003e6SMatthew G. Knepley 1232b28003e6SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, centroid, NULL);CHKERRQ(ierr); 1233e9ccc142SToby Isaac ierr = (*refinementFunc)(centroid, &maxVol);CHKERRQ(ierr); 1234e9ccc142SToby Isaac maxVolumes[c - cStart] = (double) maxVol; 1235b28003e6SMatthew G. Knepley } 1236b28003e6SMatthew G. Knepley } else { 1237d9deefdfSMatthew G. Knepley for (c = 0; c < cEnd-cStart; ++c) maxVolumes[c] = refinementLimit; 1238b28003e6SMatthew G. Knepley } 1239d9deefdfSMatthew G. Knepley ierr = DMPlexRefine_Triangle(dm, maxVolumes, dmRefined);CHKERRQ(ierr); 1240d9deefdfSMatthew G. Knepley ierr = PetscFree(maxVolumes);CHKERRQ(ierr); 1241d9deefdfSMatthew G. Knepley #else 1242d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Mesh refinement needs external package support.\nPlease reconfigure with --download-triangle."); 1243d9deefdfSMatthew G. Knepley #endif 1244d9deefdfSMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unknown 2D mesh generation package %s", name); 1245d9deefdfSMatthew G. Knepley break; 1246d9deefdfSMatthew G. Knepley case 3: 1247d9deefdfSMatthew G. Knepley if (!name || isCTetgen) { 1248d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_CTETGEN) 1249d9deefdfSMatthew G. Knepley PetscReal *maxVolumes; 1250d9deefdfSMatthew G. Knepley PetscInt c; 1251d9deefdfSMatthew G. Knepley 1252854ce69bSBarry Smith ierr = PetscMalloc1(cEnd - cStart, &maxVolumes);CHKERRQ(ierr); 1253*713918a9SToby Isaac if (adaptLabel) { 1254*713918a9SToby Isaac ierr = DMRefine_Plex_Label(dm,adaptLabel,cStart,cEnd,maxVolumes);CHKERRQ(ierr); 1255*713918a9SToby Isaac } else if (refinementFunc) { 1256b28003e6SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1257b28003e6SMatthew G. Knepley PetscReal vol, centroid[3]; 1258b28003e6SMatthew G. Knepley 1259b28003e6SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, centroid, NULL);CHKERRQ(ierr); 1260b28003e6SMatthew G. Knepley ierr = (*refinementFunc)(centroid, &maxVolumes[c-cStart]);CHKERRQ(ierr); 1261b28003e6SMatthew G. Knepley } 1262b28003e6SMatthew G. Knepley } else { 1263d9deefdfSMatthew G. Knepley for (c = 0; c < cEnd-cStart; ++c) maxVolumes[c] = refinementLimit; 1264b28003e6SMatthew G. Knepley } 1265d9deefdfSMatthew G. Knepley ierr = DMPlexRefine_CTetgen(dm, maxVolumes, dmRefined);CHKERRQ(ierr); 1266d9deefdfSMatthew G. Knepley #else 1267d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "CTetgen needs external package support.\nPlease reconfigure with --download-ctetgen."); 1268d9deefdfSMatthew G. Knepley #endif 1269d9deefdfSMatthew G. Knepley } else if (isTetgen) { 1270d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TETGEN) 1271d9deefdfSMatthew G. Knepley double *maxVolumes; 1272d9deefdfSMatthew G. Knepley PetscInt c; 1273d9deefdfSMatthew G. Knepley 1274854ce69bSBarry Smith ierr = PetscMalloc1(cEnd - cStart, &maxVolumes);CHKERRQ(ierr); 1275*713918a9SToby Isaac if (adaptLabel) { 1276*713918a9SToby Isaac ierr = DMRefine_Plex_Label(dm,adaptLabel,cStart,cEnd,maxVolumes);CHKERRQ(ierr); 1277*713918a9SToby Isaac } else if (refinementFunc) { 1278b28003e6SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1279b28003e6SMatthew G. Knepley PetscReal vol, centroid[3]; 1280b28003e6SMatthew G. Knepley 1281b28003e6SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, centroid, NULL);CHKERRQ(ierr); 1282b28003e6SMatthew G. Knepley ierr = (*refinementFunc)(centroid, &maxVolumes[c-cStart]);CHKERRQ(ierr); 1283b28003e6SMatthew G. Knepley } 1284b28003e6SMatthew G. Knepley } else { 1285d9deefdfSMatthew G. Knepley for (c = 0; c < cEnd-cStart; ++c) maxVolumes[c] = refinementLimit; 1286b28003e6SMatthew G. Knepley } 1287d9deefdfSMatthew G. Knepley ierr = DMPlexRefine_Tetgen(dm, maxVolumes, dmRefined);CHKERRQ(ierr); 1288d9deefdfSMatthew G. Knepley #else 1289d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Tetgen needs external package support.\nPlease reconfigure with --with-c-language=cxx --download-tetgen."); 1290d9deefdfSMatthew G. Knepley #endif 1291d9deefdfSMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unknown 3D mesh generation package %s", name); 1292d9deefdfSMatthew G. Knepley break; 1293d9deefdfSMatthew G. Knepley default: 1294d9deefdfSMatthew G. Knepley SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Mesh refinement in dimension %d is not supported.", dim); 1295d9deefdfSMatthew G. Knepley } 1296a6ba4734SToby Isaac ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 129736447a5eSToby Isaac if (localized) { 129836447a5eSToby Isaac ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr); 129936447a5eSToby Isaac } 1300d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1301d9deefdfSMatthew G. Knepley } 1302d9deefdfSMatthew G. Knepley 1303d9deefdfSMatthew G. Knepley #undef __FUNCT__ 1304*713918a9SToby Isaac #define __FUNCT__ "DMRefine_Plex" 1305*713918a9SToby Isaac PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 1306*713918a9SToby Isaac { 1307*713918a9SToby Isaac PetscErrorCode ierr; 1308*713918a9SToby Isaac 1309*713918a9SToby Isaac PetscFunctionBegin; 1310*713918a9SToby Isaac ierr = DMRefine_Plex_Internal(dm,comm,NULL,dmRefined);CHKERRQ(ierr); 1311*713918a9SToby Isaac PetscFunctionReturn(0); 1312*713918a9SToby Isaac } 1313*713918a9SToby Isaac 1314*713918a9SToby Isaac #undef __FUNCT__ 1315*713918a9SToby Isaac #define __FUNCT__ "DMAdaptLabel_Plex" 1316*713918a9SToby Isaac PetscErrorCode DMAdaptLabel_Plex(DM dm, DMLabel adaptLabel, DM *dmAdapted) 1317*713918a9SToby Isaac { 1318*713918a9SToby Isaac PetscInt defFlag, minFlag, maxFlag, numFlags, i; 1319*713918a9SToby Isaac const PetscInt *flags; 1320*713918a9SToby Isaac IS flagIS; 1321*713918a9SToby Isaac PetscErrorCode ierr; 1322*713918a9SToby Isaac 1323*713918a9SToby Isaac PetscFunctionBegin; 1324*713918a9SToby Isaac ierr = DMLabelGetDefaultValue(adaptLabel,&defFlag);CHKERRQ(ierr); 1325*713918a9SToby Isaac minFlag = defFlag; 1326*713918a9SToby Isaac maxFlag = defFlag; 1327*713918a9SToby Isaac ierr = DMLabelGetValueIS(adaptLabel,&flagIS);CHKERRQ(ierr); 1328*713918a9SToby Isaac ierr = ISGetLocalSize(flagIS,&numFlags);CHKERRQ(ierr); 1329*713918a9SToby Isaac ierr = ISGetIndices(flagIS,&flags);CHKERRQ(ierr); 1330*713918a9SToby Isaac for (i = 0; i < numFlags; i++) { 1331*713918a9SToby Isaac PetscInt flag = flags[i]; 1332*713918a9SToby Isaac 1333*713918a9SToby Isaac minFlag = PetscMin(minFlag,flag); 1334*713918a9SToby Isaac maxFlag = PetscMax(maxFlag,flag); 1335*713918a9SToby Isaac } 1336*713918a9SToby Isaac ierr = ISRestoreIndices(flagIS,&flags);CHKERRQ(ierr); 1337*713918a9SToby Isaac ierr = ISDestroy(&flagIS);CHKERRQ(ierr); 1338*713918a9SToby Isaac { 1339*713918a9SToby Isaac PetscInt minMaxFlag[2] = {minFlag, -maxFlag}; 1340*713918a9SToby Isaac PetscInt minMaxFlagGlobal[2]; 1341*713918a9SToby Isaac 1342*713918a9SToby Isaac ierr = MPI_Allreduce(minMaxFlag,minMaxFlagGlobal,2,MPIU_INT,MPI_MIN,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 1343*713918a9SToby Isaac minFlag = minMaxFlagGlobal[0]; 1344*713918a9SToby Isaac maxFlag = -minMaxFlagGlobal[1]; 1345*713918a9SToby Isaac } 1346*713918a9SToby Isaac if (minFlag == maxFlag) { 1347*713918a9SToby Isaac switch (minFlag) { 1348*713918a9SToby Isaac case DM_ADAPT_KEEP: 1349*713918a9SToby Isaac *dmAdapted = NULL; 1350*713918a9SToby Isaac break; 1351*713918a9SToby Isaac case DM_ADAPT_REFINE: 1352*713918a9SToby Isaac ierr = DMPlexSetRefinementUniform(dm,PETSC_TRUE);CHKERRQ(ierr); 1353*713918a9SToby Isaac ierr = DMRefine(dm,MPI_COMM_NULL,dmAdapted);CHKERRQ(ierr); 1354*713918a9SToby Isaac break; 1355*713918a9SToby Isaac case DM_ADAPT_COARSEN: 1356*713918a9SToby Isaac ierr = DMCoarsen(dm,MPI_COMM_NULL,dmAdapted);CHKERRQ(ierr); 1357*713918a9SToby Isaac break; 1358*713918a9SToby Isaac default: 1359*713918a9SToby Isaac SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"DMPlex does not support refinement flag %D\n",minFlag); 1360*713918a9SToby Isaac break; 1361*713918a9SToby Isaac } 1362*713918a9SToby Isaac } else { 1363*713918a9SToby Isaac ierr = DMPlexSetRefinementUniform(dm,PETSC_FALSE);CHKERRQ(ierr); 1364*713918a9SToby Isaac ierr = DMRefine_Plex_Internal(dm,MPI_COMM_NULL,adaptLabel,dmAdapted);CHKERRQ(ierr); 1365*713918a9SToby Isaac } 1366*713918a9SToby Isaac PetscFunctionReturn(0); 1367*713918a9SToby Isaac } 1368*713918a9SToby Isaac 1369*713918a9SToby Isaac #undef __FUNCT__ 1370d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMRefineHierarchy_Plex" 1371d9deefdfSMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 1372d9deefdfSMatthew G. Knepley { 1373d9deefdfSMatthew G. Knepley DM cdm = dm; 1374d9deefdfSMatthew G. Knepley PetscInt r; 137536447a5eSToby Isaac PetscBool isUniform, localized; 1376d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 1377d9deefdfSMatthew G. Knepley 1378d9deefdfSMatthew G. Knepley PetscFunctionBegin; 1379d9deefdfSMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 138036447a5eSToby Isaac ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 1381d9deefdfSMatthew G. Knepley if (!isUniform) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Non-uniform refinement is incompatible with the hierarchy"); 1382d9deefdfSMatthew G. Knepley for (r = 0; r < nlevels; ++r) { 1383d9deefdfSMatthew G. Knepley CellRefiner cellRefiner; 1384d9deefdfSMatthew G. Knepley 1385d9deefdfSMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr); 1386d9deefdfSMatthew G. Knepley ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr); 1387a6ba4734SToby Isaac ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 138836447a5eSToby Isaac if (localized) { 138936447a5eSToby Isaac ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr); 139036447a5eSToby Isaac } 1391a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 13920aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 1393d9deefdfSMatthew G. Knepley cdm = dmRefined[r]; 1394d9deefdfSMatthew G. Knepley } 1395d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1396d9deefdfSMatthew G. Knepley } 1397