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 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); }