1*25538a83SMatthew G. Knepley static char help[] = "Tests for ephemeral meshes.\n"; 2*25538a83SMatthew G. Knepley 3*25538a83SMatthew G. Knepley #include <petscdmplex.h> 4*25538a83SMatthew G. Knepley #include <petscdmplextransform.h> 5*25538a83SMatthew G. Knepley 6*25538a83SMatthew G. Knepley /* 7*25538a83SMatthew G. Knepley Use 8*25538a83SMatthew G. Knepley 9*25538a83SMatthew G. Knepley -ref_dm_view -eph_dm_view 10*25538a83SMatthew G. Knepley 11*25538a83SMatthew G. Knepley to view the concrete and ephemeral meshes from the first transformation, and 12*25538a83SMatthew G. Knepley 13*25538a83SMatthew G. Knepley -ref_dm_sec_view -eph_dm_sec_view 14*25538a83SMatthew G. Knepley 15*25538a83SMatthew G. Knepley for the second. 16*25538a83SMatthew G. Knepley */ 17*25538a83SMatthew G. Knepley 18*25538a83SMatthew G. Knepley // Should remove when I have an API for everything 19*25538a83SMatthew G. Knepley #include <petsc/private/dmplextransformimpl.h> 20*25538a83SMatthew G. Knepley 21*25538a83SMatthew G. Knepley typedef struct { 22*25538a83SMatthew G. Knepley DMLabel active; /* Label for transform */ 23*25538a83SMatthew G. Knepley PetscBool second; /* Flag to execute a second transformation */ 24*25538a83SMatthew G. Knepley PetscBool concrete; /* Flag to use the concrete mesh for the second transformation */ 25*25538a83SMatthew G. Knepley } AppCtx; 26*25538a83SMatthew G. Knepley 27*25538a83SMatthew G. Knepley static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 28*25538a83SMatthew G. Knepley { 29*25538a83SMatthew G. Knepley PetscInt cells[1024], Nc = 1024; 30*25538a83SMatthew G. Knepley PetscBool flg; 31*25538a83SMatthew G. Knepley 32*25538a83SMatthew G. Knepley PetscFunctionBeginUser; 33*25538a83SMatthew G. Knepley options->active = NULL; 34*25538a83SMatthew G. Knepley options->second = PETSC_FALSE; 35*25538a83SMatthew G. Knepley options->concrete = PETSC_FALSE; 36*25538a83SMatthew G. Knepley 37*25538a83SMatthew G. Knepley PetscOptionsBegin(comm, "", "Ephemeral Meshing Options", "DMPLEX"); 38*25538a83SMatthew G. Knepley PetscCall(PetscOptionsIntArray("-cells", "Cells to mark for transformation", "ex57.c", cells, &Nc, &flg)); 39*25538a83SMatthew G. Knepley if (flg) { 40*25538a83SMatthew G. Knepley PetscCall(DMLabelCreate(comm, "active", &options->active)); 41*25538a83SMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) PetscCall(DMLabelSetValue(options->active, cells[c], DM_ADAPT_REFINE)); 42*25538a83SMatthew G. Knepley } 43*25538a83SMatthew G. Knepley PetscCall(PetscOptionsBool("-second", "Use a second transformation", "ex57.c", options->second, &options->second, &flg)); 44*25538a83SMatthew G. Knepley PetscCall(PetscOptionsBool("-concrete", "Use concrete mesh for the second transformation", "ex57.c", options->concrete, &options->concrete, &flg)); 45*25538a83SMatthew G. Knepley PetscOptionsEnd(); 46*25538a83SMatthew G. Knepley PetscFunctionReturn(0); 47*25538a83SMatthew G. Knepley } 48*25538a83SMatthew G. Knepley 49*25538a83SMatthew G. Knepley static PetscErrorCode CreateMesh(MPI_Comm comm, DM *dm) 50*25538a83SMatthew G. Knepley { 51*25538a83SMatthew G. Knepley PetscFunctionBeginUser; 52*25538a83SMatthew G. Knepley PetscCall(DMCreate(comm, dm)); 53*25538a83SMatthew G. Knepley PetscCall(DMSetType(*dm, DMPLEX)); 54*25538a83SMatthew G. Knepley PetscCall(DMSetFromOptions(*dm)); 55*25538a83SMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)*dm, "Mesh")); 56*25538a83SMatthew G. Knepley PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view")); 57*25538a83SMatthew G. Knepley PetscFunctionReturn(0); 58*25538a83SMatthew G. Knepley } 59*25538a83SMatthew G. Knepley 60*25538a83SMatthew G. Knepley static PetscErrorCode CreateTransform(DM dm, DMLabel active, const char prefix[], DMPlexTransform *tr) 61*25538a83SMatthew G. Knepley { 62*25538a83SMatthew G. Knepley PetscFunctionBeginUser; 63*25538a83SMatthew G. Knepley PetscCall(DMPlexTransformCreate(PetscObjectComm((PetscObject)dm), tr)); 64*25538a83SMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)*tr, "Transform")); 65*25538a83SMatthew G. Knepley PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*tr, prefix)); 66*25538a83SMatthew G. Knepley PetscCall(DMPlexTransformSetDM(*tr, dm)); 67*25538a83SMatthew G. Knepley PetscCall(DMPlexTransformSetActive(*tr, active)); 68*25538a83SMatthew G. Knepley PetscCall(DMPlexTransformSetFromOptions(*tr)); 69*25538a83SMatthew G. Knepley PetscCall(DMPlexTransformSetUp(*tr)); 70*25538a83SMatthew G. Knepley 71*25538a83SMatthew G. Knepley PetscCall(DMSetApplicationContext(dm, *tr)); 72*25538a83SMatthew G. Knepley PetscCall(PetscObjectViewFromOptions((PetscObject)*tr, NULL, "-dm_plex_transform_view")); 73*25538a83SMatthew G. Knepley PetscFunctionReturn(0); 74*25538a83SMatthew G. Knepley } 75*25538a83SMatthew G. Knepley 76*25538a83SMatthew G. Knepley static PetscErrorCode CreateEphemeralMesh(DMPlexTransform tr, DM *tdm) 77*25538a83SMatthew G. Knepley { 78*25538a83SMatthew G. Knepley PetscFunctionBegin; 79*25538a83SMatthew G. Knepley PetscCall(DMCreate(PetscObjectComm((PetscObject)tr), tdm)); 80*25538a83SMatthew G. Knepley PetscCall(DMSetType(*tdm, DMPLEX)); 81*25538a83SMatthew G. Knepley PetscCall(DMSetFromOptions(*tdm)); 82*25538a83SMatthew G. Knepley 83*25538a83SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)tr)); 84*25538a83SMatthew G. Knepley PetscCall(DMPlexTransformDestroy(&((DM_Plex *)(*tdm)->data)->tr)); 85*25538a83SMatthew G. Knepley ((DM_Plex *)(*tdm)->data)->tr = tr; 86*25538a83SMatthew G. Knepley 87*25538a83SMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)*tdm, "Ephemeral Mesh")); 88*25538a83SMatthew G. Knepley PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*tdm, "eph_")); 89*25538a83SMatthew G. Knepley PetscFunctionReturn(0); 90*25538a83SMatthew G. Knepley } 91*25538a83SMatthew G. Knepley 92*25538a83SMatthew G. Knepley static PetscErrorCode CreateConcreteMesh(DMPlexTransform tr, DM *rdm) 93*25538a83SMatthew G. Knepley { 94*25538a83SMatthew G. Knepley DM cdm, codm, rcodm; 95*25538a83SMatthew G. Knepley 96*25538a83SMatthew G. Knepley PetscFunctionBegin; 97*25538a83SMatthew G. Knepley PetscCall(DMPlexTransformGetDM(tr, &cdm)); 98*25538a83SMatthew G. Knepley PetscCall(DMPlexTransformApply(tr, cdm, rdm)); 99*25538a83SMatthew G. Knepley PetscCall(DMSetCoarsenLevel(*rdm, cdm->leveldown)); 100*25538a83SMatthew G. Knepley PetscCall(DMSetRefineLevel(*rdm, cdm->levelup + 1)); 101*25538a83SMatthew G. Knepley PetscCall(DMCopyDisc(cdm, *rdm)); 102*25538a83SMatthew G. Knepley PetscCall(DMGetCoordinateDM(cdm, &codm)); 103*25538a83SMatthew G. Knepley PetscCall(DMGetCoordinateDM(*rdm, &rcodm)); 104*25538a83SMatthew G. Knepley PetscCall(DMCopyDisc(codm, rcodm)); 105*25538a83SMatthew G. Knepley PetscCall(DMPlexTransformCreateDiscLabels(tr, *rdm)); 106*25538a83SMatthew G. Knepley PetscCall(DMSetCoarseDM(*rdm, cdm)); 107*25538a83SMatthew G. Knepley PetscCall(DMPlexSetRegularRefinement(*rdm, PETSC_TRUE)); 108*25538a83SMatthew G. Knepley if (rdm) { 109*25538a83SMatthew G. Knepley ((DM_Plex *)(*rdm)->data)->printFEM = ((DM_Plex *)cdm->data)->printFEM; 110*25538a83SMatthew G. Knepley ((DM_Plex *)(*rdm)->data)->printL2 = ((DM_Plex *)cdm->data)->printL2; 111*25538a83SMatthew G. Knepley } 112*25538a83SMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)*rdm, "Concrete Mesh")); 113*25538a83SMatthew G. Knepley PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*rdm, "ref_")); 114*25538a83SMatthew G. Knepley PetscFunctionReturn(0); 115*25538a83SMatthew G. Knepley } 116*25538a83SMatthew G. Knepley 117*25538a83SMatthew G. Knepley static PetscErrorCode CompareMeshes(DM dmA, DM dmB, DM dm) 118*25538a83SMatthew G. Knepley { 119*25538a83SMatthew G. Knepley PetscInt dim, dimB, pStart, pEnd, pStartB, pEndB; 120*25538a83SMatthew G. Knepley MPI_Comm comm; 121*25538a83SMatthew G. Knepley 122*25538a83SMatthew G. Knepley PetscFunctionBegin; 123*25538a83SMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject)dmA, &comm)); 124*25538a83SMatthew G. Knepley PetscCall(DMGetDimension(dmA, &dim)); 125*25538a83SMatthew G. Knepley PetscCall(DMGetDimension(dmB, &dimB)); 126*25538a83SMatthew G. Knepley PetscCheck(dim == dimB, comm, PETSC_ERR_ARG_INCOMP, "Dimension from dmA %" PetscInt_FMT " != %" PetscInt_FMT " from dmB", dim, dimB); 127*25538a83SMatthew G. Knepley PetscCall(DMPlexGetChart(dmA, &pStart, &pEnd)); 128*25538a83SMatthew G. Knepley PetscCall(DMPlexGetChart(dmB, &pStartB, &pEndB)); 129*25538a83SMatthew G. Knepley PetscCheck(pStart == pStartB && pEnd == pEndB, comm, PETSC_ERR_ARG_INCOMP, "Chart from dmA (%" PetscInt_FMT ", %" PetscInt_FMT ") does not match (%" PetscInt_FMT ", %" PetscInt_FMT ") for dmB", pStart, pEnd, pStartB, pEndB); 130*25538a83SMatthew G. Knepley for (PetscInt p = pStart; p < pEnd; ++p) { 131*25538a83SMatthew G. Knepley const PetscInt *cone, *ornt, *coneB, *orntB; 132*25538a83SMatthew G. Knepley PetscInt coneSize, coneSizeB; 133*25538a83SMatthew G. Knepley 134*25538a83SMatthew G. Knepley PetscCall(DMPlexGetConeSize(dmA, p, &coneSize)); 135*25538a83SMatthew G. Knepley PetscCall(DMPlexGetConeSize(dmB, p, &coneSizeB)); 136*25538a83SMatthew G. Knepley PetscCheck(coneSize == coneSizeB, comm, PETSC_ERR_ARG_INCOMP, "Cone size for %" PetscInt_FMT " from dmA %" PetscInt_FMT " does not match %" PetscInt_FMT " for dmB", p, coneSize, coneSizeB); 137*25538a83SMatthew G. Knepley PetscCall(DMPlexGetOrientedCone(dmA, p, &cone, &ornt)); 138*25538a83SMatthew G. Knepley PetscCall(DMPlexGetOrientedCone(dmB, p, &coneB, &orntB)); 139*25538a83SMatthew G. Knepley for (PetscInt c = 0; c < coneSize; ++c) { 140*25538a83SMatthew G. Knepley PetscCheck(cone[c] == coneB[c] && ornt[c] == orntB[c], comm, PETSC_ERR_ARG_INCOMP, "Cone point %" PetscInt_FMT " for point %" PetscInt_FMT " from dmA (%" PetscInt_FMT ", %" PetscInt_FMT ") does not match (%" PetscInt_FMT ", %" PetscInt_FMT ") for dmB", c, p, cone[c], ornt[c], coneB[c], orntB[c]); 141*25538a83SMatthew G. Knepley } 142*25538a83SMatthew G. Knepley PetscCall(DMPlexRestoreOrientedCone(dmA, p, &cone, &ornt)); 143*25538a83SMatthew G. Knepley PetscCall(DMPlexRestoreOrientedCone(dmB, p, &coneB, &orntB)); 144*25538a83SMatthew G. Knepley } 145*25538a83SMatthew G. Knepley PetscFunctionReturn(0); 146*25538a83SMatthew G. Knepley } 147*25538a83SMatthew G. Knepley 148*25538a83SMatthew G. Knepley int main(int argc, char *argv[]) 149*25538a83SMatthew G. Knepley { 150*25538a83SMatthew G. Knepley DM dm, tdm, rdm; 151*25538a83SMatthew G. Knepley DMPlexTransform tr; 152*25538a83SMatthew G. Knepley AppCtx user; 153*25538a83SMatthew G. Knepley MPI_Comm comm; 154*25538a83SMatthew G. Knepley 155*25538a83SMatthew G. Knepley PetscFunctionBeginUser; 156*25538a83SMatthew G. Knepley PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 157*25538a83SMatthew G. Knepley comm = PETSC_COMM_WORLD; 158*25538a83SMatthew G. Knepley PetscCall(ProcessOptions(comm, &user)); 159*25538a83SMatthew G. Knepley PetscCall(CreateMesh(comm, &dm)); 160*25538a83SMatthew G. Knepley PetscCall(CreateTransform(dm, user.active, "first_", &tr)); 161*25538a83SMatthew G. Knepley PetscCall(CreateEphemeralMesh(tr, &tdm)); 162*25538a83SMatthew G. Knepley PetscCall(CreateConcreteMesh(tr, &rdm)); 163*25538a83SMatthew G. Knepley if (user.second) { 164*25538a83SMatthew G. Knepley DMPlexTransform tr2; 165*25538a83SMatthew G. Knepley DM tdm2, rdm2; 166*25538a83SMatthew G. Knepley 167*25538a83SMatthew G. Knepley PetscCall(DMViewFromOptions(rdm, NULL, "-dm_sec_view")); 168*25538a83SMatthew G. Knepley PetscCall(DMViewFromOptions(tdm, NULL, "-dm_sec_view")); 169*25538a83SMatthew G. Knepley if (user.concrete) PetscCall(CreateTransform(rdm, user.active, "second_", &tr2)); 170*25538a83SMatthew G. Knepley else PetscCall(CreateTransform(tdm, user.active, "second_", &tr2)); 171*25538a83SMatthew G. Knepley PetscCall(CreateEphemeralMesh(tr2, &tdm2)); 172*25538a83SMatthew G. Knepley PetscCall(CreateConcreteMesh(tr2, &rdm2)); 173*25538a83SMatthew G. Knepley PetscCall(DMDestroy(&tdm)); 174*25538a83SMatthew G. Knepley PetscCall(DMDestroy(&rdm)); 175*25538a83SMatthew G. Knepley PetscCall(DMPlexTransformDestroy(&tr2)); 176*25538a83SMatthew G. Knepley tdm = tdm2; 177*25538a83SMatthew G. Knepley rdm = rdm2; 178*25538a83SMatthew G. Knepley } 179*25538a83SMatthew G. Knepley PetscCall(DMViewFromOptions(tdm, NULL, "-dm_view")); 180*25538a83SMatthew G. Knepley PetscCall(DMViewFromOptions(rdm, NULL, "-dm_view")); 181*25538a83SMatthew G. Knepley PetscCall(CompareMeshes(rdm, tdm, dm)); 182*25538a83SMatthew G. Knepley PetscCall(DMPlexTransformDestroy(&tr)); 183*25538a83SMatthew G. Knepley PetscCall(DMDestroy(&tdm)); 184*25538a83SMatthew G. Knepley PetscCall(DMDestroy(&rdm)); 185*25538a83SMatthew G. Knepley PetscCall(DMDestroy(&dm)); 186*25538a83SMatthew G. Knepley PetscCall(DMLabelDestroy(&user.active)); 187*25538a83SMatthew G. Knepley PetscCall(PetscFinalize()); 188*25538a83SMatthew G. Knepley return 0; 189*25538a83SMatthew G. Knepley } 190*25538a83SMatthew G. Knepley 191*25538a83SMatthew G. Knepley /*TEST 192*25538a83SMatthew G. Knepley 193*25538a83SMatthew G. Knepley # Tests for regular refinement of whole meshes 194*25538a83SMatthew G. Knepley test: 195*25538a83SMatthew G. Knepley suffix: tri 196*25538a83SMatthew G. Knepley requires: triangle 197*25538a83SMatthew G. Knepley args: -first_dm_plex_transform_view ::ascii_info_detail 198*25538a83SMatthew G. Knepley 199*25538a83SMatthew G. Knepley test: 200*25538a83SMatthew G. Knepley suffix: quad 201*25538a83SMatthew G. Knepley args: -dm_plex_simplex 0 202*25538a83SMatthew G. Knepley 203*25538a83SMatthew G. Knepley test: 204*25538a83SMatthew G. Knepley suffix: tet 205*25538a83SMatthew G. Knepley requires: ctetgen 206*25538a83SMatthew G. Knepley args: -dm_plex_dim 3 207*25538a83SMatthew G. Knepley 208*25538a83SMatthew G. Knepley test: 209*25538a83SMatthew G. Knepley suffix: hex 210*25538a83SMatthew G. Knepley args: -dm_plex_dim 3 -dm_plex_simplex 0 211*25538a83SMatthew G. Knepley 212*25538a83SMatthew G. Knepley # Tests for filter patches 213*25538a83SMatthew G. Knepley testset: 214*25538a83SMatthew G. Knepley args: -first_dm_plex_transform_type transform_filter -ref_dm_view 215*25538a83SMatthew G. Knepley 216*25538a83SMatthew G. Knepley test: 217*25538a83SMatthew G. Knepley suffix: tri_patch 218*25538a83SMatthew G. Knepley requires: triangle 219*25538a83SMatthew G. Knepley args: -cells 0,1,2,4 220*25538a83SMatthew G. Knepley 221*25538a83SMatthew G. Knepley test: 222*25538a83SMatthew G. Knepley suffix: quad_patch 223*25538a83SMatthew G. Knepley args: -dm_plex_simplex 0 -dm_plex_box_faces 3,3 -cells 0,1,3,4 224*25538a83SMatthew G. Knepley 225*25538a83SMatthew G. Knepley # Tests for refined filter patches 226*25538a83SMatthew G. Knepley testset: 227*25538a83SMatthew G. Knepley args: -first_dm_plex_transform_type transform_filter -ref_dm_view -second 228*25538a83SMatthew G. Knepley 229*25538a83SMatthew G. Knepley test: 230*25538a83SMatthew G. Knepley suffix: tri_patch_ref 231*25538a83SMatthew G. Knepley requires: triangle 232*25538a83SMatthew G. Knepley args: -cells 0,1,2,4 233*25538a83SMatthew G. Knepley 234*25538a83SMatthew G. Knepley test: 235*25538a83SMatthew G. Knepley suffix: tri_patch_ref_concrete 236*25538a83SMatthew G. Knepley requires: triangle 237*25538a83SMatthew G. Knepley args: -cells 0,1,2,4 -concrete -first_dm_plex_transform_view ::ascii_info_detail 238*25538a83SMatthew G. Knepley 239*25538a83SMatthew G. Knepley # Tests for boundary layer refinement 240*25538a83SMatthew G. Knepley test: 241*25538a83SMatthew G. Knepley suffix: quad_bl 242*25538a83SMatthew G. Knepley args: -dm_plex_simplex 0 -dm_plex_dim 1 -dm_plex_box_faces 5 -dm_extrude 2 -cells 0,2,4,6,8 \ 243*25538a83SMatthew G. Knepley -first_dm_plex_transform_type refine_boundary_layer -first_dm_plex_transform_bl_splits 4 \ 244*25538a83SMatthew G. Knepley -ref_dm_view 245*25538a83SMatthew G. Knepley 246*25538a83SMatthew G. Knepley TEST*/ 247