1503c0ea9SMatthew G. Knepley static const char help[] = "Tests for mesh extrusion"; 2503c0ea9SMatthew G. Knepley 3503c0ea9SMatthew G. Knepley #include <petscdmplex.h> 4*83b0cc01SDavid Salac #include <petscdmforest.h> 5503c0ea9SMatthew G. Knepley 6503c0ea9SMatthew G. Knepley typedef struct { 7503c0ea9SMatthew G. Knepley char bdLabel[PETSC_MAX_PATH_LEN]; /* The boundary label name */ 8503c0ea9SMatthew G. Knepley PetscInt Nbd; /* The number of boundary markers to extrude, 0 for all */ 9503c0ea9SMatthew G. Knepley PetscInt bd[64]; /* The boundary markers to be extruded */ 10*83b0cc01SDavid Salac PetscBool testForest; /* Convert the mesh to a forest and back */ 11503c0ea9SMatthew G. Knepley } AppCtx; 12503c0ea9SMatthew G. Knepley 13503c0ea9SMatthew G. Knepley PETSC_EXTERN PetscErrorCode pyramidNormal(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 14503c0ea9SMatthew G. Knepley 15503c0ea9SMatthew G. Knepley /* The pyramid apex is at (0.5, 0.5, -1) */ 16d71ae5a4SJacob Faibussowitsch PetscErrorCode pyramidNormal(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt r, PetscScalar u[], void *ctx) 17d71ae5a4SJacob Faibussowitsch { 18503c0ea9SMatthew G. Knepley PetscReal apex[3] = {0.5, 0.5, -1.0}; 19503c0ea9SMatthew G. Knepley PetscInt d; 20503c0ea9SMatthew G. Knepley 21503c0ea9SMatthew G. Knepley for (d = 0; d < dim; ++d) u[d] = x[d] - apex[d]; 22503c0ea9SMatthew G. Knepley for (d = dim; d < 3; ++d) u[d] = 0.0 - apex[d]; 233ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 24503c0ea9SMatthew G. Knepley } 25503c0ea9SMatthew G. Knepley 26d71ae5a4SJacob Faibussowitsch static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 27d71ae5a4SJacob Faibussowitsch { 28503c0ea9SMatthew G. Knepley PetscInt n = 64; 29503c0ea9SMatthew G. Knepley PetscBool flg; 30503c0ea9SMatthew G. Knepley 31503c0ea9SMatthew G. Knepley PetscFunctionBeginUser; 32c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(options->bdLabel, "marker", sizeof(options->bdLabel))); 33d0609cedSBarry Smith PetscOptionsBegin(comm, "", "Parallel Mesh Adaptation Options", "DMPLEX"); 34503c0ea9SMatthew G. Knepley PetscCall(PetscOptionsString("-label", "The boundary label name", "ex44.c", options->bdLabel, options->bdLabel, sizeof(options->bdLabel), NULL)); 35503c0ea9SMatthew G. Knepley PetscCall(PetscOptionsIntArray("-bd", "The boundaries to be extruded", "ex44.c", options->bd, &n, &flg)); 36503c0ea9SMatthew G. Knepley options->Nbd = flg ? n : 0; 37*83b0cc01SDavid Salac options->testForest = PETSC_FALSE; 38*83b0cc01SDavid Salac PetscCall(PetscOptionsBool("-test_forest", "Create a DMForest and then convert to DMPlex before testing", "ex44.c", PETSC_FALSE, &options->testForest, NULL)); 39d0609cedSBarry Smith PetscOptionsEnd(); 403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 41503c0ea9SMatthew G. Knepley } 42503c0ea9SMatthew G. Knepley 43d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *ctx, DM *dm) 44d71ae5a4SJacob Faibussowitsch { 45503c0ea9SMatthew G. Knepley PetscFunctionBegin; 46503c0ea9SMatthew G. Knepley PetscCall(DMCreate(comm, dm)); 47503c0ea9SMatthew G. Knepley PetscCall(DMSetType(*dm, DMPLEX)); 48503c0ea9SMatthew G. Knepley PetscCall(DMSetFromOptions(*dm)); 49*83b0cc01SDavid Salac if (ctx->testForest) { 50*83b0cc01SDavid Salac DM dmForest; 51*83b0cc01SDavid Salac PetscInt dim; 52*83b0cc01SDavid Salac PetscCall(DMGetDimension(*dm, &dim)); 53*83b0cc01SDavid Salac PetscCall(DMCreate(PETSC_COMM_WORLD, &dmForest)); 54*83b0cc01SDavid Salac PetscCall(DMSetType(dmForest, (dim == 2) ? DMP4EST : DMP8EST)); 55*83b0cc01SDavid Salac PetscCall(DMForestSetBaseDM(dmForest, *dm)); 56*83b0cc01SDavid Salac PetscCall(DMSetUp(dmForest)); 57*83b0cc01SDavid Salac PetscCall(DMDestroy(dm)); 58*83b0cc01SDavid Salac PetscCall(DMConvert(dmForest, DMPLEX, dm)); 59*83b0cc01SDavid Salac PetscCall(DMDestroy(&dmForest)); 60*83b0cc01SDavid Salac PetscCall(PetscObjectSetName((PetscObject)*dm, "forest")); 61*83b0cc01SDavid Salac } 62503c0ea9SMatthew G. Knepley PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view")); 633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 64503c0ea9SMatthew G. Knepley } 65503c0ea9SMatthew G. Knepley 66d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateAdaptLabel(DM dm, AppCtx *ctx, DMLabel *adaptLabel) 67d71ae5a4SJacob Faibussowitsch { 68503c0ea9SMatthew G. Knepley DMLabel label; 69503c0ea9SMatthew G. Knepley PetscInt b; 70503c0ea9SMatthew G. Knepley 71503c0ea9SMatthew G. Knepley PetscFunctionBegin; 729371c9d4SSatish Balay if (!ctx->Nbd) { 739371c9d4SSatish Balay *adaptLabel = NULL; 743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 759371c9d4SSatish Balay } 76503c0ea9SMatthew G. Knepley PetscCall(DMGetLabel(dm, ctx->bdLabel, &label)); 77503c0ea9SMatthew G. Knepley PetscCall(DMLabelCreate(PETSC_COMM_SELF, "Adaptation Label", adaptLabel)); 78503c0ea9SMatthew G. Knepley for (b = 0; b < ctx->Nbd; ++b) { 79503c0ea9SMatthew G. Knepley IS bdIS; 80503c0ea9SMatthew G. Knepley const PetscInt *points; 81503c0ea9SMatthew G. Knepley PetscInt n, i; 82503c0ea9SMatthew G. Knepley 83503c0ea9SMatthew G. Knepley PetscCall(DMLabelGetStratumIS(label, ctx->bd[b], &bdIS)); 84503c0ea9SMatthew G. Knepley if (!bdIS) continue; 85503c0ea9SMatthew G. Knepley PetscCall(ISGetLocalSize(bdIS, &n)); 86503c0ea9SMatthew G. Knepley PetscCall(ISGetIndices(bdIS, &points)); 8748a46eb9SPierre Jolivet for (i = 0; i < n; ++i) PetscCall(DMLabelSetValue(*adaptLabel, points[i], DM_ADAPT_REFINE)); 88503c0ea9SMatthew G. Knepley PetscCall(ISRestoreIndices(bdIS, &points)); 89503c0ea9SMatthew G. Knepley PetscCall(ISDestroy(&bdIS)); 90503c0ea9SMatthew G. Knepley } 913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92503c0ea9SMatthew G. Knepley } 93503c0ea9SMatthew G. Knepley 94d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv) 95d71ae5a4SJacob Faibussowitsch { 96503c0ea9SMatthew G. Knepley DM dm, dma; 97503c0ea9SMatthew G. Knepley DMLabel adaptLabel; 98503c0ea9SMatthew G. Knepley AppCtx ctx; 99503c0ea9SMatthew G. Knepley 100327415f7SBarry Smith PetscFunctionBeginUser; 101503c0ea9SMatthew G. Knepley PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 102503c0ea9SMatthew G. Knepley PetscCall(ProcessOptions(PETSC_COMM_WORLD, &ctx)); 103503c0ea9SMatthew G. Knepley PetscCall(CreateMesh(PETSC_COMM_WORLD, &ctx, &dm)); 104503c0ea9SMatthew G. Knepley PetscCall(CreateAdaptLabel(dm, &ctx, &adaptLabel)); 1059371c9d4SSatish Balay if (adaptLabel) { 1069371c9d4SSatish Balay PetscCall(DMAdaptLabel(dm, adaptLabel, &dma)); 1079371c9d4SSatish Balay } else { 1089371c9d4SSatish Balay PetscCall(DMExtrude(dm, 3, &dma)); 1099371c9d4SSatish Balay } 110503c0ea9SMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)dma, "Adapted Mesh")); 111503c0ea9SMatthew G. Knepley PetscCall(DMLabelDestroy(&adaptLabel)); 112503c0ea9SMatthew G. Knepley PetscCall(DMDestroy(&dm)); 113503c0ea9SMatthew G. Knepley PetscCall(DMViewFromOptions(dma, NULL, "-adapt_dm_view")); 114503c0ea9SMatthew G. Knepley PetscCall(DMDestroy(&dma)); 115503c0ea9SMatthew G. Knepley PetscCall(PetscFinalize()); 116503c0ea9SMatthew G. Knepley return 0; 117503c0ea9SMatthew G. Knepley } 118503c0ea9SMatthew G. Knepley 119503c0ea9SMatthew G. Knepley /*TEST 120503c0ea9SMatthew G. Knepley 121503c0ea9SMatthew G. Knepley test: 122c403ad25SMatthew G. Knepley suffix: seg_periodic_0 123c403ad25SMatthew G. Knepley args: -dm_plex_dim 1 -dm_plex_box_faces 3 -dm_plex_transform_extrude_periodic -dm_plex_transform_extrude_use_tensor 0 \ 124c403ad25SMatthew G. Knepley -dm_view -adapt_dm_view -dm_plex_check_all 125c403ad25SMatthew G. Knepley 126c403ad25SMatthew G. Knepley test: 127503c0ea9SMatthew G. Knepley suffix: tri_tensor_0 128503c0ea9SMatthew G. Knepley requires: triangle 129503c0ea9SMatthew G. Knepley args: -dm_plex_transform_extrude_use_tensor {{0 1}separate output} \ 130503c0ea9SMatthew G. Knepley -dm_view -adapt_dm_view -dm_plex_check_all 131503c0ea9SMatthew G. Knepley 132503c0ea9SMatthew G. Knepley test: 133503c0ea9SMatthew G. Knepley suffix: quad_tensor_0 134503c0ea9SMatthew G. Knepley args: -dm_plex_simplex 0 -dm_plex_transform_extrude_use_tensor {{0 1}separate output} \ 135503c0ea9SMatthew G. Knepley -dm_view -adapt_dm_view -dm_plex_check_all 136503c0ea9SMatthew G. Knepley 137503c0ea9SMatthew G. Knepley test: 138*83b0cc01SDavid Salac suffix: quad_tensor_0_forest 139*83b0cc01SDavid Salac requires: p4est 140*83b0cc01SDavid Salac args: -dm_plex_simplex 0 -dm_plex_transform_extrude_use_tensor {{0 1}separate output} \ 141*83b0cc01SDavid Salac -dm_view -adapt_dm_view -dm_plex_check_all -test_forest 1 142*83b0cc01SDavid Salac 143*83b0cc01SDavid Salac test: 144503c0ea9SMatthew G. Knepley suffix: quad_normal_0 145503c0ea9SMatthew G. Knepley args: -dm_plex_simplex 0 -dm_plex_transform_extrude_normal 0,1,1 \ 146503c0ea9SMatthew G. Knepley -dm_view -adapt_dm_view -dm_plex_check_all 147503c0ea9SMatthew G. Knepley 148503c0ea9SMatthew G. Knepley test: 149*83b0cc01SDavid Salac suffix: quad_normal_0_forest 150*83b0cc01SDavid Salac requires: p4est 151*83b0cc01SDavid Salac args: -dm_plex_simplex 0 -dm_plex_transform_extrude_normal 0,1,1 \ 152*83b0cc01SDavid Salac -dm_view -adapt_dm_view -dm_plex_check_all -test_forest 1 153*83b0cc01SDavid Salac 154*83b0cc01SDavid Salac test: 155503c0ea9SMatthew G. Knepley suffix: quad_normal_1 156503c0ea9SMatthew G. Knepley args: -dm_plex_simplex 0 -dm_plex_transform_extrude_normal_function pyramidNormal \ 157503c0ea9SMatthew G. Knepley -dm_view -adapt_dm_view -dm_plex_check_all 158503c0ea9SMatthew G. Knepley 159503c0ea9SMatthew G. Knepley test: 160*83b0cc01SDavid Salac suffix: quad_normal_1_forest 161*83b0cc01SDavid Salac requires: p4est 162*83b0cc01SDavid Salac args: -dm_plex_simplex 0 -dm_plex_transform_extrude_normal_function pyramidNormal \ 163*83b0cc01SDavid Salac -dm_view -adapt_dm_view -dm_plex_check_all -test_forest 1 164*83b0cc01SDavid Salac 165*83b0cc01SDavid Salac test: 166503c0ea9SMatthew G. Knepley suffix: quad_symmetric_0 167503c0ea9SMatthew G. Knepley args: -dm_plex_simplex 0 -dm_plex_transform_extrude_symmetric \ 168503c0ea9SMatthew G. Knepley -dm_view -adapt_dm_view -dm_plex_check_all 169503c0ea9SMatthew G. Knepley 170533617b7SMatthew G. Knepley test: 171*83b0cc01SDavid Salac suffix: quad_symmetric_0_forest 172*83b0cc01SDavid Salac requires: p4est 173*83b0cc01SDavid Salac args: -dm_plex_simplex 0 -dm_plex_transform_extrude_symmetric \ 174*83b0cc01SDavid Salac -dm_view -adapt_dm_view -dm_plex_check_all -test_forest 1 175*83b0cc01SDavid Salac 176*83b0cc01SDavid Salac test: 177533617b7SMatthew G. Knepley suffix: quad_label 178533617b7SMatthew G. Knepley args: -dm_plex_simplex 0 -dm_plex_transform_label_replica_inc {{0 100}separate output} \ 179533617b7SMatthew G. Knepley -dm_view -adapt_dm_view -dm_plex_check_all 180533617b7SMatthew G. Knepley 181c403ad25SMatthew G. Knepley test: 182c403ad25SMatthew G. Knepley suffix: quad_periodic_0 183c403ad25SMatthew G. Knepley args: -dm_plex_simplex 0 -dm_plex_transform_extrude_periodic -dm_plex_transform_extrude_use_tensor 0 \ 184c403ad25SMatthew G. Knepley -dm_view -adapt_dm_view -dm_plex_check_all 185c403ad25SMatthew G. Knepley 186503c0ea9SMatthew G. Knepley testset: 187503c0ea9SMatthew G. Knepley args: -dm_adaptor cellrefiner -dm_plex_transform_type extrude \ 188503c0ea9SMatthew G. Knepley -dm_view -adapt_dm_view 189503c0ea9SMatthew G. Knepley 190503c0ea9SMatthew G. Knepley test: 191aa0a2741SMatthew G. Knepley suffix: tri_adapt_0 192aa0a2741SMatthew G. Knepley requires: triangle 193aa0a2741SMatthew G. Knepley args: -dm_plex_box_faces 2,2 -dm_plex_separate_marker -bd 1,3 \ 194aa0a2741SMatthew G. Knepley -dm_plex_transform_extrude_thickness 0.5 195aa0a2741SMatthew G. Knepley 196aa0a2741SMatthew G. Knepley test: 197aa0a2741SMatthew G. Knepley suffix: tri_adapt_1 198aa0a2741SMatthew G. Knepley requires: triangle 199aa0a2741SMatthew G. Knepley nsize: 2 200aa0a2741SMatthew G. Knepley args: -dm_plex_box_faces 2,2 -bd 1 \ 201aa0a2741SMatthew G. Knepley -dm_plex_transform_extrude_thickness 0.5 -petscpartitioner_type simple 202aa0a2741SMatthew G. Knepley 203aa0a2741SMatthew G. Knepley test: 204503c0ea9SMatthew G. Knepley suffix: quad_adapt_0 205230bd717SMatthew G. Knepley args: -dm_plex_simplex 0 -dm_plex_box_faces 2,2 -dm_plex_separate_marker -bd 1,3 \ 206230bd717SMatthew G. Knepley -dm_plex_transform_extrude_thickness 0.5 207503c0ea9SMatthew G. Knepley 20879a429efSMatthew G. Knepley test: 209bb21c8c5SMatthew G. Knepley suffix: quad_adapt_1 210bb21c8c5SMatthew G. Knepley nsize: 2 211bb21c8c5SMatthew G. Knepley args: -dm_plex_simplex 0 -dm_plex_box_faces 2,2 -bd 1 \ 212bb21c8c5SMatthew G. Knepley -dm_plex_transform_extrude_thickness 0.5 -petscpartitioner_type simple 213bb21c8c5SMatthew G. Knepley 214bb21c8c5SMatthew G. Knepley test: 215*83b0cc01SDavid Salac suffix: quad_adapt_1_forest 216*83b0cc01SDavid Salac requires: p4est 217*83b0cc01SDavid Salac nsize: 2 218*83b0cc01SDavid Salac args: -dm_plex_simplex 0 -dm_plex_box_faces 2,2 -bd 1 \ 219*83b0cc01SDavid Salac -dm_plex_transform_extrude_thickness 0.5 -petscpartitioner_type simple \ 220*83b0cc01SDavid Salac -test_forest 1 221*83b0cc01SDavid Salac 222*83b0cc01SDavid Salac test: 22379a429efSMatthew G. Knepley suffix: tet_adapt_0 22479a4bf6cSMatthew G. Knepley requires: ctetgen 22579a429efSMatthew G. Knepley args: -dm_plex_dim 3 -dm_plex_box_faces 2,2,2 -dm_plex_separate_marker -bd 1,3 \ 22679a429efSMatthew G. Knepley -dm_plex_transform_extrude_thickness 0.5 22779a429efSMatthew G. Knepley 22879a429efSMatthew G. Knepley test: 229aa0a2741SMatthew G. Knepley suffix: tet_adapt_1 230aa0a2741SMatthew G. Knepley requires: ctetgen 231aa0a2741SMatthew G. Knepley nsize: 2 232aa0a2741SMatthew G. Knepley args: -dm_plex_dim 3 -dm_plex_box_faces 2,2,2 -bd 1 \ 233aa0a2741SMatthew G. Knepley -dm_plex_transform_extrude_thickness 0.5 -petscpartitioner_type simple 234aa0a2741SMatthew G. Knepley 235aa0a2741SMatthew G. Knepley test: 23679a429efSMatthew G. Knepley suffix: hex_adapt_0 23779a429efSMatthew G. Knepley args: -dm_plex_simplex 0 -dm_plex_dim 3 -dm_plex_box_faces 2,2,2 -dm_plex_separate_marker -bd 1,3 \ 23879a429efSMatthew G. Knepley -dm_plex_transform_extrude_thickness 0.5 23979a429efSMatthew G. Knepley 240503c0ea9SMatthew G. Knepley TEST*/ 241