1 static const char help[] = "Tests for mesh extrusion"; 2 3 #include <petscdmplex.h> 4 #include <petscdmforest.h> 5 6 typedef struct { 7 char bdLabel[PETSC_MAX_PATH_LEN]; /* The boundary label name */ 8 PetscInt Nbd; /* The number of boundary markers to extrude, 0 for all */ 9 PetscInt bd[64]; /* The boundary markers to be extruded */ 10 PetscBool testForest; /* Convert the mesh to a forest and back */ 11 } AppCtx; 12 13 PETSC_EXTERN PetscErrorCode pyramidNormal(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 14 15 /* The pyramid apex is at (0.5, 0.5, -1) */ 16 PetscErrorCode pyramidNormal(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt r, PetscScalar u[], void *ctx) 17 { 18 PetscReal apex[3] = {0.5, 0.5, -1.0}; 19 PetscInt d; 20 21 for (d = 0; d < dim; ++d) u[d] = x[d] - apex[d]; 22 for (d = dim; d < 3; ++d) u[d] = 0.0 - apex[d]; 23 return PETSC_SUCCESS; 24 } 25 26 static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 27 { 28 PetscInt n = 64; 29 PetscBool flg; 30 31 PetscFunctionBeginUser; 32 PetscCall(PetscStrncpy(options->bdLabel, "marker", sizeof(options->bdLabel))); 33 PetscOptionsBegin(comm, "", "Parallel Mesh Adaptation Options", "DMPLEX"); 34 PetscCall(PetscOptionsString("-label", "The boundary label name", "ex44.c", options->bdLabel, options->bdLabel, sizeof(options->bdLabel), NULL)); 35 PetscCall(PetscOptionsIntArray("-bd", "The boundaries to be extruded", "ex44.c", options->bd, &n, &flg)); 36 options->Nbd = flg ? n : 0; 37 options->testForest = PETSC_FALSE; 38 PetscCall(PetscOptionsBool("-test_forest", "Create a DMForest and then convert to DMPlex before testing", "ex44.c", PETSC_FALSE, &options->testForest, NULL)); 39 PetscOptionsEnd(); 40 PetscFunctionReturn(PETSC_SUCCESS); 41 } 42 43 static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *ctx, DM *dm) 44 { 45 PetscFunctionBegin; 46 PetscCall(DMCreate(comm, dm)); 47 PetscCall(DMSetType(*dm, DMPLEX)); 48 PetscCall(DMSetFromOptions(*dm)); 49 if (ctx->testForest) { 50 DM dmForest; 51 PetscInt dim; 52 PetscCall(DMGetDimension(*dm, &dim)); 53 PetscCall(DMCreate(PETSC_COMM_WORLD, &dmForest)); 54 PetscCall(DMSetType(dmForest, (dim == 2) ? DMP4EST : DMP8EST)); 55 PetscCall(DMForestSetBaseDM(dmForest, *dm)); 56 PetscCall(DMSetUp(dmForest)); 57 PetscCall(DMDestroy(dm)); 58 PetscCall(DMConvert(dmForest, DMPLEX, dm)); 59 PetscCall(DMDestroy(&dmForest)); 60 PetscCall(PetscObjectSetName((PetscObject)*dm, "forest")); 61 } 62 PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view")); 63 PetscFunctionReturn(PETSC_SUCCESS); 64 } 65 66 static PetscErrorCode CreateAdaptLabel(DM dm, AppCtx *ctx, DMLabel *adaptLabel) 67 { 68 DMLabel label; 69 PetscInt b; 70 71 PetscFunctionBegin; 72 if (!ctx->Nbd) { 73 *adaptLabel = NULL; 74 PetscFunctionReturn(PETSC_SUCCESS); 75 } 76 PetscCall(DMGetLabel(dm, ctx->bdLabel, &label)); 77 PetscCall(DMLabelCreate(PETSC_COMM_SELF, "Adaptation Label", adaptLabel)); 78 for (b = 0; b < ctx->Nbd; ++b) { 79 IS bdIS; 80 const PetscInt *points; 81 PetscInt n, i; 82 83 PetscCall(DMLabelGetStratumIS(label, ctx->bd[b], &bdIS)); 84 if (!bdIS) continue; 85 PetscCall(ISGetLocalSize(bdIS, &n)); 86 PetscCall(ISGetIndices(bdIS, &points)); 87 for (i = 0; i < n; ++i) PetscCall(DMLabelSetValue(*adaptLabel, points[i], DM_ADAPT_REFINE)); 88 PetscCall(ISRestoreIndices(bdIS, &points)); 89 PetscCall(ISDestroy(&bdIS)); 90 } 91 PetscFunctionReturn(PETSC_SUCCESS); 92 } 93 94 int main(int argc, char **argv) 95 { 96 DM dm, dma; 97 DMLabel adaptLabel; 98 AppCtx ctx; 99 100 PetscFunctionBeginUser; 101 PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 102 PetscCall(ProcessOptions(PETSC_COMM_WORLD, &ctx)); 103 PetscCall(CreateMesh(PETSC_COMM_WORLD, &ctx, &dm)); 104 PetscCall(CreateAdaptLabel(dm, &ctx, &adaptLabel)); 105 if (adaptLabel) { 106 PetscCall(DMAdaptLabel(dm, adaptLabel, &dma)); 107 } else { 108 PetscCall(DMExtrude(dm, 3, &dma)); 109 } 110 PetscCall(PetscObjectSetName((PetscObject)dma, "Adapted Mesh")); 111 PetscCall(DMLabelDestroy(&adaptLabel)); 112 PetscCall(DMDestroy(&dm)); 113 PetscCall(DMViewFromOptions(dma, NULL, "-adapt_dm_view")); 114 PetscCall(DMDestroy(&dma)); 115 PetscCall(PetscFinalize()); 116 return 0; 117 } 118 119 /*TEST 120 121 test: 122 suffix: seg_periodic_0 123 args: -dm_plex_dim 1 -dm_plex_box_faces 3 -dm_plex_transform_extrude_periodic -dm_plex_transform_extrude_use_tensor 0 \ 124 -dm_view -adapt_dm_view -dm_plex_check_all 125 126 test: 127 suffix: tri_tensor_0 128 requires: triangle 129 args: -dm_plex_transform_extrude_use_tensor {{0 1}separate output} \ 130 -dm_view -adapt_dm_view -dm_plex_check_all 131 132 test: 133 suffix: quad_tensor_0 134 args: -dm_plex_simplex 0 -dm_plex_transform_extrude_use_tensor {{0 1}separate output} \ 135 -dm_view -adapt_dm_view -dm_plex_check_all 136 137 test: 138 suffix: quad_tensor_0_forest 139 requires: p4est 140 args: -dm_plex_simplex 0 -dm_plex_transform_extrude_use_tensor {{0 1}separate output} \ 141 -dm_view -adapt_dm_view -dm_plex_check_all -test_forest 1 142 143 test: 144 suffix: quad_normal_0 145 args: -dm_plex_simplex 0 -dm_plex_transform_extrude_normal 0,1,1 \ 146 -dm_view -adapt_dm_view -dm_plex_check_all 147 148 test: 149 suffix: quad_normal_0_forest 150 requires: p4est 151 args: -dm_plex_simplex 0 -dm_plex_transform_extrude_normal 0,1,1 \ 152 -dm_view -adapt_dm_view -dm_plex_check_all -test_forest 1 153 154 test: 155 suffix: quad_normal_1 156 args: -dm_plex_simplex 0 -dm_plex_transform_extrude_normal_function pyramidNormal \ 157 -dm_view -adapt_dm_view -dm_plex_check_all 158 159 test: 160 suffix: quad_normal_1_forest 161 requires: p4est 162 args: -dm_plex_simplex 0 -dm_plex_transform_extrude_normal_function pyramidNormal \ 163 -dm_view -adapt_dm_view -dm_plex_check_all -test_forest 1 164 165 test: 166 suffix: quad_symmetric_0 167 args: -dm_plex_simplex 0 -dm_plex_transform_extrude_symmetric \ 168 -dm_view -adapt_dm_view -dm_plex_check_all 169 170 test: 171 suffix: quad_symmetric_0_forest 172 requires: p4est 173 args: -dm_plex_simplex 0 -dm_plex_transform_extrude_symmetric \ 174 -dm_view -adapt_dm_view -dm_plex_check_all -test_forest 1 175 176 test: 177 suffix: quad_label 178 args: -dm_plex_simplex 0 -dm_plex_transform_label_replica_inc {{0 100}separate output} \ 179 -dm_view -adapt_dm_view -dm_plex_check_all 180 181 test: 182 suffix: quad_periodic_0 183 args: -dm_plex_simplex 0 -dm_plex_transform_extrude_periodic -dm_plex_transform_extrude_use_tensor 0 \ 184 -dm_view -adapt_dm_view -dm_plex_check_all 185 186 testset: 187 args: -dm_adaptor cellrefiner -dm_plex_transform_type extrude \ 188 -dm_view -adapt_dm_view 189 190 test: 191 suffix: tri_adapt_0 192 requires: triangle 193 args: -dm_plex_box_faces 2,2 -dm_plex_separate_marker -bd 1,3 \ 194 -dm_plex_transform_extrude_thickness 0.5 195 196 test: 197 suffix: tri_adapt_1 198 requires: triangle 199 nsize: 2 200 args: -dm_plex_box_faces 2,2 -bd 1 \ 201 -dm_plex_transform_extrude_thickness 0.5 -petscpartitioner_type simple 202 203 test: 204 suffix: quad_adapt_0 205 args: -dm_plex_simplex 0 -dm_plex_box_faces 2,2 -dm_plex_separate_marker -bd 1,3 \ 206 -dm_plex_transform_extrude_thickness 0.5 207 208 test: 209 suffix: quad_adapt_1 210 nsize: 2 211 args: -dm_plex_simplex 0 -dm_plex_box_faces 2,2 -bd 1 \ 212 -dm_plex_transform_extrude_thickness 0.5 -petscpartitioner_type simple 213 214 test: 215 suffix: quad_adapt_1_forest 216 requires: p4est 217 nsize: 2 218 args: -dm_plex_simplex 0 -dm_plex_box_faces 2,2 -bd 1 \ 219 -dm_plex_transform_extrude_thickness 0.5 -petscpartitioner_type simple \ 220 -test_forest 1 221 222 test: 223 suffix: tet_adapt_0 224 requires: ctetgen 225 args: -dm_plex_dim 3 -dm_plex_box_faces 2,2,2 -dm_plex_separate_marker -bd 1,3 \ 226 -dm_plex_transform_extrude_thickness 0.5 227 228 test: 229 suffix: tet_adapt_1 230 requires: ctetgen 231 nsize: 2 232 args: -dm_plex_dim 3 -dm_plex_box_faces 2,2,2 -bd 1 \ 233 -dm_plex_transform_extrude_thickness 0.5 -petscpartitioner_type simple 234 235 test: 236 suffix: hex_adapt_0 237 args: -dm_plex_simplex 0 -dm_plex_dim 3 -dm_plex_box_faces 2,2,2 -dm_plex_separate_marker -bd 1,3 \ 238 -dm_plex_transform_extrude_thickness 0.5 239 240 TEST*/ 241