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; 841d9deefdfSMatthew G. Knepley const double *meshCoords = out->pointlist; 842d9deefdfSMatthew G. Knepley int *cells = out->tetrahedronlist; 843d9deefdfSMatthew G. Knepley 844d9deefdfSMatthew G. Knepley ierr = DMPlexInvertCells_Internal(dim, numCells, numCorners, cells);CHKERRQ(ierr); 845d9deefdfSMatthew G. Knepley ierr = DMPlexCreateFromCellList(comm, dim, numCells, numVertices, numCorners, interpolate, cells, dim, meshCoords, dm);CHKERRQ(ierr); 846c58f1c22SToby Isaac if (label) {ierr = DMCreateLabel(*dm, labelName); ierr = DMGetLabel(*dm, labelName, &glabel);} 847d9deefdfSMatthew G. Knepley /* Set labels */ 848d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 849d9deefdfSMatthew G. Knepley if (out->pointmarkerlist[v]) { 850d988aadeSMatthew G. Knepley if (glabel) {ierr = DMLabelSetValue(glabel, v+numCells, out->pointmarkerlist[v]);CHKERRQ(ierr);} 851d9deefdfSMatthew G. Knepley } 852d9deefdfSMatthew G. Knepley } 853d9deefdfSMatthew G. Knepley if (interpolate) { 854d9deefdfSMatthew G. Knepley PetscInt e; 855d9deefdfSMatthew G. Knepley 856d9deefdfSMatthew G. Knepley for (e = 0; e < out->numberofedges; e++) { 857d9deefdfSMatthew G. Knepley if (out->edgemarkerlist[e]) { 858d9deefdfSMatthew G. Knepley const PetscInt vertices[2] = {out->edgelist[e*2+0]+numCells, out->edgelist[e*2+1]+numCells}; 859d9deefdfSMatthew G. Knepley const PetscInt *edges; 860d9deefdfSMatthew G. Knepley PetscInt numEdges; 861d9deefdfSMatthew G. Knepley 862d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dm, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 863d9deefdfSMatthew G. Knepley if (numEdges != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Two vertices must cover only one edge, not %D", numEdges); 864d988aadeSMatthew G. Knepley if (glabel) {ierr = DMLabelSetValue(glabel, edges[0], out->edgemarkerlist[e]);CHKERRQ(ierr);} 865d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dm, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 866d9deefdfSMatthew G. Knepley } 867d9deefdfSMatthew G. Knepley } 868d9deefdfSMatthew G. Knepley for (f = 0; f < out->numberoftrifaces; f++) { 869d9deefdfSMatthew G. Knepley if (out->trifacemarkerlist[f]) { 870d9deefdfSMatthew G. Knepley const PetscInt vertices[3] = {out->trifacelist[f*3+0]+numCells, out->trifacelist[f*3+1]+numCells, out->trifacelist[f*3+2]+numCells}; 871d9deefdfSMatthew G. Knepley const PetscInt *faces; 872d9deefdfSMatthew G. Knepley PetscInt numFaces; 873d9deefdfSMatthew G. Knepley 874d9deefdfSMatthew G. Knepley ierr = DMPlexGetFullJoin(*dm, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 875d9deefdfSMatthew G. Knepley if (numFaces != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Three vertices must cover only one face, not %D", numFaces); 876d988aadeSMatthew G. Knepley if (glabel) {ierr = DMLabelSetValue(glabel, faces[0], out->trifacemarkerlist[f]);CHKERRQ(ierr);} 877d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dm, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 878d9deefdfSMatthew G. Knepley } 879d9deefdfSMatthew G. Knepley } 880d9deefdfSMatthew G. Knepley } 881d9deefdfSMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*dm, PETSC_FALSE);CHKERRQ(ierr); 882d9deefdfSMatthew G. Knepley } 883d9deefdfSMatthew G. Knepley 884d9deefdfSMatthew G. Knepley ierr = PLCDestroy(&in);CHKERRQ(ierr); 885d9deefdfSMatthew G. Knepley ierr = PLCDestroy(&out);CHKERRQ(ierr); 886d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 887d9deefdfSMatthew G. Knepley } 888d9deefdfSMatthew G. Knepley 889d9deefdfSMatthew G. Knepley #undef __FUNCT__ 890d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexRefine_CTetgen" 891d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexRefine_CTetgen(DM dm, PetscReal *maxVolumes, DM *dmRefined) 892d9deefdfSMatthew G. Knepley { 893d9deefdfSMatthew G. Knepley MPI_Comm comm; 894d9deefdfSMatthew G. Knepley const PetscInt dim = 3; 895d988aadeSMatthew G. Knepley const char *labelName = "marker"; 896d9deefdfSMatthew G. Knepley PLC *in, *out; 897d988aadeSMatthew G. Knepley DMLabel label; 898d9deefdfSMatthew G. Knepley PetscInt verbose = 0, vStart, vEnd, v, cStart, cEnd, c, depth, depthGlobal; 899d9deefdfSMatthew G. Knepley PetscMPIInt rank; 900d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 901d9deefdfSMatthew G. Knepley 902d9deefdfSMatthew G. Knepley PetscFunctionBegin; 903d9deefdfSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 904c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,((PetscObject) dm)->prefix, "-ctetgen_verbose", &verbose, NULL);CHKERRQ(ierr); 905d9deefdfSMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 906d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 907b2566f29SBarry Smith ierr = MPIU_Allreduce(&depth, &depthGlobal, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); 908d9deefdfSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 909c58f1c22SToby Isaac ierr = DMGetLabel(dm, labelName, &label);CHKERRQ(ierr); 910d9deefdfSMatthew G. Knepley ierr = PLCCreate(&in);CHKERRQ(ierr); 911d9deefdfSMatthew G. Knepley ierr = PLCCreate(&out);CHKERRQ(ierr); 912d9deefdfSMatthew G. Knepley 913d9deefdfSMatthew G. Knepley in->numberofpoints = vEnd - vStart; 914d9deefdfSMatthew G. Knepley if (in->numberofpoints > 0) { 915d9deefdfSMatthew G. Knepley PetscSection coordSection; 916d9deefdfSMatthew G. Knepley Vec coordinates; 917d9deefdfSMatthew G. Knepley PetscScalar *array; 918d9deefdfSMatthew G. Knepley 919d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberofpoints*dim, &in->pointlist);CHKERRQ(ierr); 920d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberofpoints, &in->pointmarkerlist);CHKERRQ(ierr); 921d9deefdfSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 922d9deefdfSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 923d9deefdfSMatthew G. Knepley ierr = VecGetArray(coordinates, &array);CHKERRQ(ierr); 924d9deefdfSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 925d9deefdfSMatthew G. Knepley const PetscInt idx = v - vStart; 926a9a51d2cSMatthew G. Knepley PetscInt off, d, m = -1; 927d9deefdfSMatthew G. Knepley 928d9deefdfSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 929d9deefdfSMatthew G. Knepley for (d = 0; d < dim; ++d) { 930d9deefdfSMatthew G. Knepley in->pointlist[idx*dim + d] = PetscRealPart(array[off+d]); 931d9deefdfSMatthew G. Knepley } 932d988aadeSMatthew G. Knepley if (label) {ierr = DMLabelGetValue(label, v, &m);CHKERRQ(ierr);} 933d9deefdfSMatthew G. Knepley 934d9deefdfSMatthew G. Knepley in->pointmarkerlist[idx] = (int) m; 935d9deefdfSMatthew G. Knepley } 936d9deefdfSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &array);CHKERRQ(ierr); 937d9deefdfSMatthew G. Knepley } 938d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 939d9deefdfSMatthew G. Knepley 940d9deefdfSMatthew G. Knepley in->numberofcorners = 4; 941d9deefdfSMatthew G. Knepley in->numberoftetrahedra = cEnd - cStart; 942d9deefdfSMatthew G. Knepley in->tetrahedronvolumelist = maxVolumes; 943d9deefdfSMatthew G. Knepley if (in->numberoftetrahedra > 0) { 944d9deefdfSMatthew G. Knepley ierr = PetscMalloc1(in->numberoftetrahedra*in->numberofcorners, &in->tetrahedronlist);CHKERRQ(ierr); 945d9deefdfSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 946d9deefdfSMatthew G. Knepley const PetscInt idx = c - cStart; 947d9deefdfSMatthew G. Knepley PetscInt *closure = NULL; 948d9deefdfSMatthew G. Knepley PetscInt closureSize; 949d9deefdfSMatthew G. Knepley 950d9deefdfSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 951d9deefdfSMatthew 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); 952d9deefdfSMatthew G. Knepley for (v = 0; v < 4; ++v) { 953d9deefdfSMatthew G. Knepley in->tetrahedronlist[idx*in->numberofcorners + v] = closure[(v+closureSize-4)*2] - vStart; 954d9deefdfSMatthew G. Knepley } 955d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 956d9deefdfSMatthew G. Knepley } 957d9deefdfSMatthew G. Knepley } 958d9deefdfSMatthew G. Knepley if (!rank) { 959d9deefdfSMatthew G. Knepley TetGenOpts t; 960d9deefdfSMatthew G. Knepley 961d9deefdfSMatthew G. Knepley ierr = TetGenOptsInitialize(&t);CHKERRQ(ierr); 962d9deefdfSMatthew G. Knepley 963d9deefdfSMatthew G. Knepley t.in = dm; /* Should go away */ 964d9deefdfSMatthew G. Knepley t.refine = 1; 965d9deefdfSMatthew G. Knepley t.varvolume = 1; 966d9deefdfSMatthew G. Knepley t.quality = 1; 967d9deefdfSMatthew G. Knepley t.edgesout = 1; 968d9deefdfSMatthew G. Knepley t.zeroindex = 1; 969d9deefdfSMatthew G. Knepley t.quiet = 1; 970d9deefdfSMatthew G. Knepley t.verbose = verbose; /* Change this */ 971d9deefdfSMatthew G. Knepley 972d9deefdfSMatthew G. Knepley ierr = TetGenCheckOpts(&t);CHKERRQ(ierr); 973d9deefdfSMatthew G. Knepley ierr = TetGenTetrahedralize(&t, in, out);CHKERRQ(ierr); 974d9deefdfSMatthew G. Knepley } 975d9deefdfSMatthew G. Knepley { 976d988aadeSMatthew G. Knepley DMLabel rlabel = NULL; 977d9deefdfSMatthew G. Knepley const PetscInt numCorners = 4; 978d9deefdfSMatthew G. Knepley const PetscInt numCells = out->numberoftetrahedra; 979d9deefdfSMatthew G. Knepley const PetscInt numVertices = out->numberofpoints; 980d9deefdfSMatthew G. Knepley const double *meshCoords = out->pointlist; 981d9deefdfSMatthew G. Knepley int *cells = out->tetrahedronlist; 982d9deefdfSMatthew G. Knepley PetscBool interpolate = depthGlobal > 1 ? PETSC_TRUE : PETSC_FALSE; 983d9deefdfSMatthew G. Knepley 984d9deefdfSMatthew G. Knepley ierr = DMPlexInvertCells_Internal(dim, numCells, numCorners, cells);CHKERRQ(ierr); 985d9deefdfSMatthew G. Knepley ierr = DMPlexCreateFromCellList(comm, dim, numCells, numVertices, numCorners, interpolate, cells, dim, meshCoords, dmRefined);CHKERRQ(ierr); 986c58f1c22SToby Isaac if (label) {ierr = DMCreateLabel(*dmRefined, labelName); ierr = DMGetLabel(*dmRefined, labelName, &rlabel);} 987d9deefdfSMatthew G. Knepley /* Set labels */ 988d9deefdfSMatthew G. Knepley for (v = 0; v < numVertices; ++v) { 989d9deefdfSMatthew G. Knepley if (out->pointmarkerlist[v]) { 990d988aadeSMatthew G. Knepley if (rlabel) {ierr = DMLabelSetValue(rlabel, v+numCells, out->pointmarkerlist[v]);CHKERRQ(ierr);} 991d9deefdfSMatthew G. Knepley } 992d9deefdfSMatthew G. Knepley } 993d9deefdfSMatthew G. Knepley if (interpolate) { 994d9deefdfSMatthew G. Knepley PetscInt e, f; 995d9deefdfSMatthew G. Knepley 996d9deefdfSMatthew G. Knepley for (e = 0; e < out->numberofedges; e++) { 997d9deefdfSMatthew G. Knepley if (out->edgemarkerlist[e]) { 998d9deefdfSMatthew G. Knepley const PetscInt vertices[2] = {out->edgelist[e*2+0]+numCells, out->edgelist[e*2+1]+numCells}; 999d9deefdfSMatthew G. Knepley const PetscInt *edges; 1000d9deefdfSMatthew G. Knepley PetscInt numEdges; 1001d9deefdfSMatthew G. Knepley 1002d9deefdfSMatthew G. Knepley ierr = DMPlexGetJoin(*dmRefined, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 1003d9deefdfSMatthew G. Knepley if (numEdges != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Two vertices must cover only one edge, not %D", numEdges); 1004d988aadeSMatthew G. Knepley if (rlabel) {ierr = DMLabelSetValue(rlabel, edges[0], out->edgemarkerlist[e]);CHKERRQ(ierr);} 1005d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dmRefined, 2, vertices, &numEdges, &edges);CHKERRQ(ierr); 1006d9deefdfSMatthew G. Knepley } 1007d9deefdfSMatthew G. Knepley } 1008d9deefdfSMatthew G. Knepley for (f = 0; f < out->numberoftrifaces; f++) { 1009d9deefdfSMatthew G. Knepley if (out->trifacemarkerlist[f]) { 1010d9deefdfSMatthew G. Knepley const PetscInt vertices[3] = {out->trifacelist[f*3+0]+numCells, out->trifacelist[f*3+1]+numCells, out->trifacelist[f*3+2]+numCells}; 1011d9deefdfSMatthew G. Knepley const PetscInt *faces; 1012d9deefdfSMatthew G. Knepley PetscInt numFaces; 1013d9deefdfSMatthew G. Knepley 1014d9deefdfSMatthew G. Knepley ierr = DMPlexGetFullJoin(*dmRefined, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 1015d9deefdfSMatthew G. Knepley if (numFaces != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Three vertices must cover only one face, not %D", numFaces); 1016d988aadeSMatthew G. Knepley if (rlabel) {ierr = DMLabelSetValue(rlabel, faces[0], out->trifacemarkerlist[f]);CHKERRQ(ierr);} 1017d9deefdfSMatthew G. Knepley ierr = DMPlexRestoreJoin(*dmRefined, 3, vertices, &numFaces, &faces);CHKERRQ(ierr); 1018d9deefdfSMatthew G. Knepley } 1019d9deefdfSMatthew G. Knepley } 1020d9deefdfSMatthew G. Knepley } 1021d9deefdfSMatthew G. Knepley ierr = DMPlexSetRefinementUniform(*dmRefined, PETSC_FALSE);CHKERRQ(ierr); 1022d9deefdfSMatthew G. Knepley } 1023d9deefdfSMatthew G. Knepley ierr = PLCDestroy(&in);CHKERRQ(ierr); 1024d9deefdfSMatthew G. Knepley ierr = PLCDestroy(&out);CHKERRQ(ierr); 1025d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1026d9deefdfSMatthew G. Knepley } 1027d9deefdfSMatthew G. Knepley #endif /* PETSC_HAVE_CTETGEN */ 1028d9deefdfSMatthew G. Knepley 1029d9deefdfSMatthew G. Knepley #undef __FUNCT__ 1030d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMPlexGenerate" 1031d9deefdfSMatthew G. Knepley /*@C 1032d9deefdfSMatthew G. Knepley DMPlexGenerate - Generates a mesh. 1033d9deefdfSMatthew G. Knepley 1034d9deefdfSMatthew G. Knepley Not Collective 1035d9deefdfSMatthew G. Knepley 1036d9deefdfSMatthew G. Knepley Input Parameters: 1037d9deefdfSMatthew G. Knepley + boundary - The DMPlex boundary object 1038d9deefdfSMatthew G. Knepley . name - The mesh generation package name 1039d9deefdfSMatthew G. Knepley - interpolate - Flag to create intermediate mesh elements 1040d9deefdfSMatthew G. Knepley 1041d9deefdfSMatthew G. Knepley Output Parameter: 1042d9deefdfSMatthew G. Knepley . mesh - The DMPlex object 1043d9deefdfSMatthew G. Knepley 1044d9deefdfSMatthew G. Knepley Level: intermediate 1045d9deefdfSMatthew G. Knepley 1046d9deefdfSMatthew G. Knepley .keywords: mesh, elements 1047d9deefdfSMatthew G. Knepley .seealso: DMPlexCreate(), DMRefine() 1048d9deefdfSMatthew G. Knepley @*/ 1049d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexGenerate(DM boundary, const char name[], PetscBool interpolate, DM *mesh) 1050d9deefdfSMatthew G. Knepley { 1051d9deefdfSMatthew G. Knepley PetscInt dim; 1052d9deefdfSMatthew G. Knepley char genname[1024]; 1053d9deefdfSMatthew G. Knepley PetscBool isTriangle = PETSC_FALSE, isTetgen = PETSC_FALSE, isCTetgen = PETSC_FALSE, flg; 1054d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 1055d9deefdfSMatthew G. Knepley 1056d9deefdfSMatthew G. Knepley PetscFunctionBegin; 1057d9deefdfSMatthew G. Knepley PetscValidHeaderSpecific(boundary, DM_CLASSID, 1); 1058d9deefdfSMatthew G. Knepley PetscValidLogicalCollectiveBool(boundary, interpolate, 2); 1059d9deefdfSMatthew G. Knepley ierr = DMGetDimension(boundary, &dim);CHKERRQ(ierr); 1060c5929fdfSBarry Smith ierr = PetscOptionsGetString(((PetscObject) boundary)->options,((PetscObject) boundary)->prefix, "-dm_plex_generator", genname, 1024, &flg);CHKERRQ(ierr); 1061d9deefdfSMatthew G. Knepley if (flg) name = genname; 1062d9deefdfSMatthew G. Knepley if (name) { 1063d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "triangle", &isTriangle);CHKERRQ(ierr); 1064d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "tetgen", &isTetgen);CHKERRQ(ierr); 1065d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "ctetgen", &isCTetgen);CHKERRQ(ierr); 1066d9deefdfSMatthew G. Knepley } 1067d9deefdfSMatthew G. Knepley switch (dim) { 1068d9deefdfSMatthew G. Knepley case 1: 1069d9deefdfSMatthew G. Knepley if (!name || isTriangle) { 1070d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TRIANGLE) 1071d9deefdfSMatthew G. Knepley ierr = DMPlexGenerate_Triangle(boundary, interpolate, mesh);CHKERRQ(ierr); 1072d9deefdfSMatthew G. Knepley #else 1073d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Mesh generation needs external package support.\nPlease reconfigure with --download-triangle."); 1074d9deefdfSMatthew G. Knepley #endif 1075d9deefdfSMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Unknown 2D mesh generation package %s", name); 1076d9deefdfSMatthew G. Knepley break; 1077d9deefdfSMatthew G. Knepley case 2: 1078d9deefdfSMatthew G. Knepley if (!name || isCTetgen) { 1079d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_CTETGEN) 1080d9deefdfSMatthew G. Knepley ierr = DMPlexGenerate_CTetgen(boundary, interpolate, mesh);CHKERRQ(ierr); 1081d9deefdfSMatthew G. Knepley #else 1082d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "CTetgen needs external package support.\nPlease reconfigure with --download-ctetgen."); 1083d9deefdfSMatthew G. Knepley #endif 1084d9deefdfSMatthew G. Knepley } else if (isTetgen) { 1085d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TETGEN) 1086d9deefdfSMatthew G. Knepley ierr = DMPlexGenerate_Tetgen(boundary, interpolate, mesh);CHKERRQ(ierr); 1087d9deefdfSMatthew G. Knepley #else 1088*2ca110d9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Tetgen needs external package support.\nPlease reconfigure with --download-tetgen."); 1089d9deefdfSMatthew G. Knepley #endif 1090d9deefdfSMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Unknown 3D mesh generation package %s", name); 1091d9deefdfSMatthew G. Knepley break; 1092d9deefdfSMatthew G. Knepley default: 1093d9deefdfSMatthew G. Knepley SETERRQ1(PetscObjectComm((PetscObject)boundary), PETSC_ERR_SUP, "Mesh generation for a dimension %d boundary is not supported.", dim); 1094d9deefdfSMatthew G. Knepley } 1095d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1096d9deefdfSMatthew G. Knepley } 1097d9deefdfSMatthew G. Knepley 1098d9deefdfSMatthew G. Knepley #undef __FUNCT__ 1099d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMRefine_Plex" 1100d9deefdfSMatthew G. Knepley PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 1101d9deefdfSMatthew G. Knepley { 1102b28003e6SMatthew G. Knepley PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *); 1103d9deefdfSMatthew G. Knepley PetscReal refinementLimit; 1104d9deefdfSMatthew G. Knepley PetscInt dim, cStart, cEnd; 1105d9deefdfSMatthew G. Knepley char genname[1024], *name = NULL; 110636447a5eSToby Isaac PetscBool isUniform, isTriangle = PETSC_FALSE, isTetgen = PETSC_FALSE, isCTetgen = PETSC_FALSE, flg, localized; 1107d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 1108d9deefdfSMatthew G. Knepley 1109d9deefdfSMatthew G. Knepley PetscFunctionBegin; 111036447a5eSToby Isaac ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 1111d9deefdfSMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 1112d9deefdfSMatthew G. Knepley if (isUniform) { 1113d9deefdfSMatthew G. Knepley CellRefiner cellRefiner; 1114d9deefdfSMatthew G. Knepley 1115d9deefdfSMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 1116d9deefdfSMatthew G. Knepley ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr); 1117a6ba4734SToby Isaac ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 111836447a5eSToby Isaac if (localized) { 111936447a5eSToby Isaac ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr); 112036447a5eSToby Isaac } 1121d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1122d9deefdfSMatthew G. Knepley } 1123d9deefdfSMatthew G. Knepley ierr = DMPlexGetRefinementLimit(dm, &refinementLimit);CHKERRQ(ierr); 1124b28003e6SMatthew G. Knepley ierr = DMPlexGetRefinementFunction(dm, &refinementFunc);CHKERRQ(ierr); 1125b28003e6SMatthew G. Knepley if (refinementLimit == 0.0 && !refinementFunc) PetscFunctionReturn(0); 1126d9deefdfSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1127d9deefdfSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1128c5929fdfSBarry Smith ierr = PetscOptionsGetString(((PetscObject) dm)->options,((PetscObject) dm)->prefix, "-dm_plex_generator", genname, 1024, &flg);CHKERRQ(ierr); 1129d9deefdfSMatthew G. Knepley if (flg) name = genname; 1130d9deefdfSMatthew G. Knepley if (name) { 1131d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "triangle", &isTriangle);CHKERRQ(ierr); 1132d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "tetgen", &isTetgen);CHKERRQ(ierr); 1133d9deefdfSMatthew G. Knepley ierr = PetscStrcmp(name, "ctetgen", &isCTetgen);CHKERRQ(ierr); 1134d9deefdfSMatthew G. Knepley } 1135d9deefdfSMatthew G. Knepley switch (dim) { 1136d9deefdfSMatthew G. Knepley case 2: 1137d9deefdfSMatthew G. Knepley if (!name || isTriangle) { 1138d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TRIANGLE) 1139d9deefdfSMatthew G. Knepley double *maxVolumes; 1140d9deefdfSMatthew G. Knepley PetscInt c; 1141d9deefdfSMatthew G. Knepley 1142854ce69bSBarry Smith ierr = PetscMalloc1(cEnd - cStart, &maxVolumes);CHKERRQ(ierr); 1143b28003e6SMatthew G. Knepley if (refinementFunc) { 1144b28003e6SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1145b28003e6SMatthew G. Knepley PetscReal vol, centroid[3]; 1146b28003e6SMatthew G. Knepley 1147b28003e6SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, centroid, NULL);CHKERRQ(ierr); 1148b28003e6SMatthew G. Knepley ierr = (*refinementFunc)(centroid, &maxVolumes[c-cStart]);CHKERRQ(ierr); 1149b28003e6SMatthew G. Knepley } 1150b28003e6SMatthew G. Knepley } else { 1151d9deefdfSMatthew G. Knepley for (c = 0; c < cEnd-cStart; ++c) maxVolumes[c] = refinementLimit; 1152b28003e6SMatthew G. Knepley } 1153d9deefdfSMatthew G. Knepley ierr = DMPlexRefine_Triangle(dm, maxVolumes, dmRefined);CHKERRQ(ierr); 1154d9deefdfSMatthew G. Knepley ierr = PetscFree(maxVolumes);CHKERRQ(ierr); 1155d9deefdfSMatthew G. Knepley #else 1156d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Mesh refinement needs external package support.\nPlease reconfigure with --download-triangle."); 1157d9deefdfSMatthew G. Knepley #endif 1158d9deefdfSMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unknown 2D mesh generation package %s", name); 1159d9deefdfSMatthew G. Knepley break; 1160d9deefdfSMatthew G. Knepley case 3: 1161d9deefdfSMatthew G. Knepley if (!name || isCTetgen) { 1162d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_CTETGEN) 1163d9deefdfSMatthew G. Knepley PetscReal *maxVolumes; 1164d9deefdfSMatthew G. Knepley PetscInt c; 1165d9deefdfSMatthew G. Knepley 1166854ce69bSBarry Smith ierr = PetscMalloc1(cEnd - cStart, &maxVolumes);CHKERRQ(ierr); 1167b28003e6SMatthew G. Knepley if (refinementFunc) { 1168b28003e6SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1169b28003e6SMatthew G. Knepley PetscReal vol, centroid[3]; 1170b28003e6SMatthew G. Knepley 1171b28003e6SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, centroid, NULL);CHKERRQ(ierr); 1172b28003e6SMatthew G. Knepley ierr = (*refinementFunc)(centroid, &maxVolumes[c-cStart]);CHKERRQ(ierr); 1173b28003e6SMatthew G. Knepley } 1174b28003e6SMatthew G. Knepley } else { 1175d9deefdfSMatthew G. Knepley for (c = 0; c < cEnd-cStart; ++c) maxVolumes[c] = refinementLimit; 1176b28003e6SMatthew G. Knepley } 1177d9deefdfSMatthew G. Knepley ierr = DMPlexRefine_CTetgen(dm, maxVolumes, dmRefined);CHKERRQ(ierr); 1178d9deefdfSMatthew G. Knepley #else 1179d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "CTetgen needs external package support.\nPlease reconfigure with --download-ctetgen."); 1180d9deefdfSMatthew G. Knepley #endif 1181d9deefdfSMatthew G. Knepley } else if (isTetgen) { 1182d9deefdfSMatthew G. Knepley #if defined(PETSC_HAVE_TETGEN) 1183d9deefdfSMatthew G. Knepley double *maxVolumes; 1184d9deefdfSMatthew G. Knepley PetscInt c; 1185d9deefdfSMatthew G. Knepley 1186854ce69bSBarry Smith ierr = PetscMalloc1(cEnd - cStart, &maxVolumes);CHKERRQ(ierr); 1187b28003e6SMatthew G. Knepley if (refinementFunc) { 1188b28003e6SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1189b28003e6SMatthew G. Knepley PetscReal vol, centroid[3]; 1190b28003e6SMatthew G. Knepley 1191b28003e6SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, centroid, NULL);CHKERRQ(ierr); 1192b28003e6SMatthew G. Knepley ierr = (*refinementFunc)(centroid, &maxVolumes[c-cStart]);CHKERRQ(ierr); 1193b28003e6SMatthew G. Knepley } 1194b28003e6SMatthew G. Knepley } else { 1195d9deefdfSMatthew G. Knepley for (c = 0; c < cEnd-cStart; ++c) maxVolumes[c] = refinementLimit; 1196b28003e6SMatthew G. Knepley } 1197d9deefdfSMatthew G. Knepley ierr = DMPlexRefine_Tetgen(dm, maxVolumes, dmRefined);CHKERRQ(ierr); 1198d9deefdfSMatthew G. Knepley #else 1199d9deefdfSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Tetgen needs external package support.\nPlease reconfigure with --with-c-language=cxx --download-tetgen."); 1200d9deefdfSMatthew G. Knepley #endif 1201d9deefdfSMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unknown 3D mesh generation package %s", name); 1202d9deefdfSMatthew G. Knepley break; 1203d9deefdfSMatthew G. Knepley default: 1204d9deefdfSMatthew G. Knepley SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Mesh refinement in dimension %d is not supported.", dim); 1205d9deefdfSMatthew G. Knepley } 1206a6ba4734SToby Isaac ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 120736447a5eSToby Isaac if (localized) { 120836447a5eSToby Isaac ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr); 120936447a5eSToby Isaac } 1210d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1211d9deefdfSMatthew G. Knepley } 1212d9deefdfSMatthew G. Knepley 1213d9deefdfSMatthew G. Knepley #undef __FUNCT__ 1214d9deefdfSMatthew G. Knepley #define __FUNCT__ "DMRefineHierarchy_Plex" 1215d9deefdfSMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 1216d9deefdfSMatthew G. Knepley { 1217d9deefdfSMatthew G. Knepley DM cdm = dm; 1218d9deefdfSMatthew G. Knepley PetscInt r; 121936447a5eSToby Isaac PetscBool isUniform, localized; 1220d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 1221d9deefdfSMatthew G. Knepley 1222d9deefdfSMatthew G. Knepley PetscFunctionBegin; 1223d9deefdfSMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 122436447a5eSToby Isaac ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 1225d9deefdfSMatthew G. Knepley if (!isUniform) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Non-uniform refinement is incompatible with the hierarchy"); 1226d9deefdfSMatthew G. Knepley for (r = 0; r < nlevels; ++r) { 1227d9deefdfSMatthew G. Knepley CellRefiner cellRefiner; 1228d9deefdfSMatthew G. Knepley 1229d9deefdfSMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr); 1230d9deefdfSMatthew G. Knepley ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr); 1231a6ba4734SToby Isaac ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 123236447a5eSToby Isaac if (localized) { 123336447a5eSToby Isaac ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr); 123436447a5eSToby Isaac } 1235a8fb8f29SToby Isaac ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 12360aef6b92SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 1237d9deefdfSMatthew G. Knepley cdm = dmRefined[r]; 1238d9deefdfSMatthew G. Knepley } 1239d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 1240d9deefdfSMatthew G. Knepley } 1241