PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) { const char *filename = user->filename; PetscInt dim = user->dim; size_t len; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscStrlen(filename, &len);CHKERRQ(ierr); if (!len) {ierr = DMPlexCreateBoxMesh(comm, dim, PETSC_TRUE, dm);CHKERRQ(ierr);} else {ierr = DMPlexCreateFromFile(comm, filename, PETSC_TRUE, dm);CHKERRQ(ierr);} ierr = DMViewFromOptions(*dm, NULL, "-orig_dm_view");CHKERRQ(ierr); { DM distributedMesh = NULL; ierr = DMPlexDistribute(*dm, 0, NULL, &distributedMesh);CHKERRQ(ierr); if (distributedMesh) { ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = distributedMesh; ierr = DMViewFromOptions(*dm, NULL, "-dist_dm_view");CHKERRQ(ierr); } } ierr = DMSetFromOptions(*dm);CHKERRQ(ierr); if (user->uninterpolate) { DM udm = NULL; ierr = DMPlexUninterpolate(*dm, &udm);CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = udm; ierr = DMViewFromOptions(*dm, NULL, "-un_dm_view");CHKERRQ(ierr); } ierr = PetscObjectSetName((PetscObject) *dm, "Test Mesh");CHKERRQ(ierr); ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) { PetscInt dim = user->dim; PetscBool cellHybrid = user->cellHybrid; PetscBool cellSimplex = user->cellSimplex; PetscMPIInt rank, size; PetscErrorCode ierr; PetscFunctionBegin; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); ierr = DMCreate(comm, dm);CHKERRQ(ierr); ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); switch (dim) { case 1: if (cellHybrid) SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make hybrid meshes for dimension %d", dim); ierr = CreateSimplex_1D(comm, dm);CHKERRQ(ierr); break; case 2: if (cellSimplex) { if (cellHybrid) { ierr = CreateSimplexHybrid_2D(comm, user->testNum, dm);CHKERRQ(ierr); } else { ierr = CreateSimplex_2D(comm, dm);CHKERRQ(ierr); } } else { if (cellHybrid) { ierr = CreateTensorProductHybrid_2D(comm, user->testNum, dm);CHKERRQ(ierr); } else { ierr = CreateTensorProduct_2D(comm, user->testNum, dm);CHKERRQ(ierr); } } break; case 3: if (cellSimplex) { if (cellHybrid) { ierr = CreateSimplexHybrid_3D(comm, user->testNum, dm);CHKERRQ(ierr); } else { ierr = CreateSimplex_3D(comm, user->testNum, dm);CHKERRQ(ierr); } } else { if (cellHybrid) { ierr = CreateTensorProductHybrid_3D(comm, user->testNum, dm);CHKERRQ(ierr); } else { ierr = CreateTensorProduct_3D(comm, user->testNum, dm);CHKERRQ(ierr); } } break; default: SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make meshes for dimension %d", dim); } if (user->testPartition && size > 1) { PetscPartitioner part; PetscInt *sizes = NULL; PetscInt *points = NULL; if (!rank) { if (dim == 2 && cellSimplex && !cellHybrid && size == 2) { switch (user->testNum) { case 0: { PetscInt triSizes_p2[2] = {1, 1}; PetscInt triPoints_p2[2] = {0, 1}; ierr = PetscMalloc2(2, &sizes, 2, &points);CHKERRQ(ierr); ierr = PetscMemcpy(sizes, triSizes_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(points, triPoints_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr);break;} default: SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for triangular mesh on 2 procs", user->testNum); } } else if (dim == 2 && cellSimplex && cellHybrid && size == 2) { switch (user->testNum) { case 0: { PetscInt triSizes_p2[2] = {1, 2}; PetscInt triPoints_p2[3] = {0, 1, 2}; ierr = PetscMalloc2(2, &sizes, 3, &points);CHKERRQ(ierr); ierr = PetscMemcpy(sizes, triSizes_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(points, triPoints_p2, 3 * sizeof(PetscInt));CHKERRQ(ierr);break;} default: SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for triangular hybrid mesh on 2 procs", user->testNum); } } else if (dim == 2 && !cellSimplex && !cellHybrid && size == 2) { switch (user->testNum) { case 0: { PetscInt quadSizes_p2[2] = {1, 1}; PetscInt quadPoints_p2[2] = {0, 1}; ierr = PetscMalloc2(2, &sizes, 2, &points);CHKERRQ(ierr); ierr = PetscMemcpy(sizes, quadSizes_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(points, quadPoints_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr);break;} default: SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for quadrilateral mesh on 2 procs", user->testNum); } } else if (dim == 2 && !cellSimplex && cellHybrid && size == 2) { switch (user->testNum) { case 0: { PetscInt quadSizes_p2[2] = {1, 2}; PetscInt quadPoints_p2[3] = {0, 1, 2}; ierr = PetscMalloc2(2, &sizes, 3, &points);CHKERRQ(ierr); ierr = PetscMemcpy(sizes, quadSizes_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(points, quadPoints_p2, 3 * sizeof(PetscInt));CHKERRQ(ierr);break;} default: SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for quadrilateral hybrid mesh on 2 procs", user->testNum); } } else if (dim == 3 && cellSimplex && !cellHybrid && size == 2) { switch (user->testNum) { case 0: { PetscInt tetSizes_p2[2] = {1, 1}; PetscInt tetPoints_p2[2] = {0, 1}; ierr = PetscMalloc2(2, &sizes, 2, &points);CHKERRQ(ierr); ierr = PetscMemcpy(sizes, tetSizes_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(points, tetPoints_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr);break;} case 1: { PetscInt tetSizes_p2[2] = {1, 1}; PetscInt tetPoints_p2[2] = {0, 1}; ierr = PetscMalloc2(2, &sizes, 2, &points);CHKERRQ(ierr); ierr = PetscMemcpy(sizes, tetSizes_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(points, tetPoints_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr);break;} default: SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for tetrahedral mesh on 2 procs", user->testNum); } } else if (dim == 3 && cellSimplex && cellHybrid && size == 2) { switch (user->testNum) { case 0: { PetscInt tetSizes_p2[2] = {1, 2}; PetscInt tetPoints_p2[3] = {0, 1, 2}; ierr = PetscMalloc2(2, &sizes, 3, &points);CHKERRQ(ierr); ierr = PetscMemcpy(sizes, tetSizes_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(points, tetPoints_p2, 3 * sizeof(PetscInt));CHKERRQ(ierr);break;} case 1: { PetscInt tetSizes_p2[2] = {3, 4}; PetscInt tetPoints_p2[7] = {0, 3, 5, 1, 2, 4, 6}; ierr = PetscMalloc2(2, &sizes, 7, &points);CHKERRQ(ierr); ierr = PetscMemcpy(sizes, tetSizes_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(points, tetPoints_p2, 7 * sizeof(PetscInt));CHKERRQ(ierr);break;} default: SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for tetrahedral hybrid mesh on 2 procs", user->testNum); } } else if (dim == 3 && !cellSimplex && !cellHybrid && size == 2) { switch (user->testNum) { case 0: { PetscInt hexSizes_p2[2] = {1, 1}; PetscInt hexPoints_p2[2] = {0, 1}; ierr = PetscMalloc2(2, &sizes, 2, &points);CHKERRQ(ierr); ierr = PetscMemcpy(sizes, hexSizes_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(points, hexPoints_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr);break;} default: SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for hexahedral mesh on 2 procs", user->testNum); } } else if (dim == 3 && !cellSimplex && cellHybrid && size == 2) { switch (user->testNum) { case 0: { PetscInt hexSizes_p2[2] = {1, 1}; PetscInt hexPoints_p2[2] = {0, 1}; ierr = PetscMalloc2(2, &sizes, 2, &points);CHKERRQ(ierr); ierr = PetscMemcpy(sizes, hexSizes_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(points, hexPoints_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr);break;} case 1: { PetscInt hexSizes_p2[2] = {5, 4}; PetscInt hexPoints_p2[9] = {3, 4, 5, 7, 8, 0, 1, 2, 6}; ierr = PetscMalloc2(2, &sizes, 9, &points);CHKERRQ(ierr); ierr = PetscMemcpy(sizes, hexSizes_p2, 2 * sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(points, hexPoints_p2, 9 * sizeof(PetscInt));CHKERRQ(ierr);break;} default: SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for hexahedral hybrid mesh on 2 procs", user->testNum); } } else SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test partition"); } ierr = DMPlexGetPartitioner(*dm, &part);CHKERRQ(ierr); ierr = PetscPartitionerSetType(part, PETSCPARTITIONERSHELL);CHKERRQ(ierr); ierr = PetscPartitionerShellSetPartition(part, size, sizes, points);CHKERRQ(ierr); ierr = PetscFree2(sizes, points);CHKERRQ(ierr); } else { PetscPartitioner part; ierr = DMPlexGetPartitioner(*dm,&part);CHKERRQ(ierr); ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); } { DM pdm = NULL; ierr = DMPlexDistribute(*dm, 0, NULL, &pdm);CHKERRQ(ierr); if (pdm) { ierr = DMViewFromOptions(pdm, NULL, "-dm_view");CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = pdm; } } ierr = DMSetFromOptions(*dm);CHKERRQ(ierr); if (user->simplex2tensor) { DM rdm = NULL; ierr = DMPlexSetRefinementUniform(*dm, PETSC_TRUE);CHKERRQ(ierr); ierr = DMPlexRefineSimplexToTensor(*dm, &rdm);CHKERRQ(ierr); if (rdm) { ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = rdm; } user->cellSimplex = PETSC_FALSE; } if (user->uninterpolate || user->reinterpolate) { DM udm = NULL; ierr = DMPlexUninterpolate(*dm, &udm);CHKERRQ(ierr); ierr = DMPlexCopyCoordinates(*dm, udm);CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = udm; } if (user->reinterpolate) { DM idm = NULL; ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); ierr = DMPlexCopyCoordinates(*dm, idm);CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = idm; } ierr = PetscObjectSetName((PetscObject) *dm, "Hybrid Mesh");CHKERRQ(ierr); ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr); ierr = PetscObjectSetOptionsPrefix((PetscObject) *dm, "hyb_");CHKERRQ(ierr); ierr = DMSetFromOptions(*dm);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DMCoarsen_Plex(DM dm, MPI_Comm comm, DM *dmCoarsened) { DM_Plex *mesh = (DM_Plex*) dm->data; #ifdef PETSC_HAVE_PRAGMATIC DM udm, coordDM; DMLabel bd; Mat A; Vec coordinates, mb, mx; PetscSection coordSection; const PetscScalar *coords; double *coarseCoords; IS bdIS; PetscReal *x, *y, *z, *eqns, *metric; PetscReal coarseRatio = PetscSqr(0.5); const PetscInt *faces; PetscInt *cells, *bdFaces, *bdFaceIds; PetscInt dim, numCorners, cStart, cEnd, numCells, numCoarseCells, c, vStart, vEnd, numVertices, numCoarseVertices, v, numBdFaces, f, maxConeSize, size, bdSize, coff; #endif PetscErrorCode ierr; PetscFunctionBegin; #ifdef PETSC_HAVE_PRAGMATIC if (!mesh->coarseMesh) { ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); ierr = DMGetCoordinateDM(dm, &coordDM);CHKERRQ(ierr); ierr = DMGetDefaultSection(coordDM, &coordSection);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); ierr = DMPlexUninterpolate(dm, &udm);CHKERRQ(ierr); ierr = DMPlexGetMaxSizes(udm, &maxConeSize, NULL);CHKERRQ(ierr); numCells = cEnd - cStart; numVertices = vEnd - vStart; ierr = PetscCalloc5(numVertices, &x, numVertices, &y, numVertices, &z, numVertices*PetscSqr(dim), &metric, numCells*maxConeSize, &cells);CHKERRQ(ierr); ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); for (v = vStart; v < vEnd; ++v) { PetscInt off; ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); x[v-vStart] = coords[off+0]; y[v-vStart] = coords[off+1]; if (dim > 2) z[v-vStart] = coords[off+2]; } ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); for (c = 0, coff = 0; c < numCells; ++c) { const PetscInt *cone; PetscInt coneSize, cl; ierr = DMPlexGetConeSize(udm, c, &coneSize);CHKERRQ(ierr); ierr = DMPlexGetCone(udm, c, &cone);CHKERRQ(ierr); for (cl = 0; cl < coneSize; ++cl) cells[coff++] = cone[cl] - vStart; } switch (dim) { case 2: pragmatic_2d_init(&numVertices, &numCells, cells, x, y); break; case 3: pragmatic_3d_init(&numVertices, &numCells, cells, x, y, z); break; default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No Pragmatic coarsening defined for dimension %d", dim); } /* Create boundary mesh */ ierr = DMLabelCreate("boundary", &bd);CHKERRQ(ierr); ierr = DMPlexMarkBoundaryFaces(dm, bd);CHKERRQ(ierr); ierr = DMLabelGetStratumIS(bd, 1, &bdIS);CHKERRQ(ierr); ierr = DMLabelGetStratumSize(bd, 1, &numBdFaces);CHKERRQ(ierr); ierr = ISGetIndices(bdIS, &faces);CHKERRQ(ierr); for (f = 0, bdSize = 0; f < numBdFaces; ++f) { PetscInt *closure = NULL; PetscInt closureSize, cl; ierr = DMPlexGetTransitiveClosure(dm, faces[f], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); for (cl = 0; cl < closureSize*2; cl += 2) { if ((closure[cl] >= vStart) && (closure[cl] < vEnd)) ++bdSize; } ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); } ierr = PetscMalloc2(bdSize, &bdFaces, numBdFaces, &bdFaceIds);CHKERRQ(ierr); for (f = 0, bdSize = 0; f < numBdFaces; ++f) { PetscInt *closure = NULL; PetscInt closureSize, cl; ierr = DMPlexGetTransitiveClosure(dm, faces[f], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); for (cl = 0; cl < closureSize*2; cl += 2) { if ((closure[cl] >= vStart) && (closure[cl] < vEnd)) bdFaces[bdSize++] = closure[cl] - vStart; } /* TODO Fix */ bdFaceIds[f] = 1; ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); } ierr = ISDestroy(&bdIS);CHKERRQ(ierr); ierr = DMLabelDestroy(&bd);CHKERRQ(ierr); pragmatic_set_boundary(&numBdFaces, bdFaces, bdFaceIds); /* Create metric */ size = (dim*(dim+1))/2; ierr = PetscMalloc1(PetscSqr(size), &eqns);CHKERRQ(ierr); ierr = MatCreateSeqDense(PETSC_COMM_SELF, size, size, eqns, &A);CHKERRQ(ierr); ierr = MatCreateVecs(A, &mx, &mb);CHKERRQ(ierr); ierr = VecSet(mb, 1.0);CHKERRQ(ierr); for (c = 0; c < numCells; ++c) { const PetscScalar *sol; PetscScalar *cellCoords = NULL; PetscReal e[3], vol; const PetscInt *cone; PetscInt coneSize, cl, i, j, d, r; ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, NULL, &cellCoords);CHKERRQ(ierr); /* Only works for simplices */ for (i = 0, r = 0; i < dim+1; ++i) { for (j = 0; j < i; ++j, ++r) { for (d = 0; d < dim; ++d) e[d] = cellCoords[i*dim+d] - cellCoords[j*dim+d]; /* FORTRAN ORDERING */ if (dim == 2) { eqns[0*size+r] = PetscSqr(e[0]); eqns[1*size+r] = 2.0*e[0]*e[1]; eqns[2*size+r] = PetscSqr(e[1]); } else { eqns[0*size+r] = PetscSqr(e[0]); eqns[1*size+r] = 2.0*e[0]*e[1]; eqns[2*size+r] = 2.0*e[0]*e[2]; eqns[3*size+r] = PetscSqr(e[1]); eqns[4*size+r] = 2.0*e[1]*e[2]; eqns[5*size+r] = PetscSqr(e[2]); } } } ierr = MatSetUnfactored(A);CHKERRQ(ierr); ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, NULL, &cellCoords);CHKERRQ(ierr); ierr = MatLUFactor(A, NULL, NULL, NULL);CHKERRQ(ierr); ierr = MatSolve(A, mb, mx);CHKERRQ(ierr); ierr = VecGetArrayRead(mx, &sol);CHKERRQ(ierr); ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, NULL, NULL);CHKERRQ(ierr); ierr = DMPlexGetCone(udm, c, &cone);CHKERRQ(ierr); ierr = DMPlexGetConeSize(udm, c, &coneSize);CHKERRQ(ierr); for (cl = 0; cl < coneSize; ++cl) { const PetscInt v = cone[cl] - vStart; if (dim == 2) { metric[v*4+0] += vol*coarseRatio*sol[0]; metric[v*4+1] += vol*coarseRatio*sol[1]; metric[v*4+2] += vol*coarseRatio*sol[1]; metric[v*4+3] += vol*coarseRatio*sol[2]; } else { metric[v*9+0] += vol*coarseRatio*sol[0]; metric[v*9+1] += vol*coarseRatio*sol[1]; metric[v*9+3] += vol*coarseRatio*sol[1]; metric[v*9+2] += vol*coarseRatio*sol[2]; metric[v*9+6] += vol*coarseRatio*sol[2]; metric[v*9+4] += vol*coarseRatio*sol[3]; metric[v*9+5] += vol*coarseRatio*sol[4]; metric[v*9+7] += vol*coarseRatio*sol[4]; metric[v*9+8] += vol*coarseRatio*sol[5]; } } ierr = VecRestoreArrayRead(mx, &sol);CHKERRQ(ierr); } for (v = 0; v < numVertices; ++v) { const PetscInt *support; PetscInt supportSize, s; PetscReal vol, totVol = 0.0; ierr = DMPlexGetSupport(udm, v+vStart, &support);CHKERRQ(ierr); ierr = DMPlexGetSupportSize(udm, v+vStart, &supportSize);CHKERRQ(ierr); for (s = 0; s < supportSize; ++s) {ierr = DMPlexComputeCellGeometryFVM(dm, support[s], &vol, NULL, NULL);CHKERRQ(ierr); totVol += vol;} for (s = 0; s < PetscSqr(dim); ++s) metric[v*PetscSqr(dim)+s] /= totVol; } ierr = VecDestroy(&mx);CHKERRQ(ierr); ierr = VecDestroy(&mb);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = DMDestroy(&udm);CHKERRQ(ierr); ierr = PetscFree(eqns);CHKERRQ(ierr); pragmatic_set_metric(metric); pragmatic_adapt(); /* Read out mesh */ pragmatic_get_info(&numCoarseVertices, &numCoarseCells); ierr = PetscMalloc1(numCoarseVertices*dim, &coarseCoords);CHKERRQ(ierr); switch (dim) { case 2: pragmatic_get_coords_2d(x, y); numCorners = 3; for (v = 0; v < numCoarseVertices; ++v) {coarseCoords[v*2+0] = x[v]; coarseCoords[v*2+1] = y[v];} break; case 3: pragmatic_get_coords_3d(x, y, z); numCorners = 4; for (v = 0; v < numCoarseVertices; ++v) {coarseCoords[v*3+0] = x[v]; coarseCoords[v*3+1] = y[v]; coarseCoords[v*3+2] = z[v];} break; default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No Pragmatic coarsening defined for dimension %d", dim); } pragmatic_get_elements(cells); /* TODO Read out markers for boundary */ ierr = DMPlexCreateFromCellList(PetscObjectComm((PetscObject) dm), dim, numCoarseCells, numCoarseVertices, numCorners, PETSC_TRUE, cells, dim, coarseCoords, &mesh->coarseMesh);CHKERRQ(ierr); pragmatic_finalize(); ierr = PetscFree5(x, y, z, metric, cells);CHKERRQ(ierr); ierr = PetscFree2(bdFaces, bdFaceIds);CHKERRQ(ierr); ierr = PetscFree(coarseCoords);CHKERRQ(ierr); } #endif ierr = PetscObjectReference((PetscObject) mesh->coarseMesh);CHKERRQ(ierr); *dmCoarsened = mesh->coarseMesh; PetscFunctionReturn(0); }
PETSC_EXTERN void PETSC_STDCALL dmplexuninterpolate_(DM dm,DM *dmUnint, int *__ierr ){ *__ierr = DMPlexUninterpolate( (DM)PetscToPointer((dm) ),dmUnint); }
PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) { PetscInt dim = user->dim; PetscInt numRefinements = user->numRefinements; PetscBool cellHybrid = user->cellHybrid; PetscBool cellSimplex = user->cellSimplex; PetscMPIInt rank; PetscErrorCode ierr; PetscFunctionBegin; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = DMCreate(comm, dm);CHKERRQ(ierr); ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); switch (dim) { case 1: if (cellHybrid) SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make hybrid meshes for dimension %d", dim); ierr = CreateSimplex_1D(comm, dm);CHKERRQ(ierr); break; case 2: if (cellSimplex) { if (cellHybrid) { ierr = CreateSimplexHybrid_2D(comm, user->testNum, dm);CHKERRQ(ierr); } else { ierr = CreateSimplex_2D(comm, dm);CHKERRQ(ierr); } } else { if (cellHybrid) { ierr = CreateTensorProductHybrid_2D(comm, user->testNum, dm);CHKERRQ(ierr); } else { ierr = CreateTensorProduct_2D(comm, user->testNum, dm);CHKERRQ(ierr); } } break; case 3: if (cellSimplex) { if (cellHybrid) { ierr = CreateSimplexHybrid_3D(comm, user->testNum, dm);CHKERRQ(ierr); } else { ierr = CreateSimplex_3D(comm, user->testNum, dm);CHKERRQ(ierr); } } else { if (cellHybrid) { ierr = CreateTensorProductHybrid_3D(comm, user->testNum, dm);CHKERRQ(ierr); } else { ierr = CreateTensorProduct_3D(comm, user->testNum, dm);CHKERRQ(ierr); } } break; default: SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make meshes for dimension %d", dim); } { DM refinedMesh = NULL; DM distributedMesh = NULL; PetscInt r; /* Distribute mesh over processes */ ierr = DMPlexDistribute(*dm, 0, NULL, &distributedMesh);CHKERRQ(ierr); if (distributedMesh) { ierr = DMViewFromOptions(distributedMesh, NULL, "-dm_view");CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = distributedMesh; } for (r = 0; r < numRefinements; ++r) { ierr = DMViewFromOptions(*dm, NULL, "-orig_dm_view");CHKERRQ(ierr); ierr = DMPlexCheckSymmetry(*dm);CHKERRQ(ierr); ierr = DMPlexCheckSkeleton(*dm, user->cellSimplex, 0);CHKERRQ(ierr); ierr = DMPlexCheckFaces(*dm, user->cellSimplex, 0);CHKERRQ(ierr); ierr = DMPlexSetRefinementUniform(*dm, PETSC_TRUE);CHKERRQ(ierr); ierr = DMRefine(*dm, comm, &refinedMesh);CHKERRQ(ierr); if (refinedMesh) { ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = refinedMesh; } } } if (user->uninterpolate) { DM udm = NULL; ierr = DMPlexUninterpolate(*dm, &udm);CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = udm; } ierr = PetscObjectSetName((PetscObject) *dm, "Hybrid Mesh");CHKERRQ(ierr); ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr); PetscFunctionReturn(0); }