1 static char help[] = "Tests for mesh interpolation\n\n"; 2 3 #include <petscdmplex.h> 4 5 /* List of test meshes 6 7 Triangle 8 -------- 9 Test 0: 10 Two triangles sharing a face 11 12 4 13 / | \ 14 / | \ 15 / | \ 16 2 0 | 1 5 17 \ | / 18 \ | / 19 \ | / 20 3 21 22 should become 23 24 4 25 / | \ 26 8 | 9 27 / | \ 28 2 0 7 1 5 29 \ | / 30 6 | 10 31 \ | / 32 3 33 34 Tetrahedron 35 ----------- 36 Test 0: 37 Two tets sharing a face 38 39 cell 5 _______ cell 40 0 / | \ \ 1 41 / | \ \ 42 / | \ \ 43 2----|----4-----6 44 \ | / / 45 \ | / / 46 \ | / / 47 3------- 48 49 should become 50 51 cell 5 _______ cell 52 0 / | \ \ 1 53 / | \ \ 54 17 | 18 13 22 55 / 8 19 10 \ \ 56 / | \ \ 57 2---14-|------4--20--6 58 \ | / / 59 \ 9 | 7 / / 60 16 | 15 11 21 61 \ | / / 62 \ | / / 63 3------- 64 65 Quadrilateral 66 ------------- 67 Test 0: 68 Two quads sharing a face 69 70 5-------4-------7 71 | | | 72 | 0 | 1 | 73 | | | 74 2-------3-------6 75 76 should become 77 78 5--10---4--14---7 79 | | | 80 11 0 9 1 13 81 | | | 82 2---8---3--12---6 83 84 Test 1: 85 A quad and a triangle sharing a face 86 87 5-------4 88 | | \ 89 | 0 | \ 90 | | 1 \ 91 2-------3----6 92 93 should become 94 95 5---9---4 96 | | \ 97 10 0 8 12 98 | | 1 \ 99 2---7---3-11-6 100 101 Hexahedron 102 ---------- 103 Test 0: 104 Two hexes sharing a face 105 106 cell 9-------------8-------------13 cell 107 0 /| /| /| 1 108 / | 15 / | 21 / | 109 / | / | / | 110 6-------------7-------------12 | 111 | | 18 | | 24 | | 112 | | | | | | 113 |19 | |17 | |23 | 114 | | 16 | | 22 | | 115 | 5---------|---4---------|---11 116 | / | / | / 117 | / 14 | / 20 | / 118 |/ |/ |/ 119 2-------------3-------------10 120 121 should become 122 123 cell 9-----31------8-----42------13 cell 124 0 /| /| /| 1 125 32 | 15 30| 21 41| 126 / | / | / | 127 6-----29------7-----40------12 | 128 | | 17 | | 23 | | 129 | 35 | 36 | 44 130 |19 | |18 | |24 | 131 34 | 16 33 | 22 43 | 132 | 5-----26--|---4-----37--|---11 133 | / | / | / 134 | 25 14 | 27 20 | 38 135 |/ |/ |/ 136 2-----28------3-----39------10 137 138 */ 139 140 typedef struct { 141 PetscInt testNum; /* Indicates the mesh to create */ 142 PetscInt dim; /* The topological mesh dimension */ 143 PetscBool simplex; /* Use simplices or hexes */ 144 PetscBool useGenerator; /* Construct mesh with a mesh generator */ 145 } AppCtx; 146 147 PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 148 { 149 PetscFunctionBegin; 150 options->testNum = 0; 151 options->dim = 2; 152 options->simplex = PETSC_TRUE; 153 options->useGenerator = PETSC_FALSE; 154 155 PetscOptionsBegin(comm, "", "Meshing Interpolation Test Options", "DMPLEX"); 156 PetscCall(PetscOptionsBoundedInt("-testnum", "The mesh to create", "ex7.c", options->testNum, &options->testNum, NULL, 0)); 157 PetscCall(PetscOptionsRangeInt("-dim", "The topological mesh dimension", "ex7.c", options->dim, &options->dim, NULL, 1, 3)); 158 PetscCall(PetscOptionsBool("-simplex", "Use simplices if true, otherwise hexes", "ex7.c", options->simplex, &options->simplex, NULL)); 159 PetscCall(PetscOptionsBool("-use_generator", "Use a mesh generator to build the mesh", "ex7.c", options->useGenerator, &options->useGenerator, NULL)); 160 PetscOptionsEnd(); 161 PetscFunctionReturn(PETSC_SUCCESS); 162 } 163 164 PetscErrorCode CreateSimplex_2D(MPI_Comm comm, DM dm) 165 { 166 PetscInt depth = 1, testNum = 0, p; 167 PetscMPIInt rank; 168 169 PetscFunctionBegin; 170 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 171 if (rank == 0) { 172 switch (testNum) { 173 case 0: { 174 PetscInt numPoints[2] = {4, 2}; 175 PetscInt coneSize[6] = {3, 3, 0, 0, 0, 0}; 176 PetscInt cones[6] = {2, 3, 4, 5, 4, 3}; 177 PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0}; 178 PetscScalar vertexCoords[8] = {-0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 0.5, 0.5}; 179 PetscInt markerPoints[8] = {2, 1, 3, 1, 4, 1, 5, 1}; 180 181 PetscCall(DMPlexCreateFromDAG(dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords)); 182 for (p = 0; p < 4; ++p) PetscCall(DMSetLabelValue(dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1])); 183 } break; 184 default: 185 SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %" PetscInt_FMT, testNum); 186 } 187 } else { 188 PetscInt numPoints[2] = {0, 0}; 189 190 PetscCall(DMPlexCreateFromDAG(dm, depth, numPoints, NULL, NULL, NULL, NULL)); 191 PetscCall(DMCreateLabel(dm, "marker")); 192 } 193 PetscFunctionReturn(PETSC_SUCCESS); 194 } 195 196 PetscErrorCode CreateSimplex_3D(MPI_Comm comm, DM dm) 197 { 198 PetscInt depth = 1, testNum = 0, p; 199 PetscMPIInt rank; 200 201 PetscFunctionBegin; 202 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 203 if (rank == 0) { 204 switch (testNum) { 205 case 0: { 206 PetscInt numPoints[2] = {5, 2}; 207 PetscInt coneSize[23] = {4, 4, 0, 0, 0, 0, 0}; 208 PetscInt cones[8] = {2, 4, 3, 5, 3, 4, 6, 5}; 209 PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 210 PetscScalar vertexCoords[15] = {0.0, 0.0, -0.5, 0.0, -0.5, 0.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5}; 211 PetscInt markerPoints[8] = {2, 1, 3, 1, 4, 1, 5, 1}; 212 213 PetscCall(DMPlexCreateFromDAG(dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords)); 214 for (p = 0; p < 4; ++p) PetscCall(DMSetLabelValue(dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1])); 215 } break; 216 default: 217 SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %" PetscInt_FMT, testNum); 218 } 219 } else { 220 PetscInt numPoints[2] = {0, 0}; 221 222 PetscCall(DMPlexCreateFromDAG(dm, depth, numPoints, NULL, NULL, NULL, NULL)); 223 PetscCall(DMCreateLabel(dm, "marker")); 224 } 225 PetscFunctionReturn(PETSC_SUCCESS); 226 } 227 228 PetscErrorCode CreateQuad_2D(MPI_Comm comm, PetscInt testNum, DM dm) 229 { 230 PetscInt depth = 1, p; 231 PetscMPIInt rank; 232 233 PetscFunctionBegin; 234 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 235 if (rank == 0) { 236 switch (testNum) { 237 case 0: { 238 PetscInt numPoints[2] = {6, 2}; 239 PetscInt coneSize[8] = {4, 4, 0, 0, 0, 0, 0, 0}; 240 PetscInt cones[8] = {2, 3, 4, 5, 3, 6, 7, 4}; 241 PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 242 PetscScalar vertexCoords[12] = {-0.5, 0.0, 0.0, 0.0, 0.0, 1.0, -0.5, 1.0, 0.5, 0.0, 0.5, 1.0}; 243 PetscInt markerPoints[12] = {2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1}; 244 245 PetscCall(DMPlexCreateFromDAG(dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords)); 246 for (p = 0; p < 6; ++p) PetscCall(DMSetLabelValue(dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1])); 247 } break; 248 case 1: { 249 PetscInt numPoints[2] = {5, 2}; 250 PetscInt coneSize[7] = {4, 3, 0, 0, 0, 0, 0}; 251 PetscInt cones[7] = {2, 3, 4, 5, 3, 6, 4}; 252 PetscInt coneOrientations[7] = {0, 0, 0, 0, 0, 0, 0}; 253 PetscScalar vertexCoords[10] = {-0.5, 0.0, 0.0, 0.0, 0.0, 1.0, -0.5, 1.0, 0.5, 0.0}; 254 PetscInt markerPoints[10] = {2, 1, 3, 1, 4, 1, 5, 1, 6, 1}; 255 256 PetscCall(DMPlexCreateFromDAG(dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords)); 257 for (p = 0; p < 5; ++p) PetscCall(DMSetLabelValue(dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1])); 258 } break; 259 default: 260 SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %" PetscInt_FMT, testNum); 261 } 262 } else { 263 PetscInt numPoints[2] = {0, 0}; 264 265 PetscCall(DMPlexCreateFromDAG(dm, depth, numPoints, NULL, NULL, NULL, NULL)); 266 PetscCall(DMCreateLabel(dm, "marker")); 267 } 268 PetscFunctionReturn(PETSC_SUCCESS); 269 } 270 271 PetscErrorCode CreateHex_3D(MPI_Comm comm, DM dm) 272 { 273 PetscInt depth = 1, testNum = 0, p; 274 PetscMPIInt rank; 275 276 PetscFunctionBegin; 277 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 278 if (rank == 0) { 279 switch (testNum) { 280 case 0: { 281 PetscInt numPoints[2] = {12, 2}; 282 PetscInt coneSize[14] = {8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 283 PetscInt cones[16] = {2, 5, 4, 3, 6, 7, 8, 9, 3, 4, 11, 10, 7, 12, 13, 8}; 284 PetscInt coneOrientations[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 285 PetscScalar vertexCoords[36] = {-0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.5, 1.0, 0.0, -0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, -0.5, 1.0, 1.0, 0.5, 0.0, 0.0, 0.5, 1.0, 0.0, 0.5, 0.0, 1.0, 0.5, 1.0, 1.0}; 286 PetscInt markerPoints[16] = {2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1}; 287 288 PetscCall(DMPlexCreateFromDAG(dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords)); 289 for (p = 0; p < 8; ++p) PetscCall(DMSetLabelValue(dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1])); 290 } break; 291 default: 292 SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %" PetscInt_FMT, testNum); 293 } 294 } else { 295 PetscInt numPoints[2] = {0, 0}; 296 297 PetscCall(DMPlexCreateFromDAG(dm, depth, numPoints, NULL, NULL, NULL, NULL)); 298 PetscCall(DMCreateLabel(dm, "marker")); 299 } 300 PetscFunctionReturn(PETSC_SUCCESS); 301 } 302 303 PetscErrorCode CreateMesh(MPI_Comm comm, PetscInt testNum, AppCtx *user, DM *dm) 304 { 305 PetscBool useGenerator = user->useGenerator; 306 307 PetscFunctionBegin; 308 PetscCall(DMCreate(comm, dm)); 309 PetscCall(DMSetType(*dm, DMPLEX)); 310 if (!useGenerator) { 311 PetscInt dim = user->dim; 312 PetscBool simplex = user->simplex; 313 314 PetscCall(DMSetDimension(*dm, dim)); 315 switch (dim) { 316 case 2: 317 if (simplex) { 318 PetscCall(CreateSimplex_2D(comm, *dm)); 319 } else { 320 PetscCall(CreateQuad_2D(comm, testNum, *dm)); 321 } 322 break; 323 case 3: 324 if (simplex) { 325 PetscCall(CreateSimplex_3D(comm, *dm)); 326 } else { 327 PetscCall(CreateHex_3D(comm, *dm)); 328 } 329 break; 330 default: 331 SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make meshes for dimension %" PetscInt_FMT, dim); 332 } 333 } 334 PetscCall(DMSetFromOptions(*dm)); 335 PetscCall(PetscObjectSetName((PetscObject)*dm, "Interpolated Mesh")); 336 PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view")); 337 PetscFunctionReturn(PETSC_SUCCESS); 338 } 339 340 int main(int argc, char **argv) 341 { 342 DM dm; 343 AppCtx user; /* user-defined work context */ 344 345 PetscFunctionBeginUser; 346 PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 347 PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user)); 348 PetscCall(CreateMesh(PETSC_COMM_WORLD, user.testNum, &user, &dm)); 349 PetscCall(DMDestroy(&dm)); 350 PetscCall(PetscFinalize()); 351 return 0; 352 } 353 354 /*TEST 355 testset: 356 args: -dm_plex_interpolate_pre -dm_plex_check_all 357 358 # Two cell test meshes 0-7 359 test: 360 suffix: 0 361 args: -dim 2 -dm_view ascii::ascii_info_detail 362 test: 363 suffix: 1 364 nsize: 2 365 args: -petscpartitioner_type simple -dim 2 -dm_view ascii::ascii_info_detail 366 test: 367 suffix: 2 368 args: -dim 2 -simplex 0 -dm_view ascii::ascii_info_detail 369 test: 370 suffix: 3 371 nsize: 2 372 args: -petscpartitioner_type simple -dim 2 -simplex 0 -dm_view ascii::ascii_info_detail 373 test: 374 suffix: 4 375 args: -dim 3 -dm_view ascii::ascii_info_detail 376 test: 377 suffix: 5 378 nsize: 2 379 args: -petscpartitioner_type simple -dim 3 -dm_view ascii::ascii_info_detail 380 test: 381 suffix: 6 382 args: -dim 3 -simplex 0 -dm_view ascii::ascii_info_detail 383 test: 384 suffix: 7 385 nsize: 2 386 args: -petscpartitioner_type simple -dim 3 -simplex 0 -dm_view ascii::ascii_info_detail 387 # 2D Hybrid Mesh 8 388 test: 389 suffix: 8 390 args: -dim 2 -simplex 0 -testnum 1 -dm_view ascii::ascii_info_detail 391 392 testset: 393 args: -dm_plex_check_all 394 395 # Reference cells 396 test: 397 suffix: 12 398 args: -use_generator -dm_plex_reference_cell_domain -dm_plex_cell pyramid -dm_plex_check_all 399 output_file: output/empty.out 400 # TetGen meshes 9-10 401 test: 402 suffix: 9 403 requires: triangle 404 args: -use_generator -dm_view ascii::ascii_info_detail -dm_coord_space 0 405 test: 406 suffix: 10 407 requires: ctetgen 408 args: -use_generator -dm_plex_dim 3 -dm_view ascii::ascii_info_detail -dm_coord_space 0 409 # Cubit meshes 11 410 test: 411 suffix: 11 412 requires: exodusii 413 args: -use_generator -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/blockcylinder-50.exo -dm_view ascii::ascii_info_detail -dm_coord_space 0 414 415 TEST*/ 416