/*@ DMPlexCreateBoxMesh - Creates a mesh on the tensor product of unit intervals (box). Collective on MPI_Comm Input Parameters: + comm - The communicator for the DM object . dim - The spatial dimension - interpolate - Flag to create intermediate mesh pieces (edges, faces) Output Parameter: . dm - The DM object Level: beginner .keywords: DM, create .seealso: DMSetType(), DMCreate() @*/ PetscErrorCode DMPlexCreateBoxMesh(MPI_Comm comm, PetscInt dim, PetscBool interpolate, DM *dm) { DM boundary; PetscErrorCode ierr; PetscFunctionBegin; PetscValidPointer(dm, 4); ierr = DMCreate(comm, &boundary);CHKERRQ(ierr); PetscValidLogicalCollectiveInt(boundary,dim,2); ierr = DMSetType(boundary, DMPLEX);CHKERRQ(ierr); ierr = DMPlexSetDimension(boundary, dim-1);CHKERRQ(ierr); switch (dim) { case 2: { PetscReal lower[2] = {0.0, 0.0}; PetscReal upper[2] = {1.0, 1.0}; PetscInt edges[2] = {2, 2}; ierr = DMPlexCreateSquareBoundary(boundary, lower, upper, edges);CHKERRQ(ierr); break; } case 3: { PetscReal lower[3] = {0.0, 0.0, 0.0}; PetscReal upper[3] = {1.0, 1.0, 1.0}; PetscInt faces[3] = {1, 1, 1}; ierr = DMPlexCreateCubeBoundary(boundary, lower, upper, faces);CHKERRQ(ierr); break; } default: SETERRQ1(comm, PETSC_ERR_SUP, "Dimension not supported: %d", dim); } ierr = DMPlexGenerate(boundary, NULL, interpolate, dm);CHKERRQ(ierr); ierr = DMDestroy(&boundary);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) { PetscInt dim = user->dim; PetscBool interpolate = user->interpolate; PetscReal refinementLimit = user->refinementLimit; PetscBool cellSimplex = user->cellSimplex; PetscBool cellWedge = user->cellWedge; PetscBool simplex2tensor = user->simplex2tensor; const char *filename = user->filename; const char *bdfilename = user->bdfilename; const char *extfilename = user->extfilename; PetscBool testp4est_seq = user->testp4est[0]; PetscBool testp4est_par = user->testp4est[1]; PetscInt triSizes_n2[2] = {4, 4}; PetscInt triPoints_n2[8] = {3, 5, 6, 7, 0, 1, 2, 4}; PetscInt triSizes_n8[8] = {1, 1, 1, 1, 1, 1, 1, 1}; PetscInt triPoints_n8[8] = {0, 1, 2, 3, 4, 5, 6, 7}; PetscInt quadSizes[2] = {2, 2}; PetscInt quadPoints[4] = {2, 3, 0, 1}; PetscInt gmshSizes_n3[3] = {14, 14, 14}; PetscInt gmshPoints_n3[42] = {1, 2, 4, 5, 9, 10, 11, 15, 16, 20, 21, 27, 28, 29, 3, 8, 12, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 0, 6, 7, 13, 14, 17, 18, 19, 22, 23, 24, 25, 26, 41}; PetscInt fluentSizes_n3[3] = {50, 50, 50}; PetscInt fluentPoints_n3[150] = { 5, 6, 7, 8, 12, 14, 16, 34, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 48, 50, 51, 80, 81, 89, 91, 93, 94, 95, 96, 97, 98, 99, 100, 101, 104, 121, 122, 124, 125, 126, 127, 128, 129, 131, 133, 143, 144, 145, 147, 1, 3, 4, 9, 10, 17, 18, 19, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 47, 61, 71, 72, 73, 74, 75, 76, 77, 78, 79, 86, 87, 88, 90, 92, 113, 115, 116, 117, 118, 119, 120, 123, 138, 140, 141, 142, 146, 148, 149, 0, 2, 11, 13, 15, 20, 21, 22, 23, 49, 52, 53, 54, 55, 56, 57, 58, 59, 60, 62, 63, 64, 65, 66, 67, 68, 69, 70, 82, 83, 84, 85, 102, 103, 105, 106, 107, 108, 109, 110, 111, 112, 114, 130, 132, 134, 135, 136, 137, 139}; size_t len, bdlen, extlen; PetscMPIInt rank, size; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLogEventBegin(user->createMeshEvent,0,0,0,0);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); ierr = PetscStrlen(filename, &len);CHKERRQ(ierr); ierr = PetscStrlen(bdfilename, &bdlen);CHKERRQ(ierr); ierr = PetscStrlen(extfilename, &extlen);CHKERRQ(ierr); ierr = PetscLogStagePush(user->stages[STAGE_LOAD]);CHKERRQ(ierr); if (len) { ierr = DMPlexCreateFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); } else if (bdlen) { DM boundary; ierr = DMPlexCreateFromFile(comm, bdfilename, interpolate, &boundary);CHKERRQ(ierr); ierr = DMPlexGenerate(boundary, NULL, interpolate, dm);CHKERRQ(ierr); ierr = DMDestroy(&boundary);CHKERRQ(ierr); } else if (extlen) { DM edm; ierr = DMPlexCreateFromFile(comm, extfilename, interpolate, &edm);CHKERRQ(ierr); ierr = DMPlexExtrude(edm, user->extrude_layers, user->extrude_thickness, PETSC_TRUE, interpolate, dm);CHKERRQ(ierr); ierr = DMDestroy(&edm);CHKERRQ(ierr); } else { switch (user->domainShape) { case BOX: if (cellWedge) { if (dim != 3) SETERRQ1(comm, PETSC_ERR_ARG_WRONG, "Dimension must be 3 for a wedge mesh, not %D", dim); ierr = DMPlexCreateWedgeBoxMesh(comm, user->domainBoxSizes, user->domainBoxL, user->domainBoxU, user->periodicity, PETSC_FALSE, interpolate, dm);CHKERRQ(ierr); } else { ierr = DMPlexCreateBoxMesh(comm, dim, cellSimplex, user->domainBoxSizes, user->domainBoxL, user->domainBoxU, user->periodicity, interpolate, dm);CHKERRQ(ierr); } break; case CYLINDER: if (cellSimplex) SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Cannot mesh a cylinder with simplices"); if (dim != 3) SETERRQ1(comm, PETSC_ERR_ARG_WRONG, "Dimension must be 3 for a cylinder mesh, not %D", dim); if (cellWedge) { ierr = DMPlexCreateWedgeCylinderMesh(comm, 6, interpolate, dm);CHKERRQ(ierr); } else { ierr = DMPlexCreateHexCylinderMesh(comm, 3, user->periodicity[2], dm);CHKERRQ(ierr); } break; default: SETERRQ1(comm, PETSC_ERR_ARG_WRONG, "Unknown domain shape %D", user->domainShape); } } ierr = DMLocalizeCoordinates(*dm);CHKERRQ(ierr); /* needed for periodic */ ierr = DMViewFromOptions(*dm,NULL,"-init_dm_view");CHKERRQ(ierr); ierr = DMGetDimension(*dm,&dim);CHKERRQ(ierr); if (testp4est_seq) { #if defined(PETSC_HAVE_P4EST) DM dmConv = NULL; ierr = DMPlexSetRefinementUniform(*dm, PETSC_TRUE);CHKERRQ(ierr); ierr = DMPlexRefineSimplexToTensor(*dm, &dmConv);CHKERRQ(ierr); if (dmConv) { ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = dmConv; } user->cellSimplex = PETSC_FALSE; ierr = DMConvert(*dm,dim == 2 ? DMP4EST : DMP8EST,&dmConv);CHKERRQ(ierr); if (dmConv) { ierr = DMSetFromOptions(dmConv);CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = dmConv; } ierr = DMSetUp(*dm);CHKERRQ(ierr); ierr = DMViewFromOptions(*dm, NULL, "-conv_seq_1_dm_view");CHKERRQ(ierr); ierr = DMConvert(*dm,DMPLEX,&dmConv);CHKERRQ(ierr); if (dmConv) { ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = dmConv; } ierr = DMViewFromOptions(*dm, NULL, "-conv_seq_2_dm_view");CHKERRQ(ierr); #else SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Recompile with --download-p4est"); #endif } ierr = PetscLogStagePop();CHKERRQ(ierr); if (!testp4est_seq) { DM refinedMesh = NULL; DM distributedMesh = NULL; if (user->testPartition) { const PetscInt *sizes = NULL; const PetscInt *points = NULL; PetscPartitioner part; if (!rank) { if (dim == 2 && cellSimplex && size == 2) { sizes = triSizes_n2; points = triPoints_n2; } else if (dim == 2 && cellSimplex && size == 8) { sizes = triSizes_n8; points = triPoints_n8; } else if (dim == 2 && !cellSimplex && size == 2) { sizes = quadSizes; points = quadPoints; } else if (dim == 2 && size == 3) { PetscInt Nc; ierr = DMPlexGetHeightStratum(*dm, 0, NULL, &Nc);CHKERRQ(ierr); if (Nc == 42) { /* Gmsh 3 & 4 */ sizes = gmshSizes_n3; points = gmshPoints_n3; } else if (Nc == 150) { /* Fluent 1 */ sizes = fluentSizes_n3; points = fluentPoints_n3; } else if (Nc == 42) { /* Med 1 */ } else if (Nc == 161) { /* Med 3 */ } } } ierr = DMPlexGetPartitioner(*dm, &part);CHKERRQ(ierr); ierr = PetscPartitionerSetType(part, PETSCPARTITIONERSHELL);CHKERRQ(ierr); ierr = PetscPartitionerShellSetPartition(part, size, sizes, points);CHKERRQ(ierr); } else { PetscPartitioner part; ierr = DMPlexGetPartitioner(*dm,&part);CHKERRQ(ierr); ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); } /* Distribute mesh over processes */ ierr = PetscLogStagePush(user->stages[STAGE_DISTRIBUTE]);CHKERRQ(ierr); ierr = DMPlexDistribute(*dm, 0, NULL, &distributedMesh);CHKERRQ(ierr); if (distributedMesh) { ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = distributedMesh; } ierr = PetscLogStagePop();CHKERRQ(ierr); ierr = DMViewFromOptions(*dm, NULL, "-distributed_dm_view");CHKERRQ(ierr); /* Refine mesh using a volume constraint */ ierr = PetscLogStagePush(user->stages[STAGE_REFINE]);CHKERRQ(ierr); ierr = DMPlexSetRefinementUniform(*dm, PETSC_FALSE);CHKERRQ(ierr); ierr = DMPlexSetRefinementLimit(*dm, refinementLimit);CHKERRQ(ierr); ierr = DMRefine(*dm, comm, &refinedMesh);CHKERRQ(ierr); if (refinedMesh) { ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = refinedMesh; } ierr = PetscLogStagePop();CHKERRQ(ierr); } ierr = PetscLogStagePush(user->stages[STAGE_REFINE]);CHKERRQ(ierr); ierr = DMSetFromOptions(*dm);CHKERRQ(ierr); ierr = PetscLogStagePop();CHKERRQ(ierr); if (testp4est_par) { #if defined(PETSC_HAVE_P4EST) DM dmConv = NULL; ierr = DMPlexSetRefinementUniform(*dm, PETSC_TRUE);CHKERRQ(ierr); ierr = DMPlexRefineSimplexToTensor(*dm, &dmConv);CHKERRQ(ierr); if (dmConv) { ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = dmConv; } user->cellSimplex = PETSC_FALSE; ierr = DMConvert(*dm,dim == 2 ? DMP4EST : DMP8EST,&dmConv);CHKERRQ(ierr); ierr = PetscObjectSetOptionsPrefix((PetscObject) dmConv, "conv_par_1_");CHKERRQ(ierr); if (dmConv) { ierr = DMSetFromOptions(dmConv);CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = dmConv; } ierr = DMSetUp(*dm);CHKERRQ(ierr); ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr); ierr = DMConvert(*dm,DMPLEX,&dmConv);CHKERRQ(ierr); ierr = PetscObjectSetOptionsPrefix((PetscObject) dmConv, "conv_par_2_");CHKERRQ(ierr); if (dmConv) { ierr = DMSetFromOptions(dmConv);CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = dmConv; } ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr); #else SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Recompile with --download-p4est"); #endif } if (user->overlap) { DM overlapMesh = NULL; /* Add the level-1 overlap to refined mesh */ ierr = PetscLogStagePush(user->stages[STAGE_OVERLAP]);CHKERRQ(ierr); ierr = DMPlexDistributeOverlap(*dm, 1, NULL, &overlapMesh);CHKERRQ(ierr); if (overlapMesh) { ierr = DMView(overlapMesh, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = overlapMesh; } ierr = PetscLogStagePop();CHKERRQ(ierr); } if (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; } ierr = PetscObjectSetName((PetscObject) *dm, "Simplicial Mesh");CHKERRQ(ierr); ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr); ierr = PetscLogEventEnd(user->createMeshEvent,0,0,0,0);CHKERRQ(ierr); user->dm = *dm; PetscFunctionReturn(0); }