1 static char help[] = "Mesh Orientation Tutorial\n\n"; 2 3 #include <petscdmplex.h> 4 #include <petscdmplextransform.h> 5 6 typedef struct { 7 PetscBool genArr; /* Generate all possible cell arrangements */ 8 PetscBool refArr; /* Refine all possible cell arrangements */ 9 PetscBool printTable; /* Print the CAyley table */ 10 PetscInt orntBounds[2]; /* Bounds for the orientation check */ 11 PetscInt numOrnt; /* Number of specific orientations specified, or -1 for all orientations */ 12 PetscInt ornts[48]; /* Specific orientations if specified */ 13 PetscInt initOrnt; /* Initial orientation for starting mesh */ 14 } AppCtx; 15 16 static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 17 { 18 PetscInt n = 2; 19 PetscBool flg; 20 PetscErrorCode ierr; 21 22 PetscFunctionBeginUser; 23 options->genArr = PETSC_FALSE; 24 options->refArr = PETSC_FALSE; 25 options->printTable = PETSC_FALSE; 26 options->orntBounds[0] = PETSC_MIN_INT; 27 options->orntBounds[1] = PETSC_MAX_INT; 28 options->numOrnt = -1; 29 options->initOrnt = 0; 30 31 ierr = PetscOptionsBegin(comm, "", "Mesh Orientation Tutorials Options", "DMPLEX");PetscCall(ierr); 32 PetscCall(PetscOptionsBool("-gen_arrangements", "Flag for generating all arrangements of the cell", "ex11.c", options->genArr, &options->genArr, NULL)); 33 PetscCall(PetscOptionsBool("-ref_arrangements", "Flag for refining all arrangements of the cell", "ex11.c", options->refArr, &options->refArr, NULL)); 34 PetscCall(PetscOptionsBool("-print_table", "Print the Cayley table", "ex11.c", options->printTable, &options->printTable, NULL)); 35 PetscCall(PetscOptionsIntArray("-ornt_bounds", "Bounds for orientation checks", "ex11.c", options->orntBounds, &n, NULL)); 36 n = 48; 37 PetscCall(PetscOptionsIntArray("-ornts", "Specific orientations for checks", "ex11.c", options->ornts, &n, &flg)); 38 if (flg) { 39 options->numOrnt = n; 40 PetscCall(PetscSortInt(n, options->ornts)); 41 } 42 PetscCall(PetscOptionsInt("-init_ornt", "Initial orientation for starting mesh", "ex11.c", options->initOrnt, &options->initOrnt, NULL)); 43 ierr = PetscOptionsEnd(); 44 PetscFunctionReturn(0); 45 } 46 47 static PetscBool ignoreOrnt(AppCtx *user, PetscInt o) 48 { 49 PetscInt loc; 50 PetscErrorCode ierr; 51 52 if (user->numOrnt < 0) return PETSC_FALSE; 53 ierr = PetscFindInt(o, user->numOrnt, user->ornts, &loc); 54 if (loc < 0 || ierr) return PETSC_TRUE; 55 return PETSC_FALSE; 56 } 57 58 static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) 59 { 60 PetscFunctionBeginUser; 61 PetscCall(DMCreate(comm, dm)); 62 PetscCall(DMSetType(*dm, DMPLEX)); 63 PetscCall(DMSetFromOptions(*dm)); 64 PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view")); 65 PetscFunctionReturn(0); 66 } 67 68 static PetscErrorCode CheckCellVertices(DM dm, PetscInt cell, PetscInt o) 69 { 70 DMPolytopeType ct; 71 const PetscInt *arrVerts; 72 PetscInt *closure = NULL; 73 PetscInt Ncl, cl, Nv, vStart, vEnd, v; 74 MPI_Comm comm; 75 76 PetscFunctionBeginUser; 77 PetscCall(PetscObjectGetComm((PetscObject) dm, &comm)); 78 PetscCall(DMPlexGetCellType(dm, cell, &ct)); 79 PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd)); 80 PetscCall(DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &Ncl, &closure)); 81 for (cl = 0, Nv = 0; cl < Ncl*2; cl += 2) { 82 const PetscInt vertex = closure[cl]; 83 84 if (vertex < vStart || vertex >= vEnd) continue; 85 closure[Nv++] = vertex; 86 } 87 PetscCheck(Nv == DMPolytopeTypeGetNumVertices(ct),comm, PETSC_ERR_ARG_WRONG, "Cell %D has %D vertices != %D vertices in a %s", cell, Nv, DMPolytopeTypeGetNumVertices(ct), DMPolytopeTypes[ct]); 88 arrVerts = DMPolytopeTypeGetVertexArrangment(ct, o); 89 for (v = 0; v < Nv; ++v) { 90 PetscCheck(closure[v] == arrVerts[v]+vStart,comm, PETSC_ERR_ARG_WRONG, "Cell %D vertex[%D]: %D should be %D for arrangement %D", cell, v, closure[v], arrVerts[v]+vStart, o); 91 } 92 PetscCall(DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &Ncl, &closure)); 93 PetscFunctionReturn(0); 94 } 95 96 /* Transform cell with group operation o */ 97 static PetscErrorCode ReorientCell(DM dm, PetscInt cell, PetscInt o, PetscBool swapCoords) 98 { 99 DM cdm; 100 Vec coordinates; 101 PetscScalar *coords, *ccoords = NULL; 102 PetscInt *closure = NULL; 103 PetscInt cdim, d, Nc, Ncl, cl, vStart, vEnd, Nv; 104 105 PetscFunctionBegin; 106 /* Change vertex coordinates so that it plots as we expect */ 107 PetscCall(DMGetCoordinateDM(dm, &cdm)); 108 PetscCall(DMGetCoordinateDim(dm, &cdim)); 109 PetscCall(DMGetCoordinatesLocal(dm, &coordinates)); 110 PetscCall(DMPlexVecGetClosure(cdm, NULL, coordinates, cell, &Nc, &ccoords)); 111 /* Reorient cone */ 112 PetscCall(DMPlexOrientPoint(dm, cell, o)); 113 /* Finish resetting coordinates */ 114 if (swapCoords) { 115 PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd)); 116 PetscCall(VecGetArrayWrite(coordinates, &coords)); 117 PetscCall(DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &Ncl, &closure)); 118 for (cl = 0, Nv = 0; cl < Ncl*2; cl += 2) { 119 const PetscInt vertex = closure[cl]; 120 PetscScalar *vcoords; 121 122 if (vertex < vStart || vertex >= vEnd) continue; 123 PetscCall(DMPlexPointLocalRef(cdm, vertex, coords, &vcoords)); 124 for (d = 0; d < cdim; ++d) vcoords[d] = ccoords[Nv*cdim + d]; 125 ++Nv; 126 } 127 PetscCall(DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &Ncl, &closure)); 128 PetscCall(VecRestoreArrayWrite(coordinates, &coords)); 129 } 130 PetscCall(DMPlexVecRestoreClosure(cdm, NULL, coordinates, cell, &Nc, &ccoords)); 131 PetscFunctionReturn(0); 132 } 133 134 static PetscErrorCode GenerateArrangments(DM dm, AppCtx *user) 135 { 136 DM odm; 137 DMPolytopeType ct; 138 PetscInt No, o; 139 const char *name; 140 141 PetscFunctionBeginUser; 142 if (!user->genArr) PetscFunctionReturn(0); 143 PetscCall(PetscObjectGetName((PetscObject) dm, &name)); 144 PetscCall(DMPlexGetCellType(dm, 0, &ct)); 145 No = DMPolytopeTypeGetNumArrangments(ct)/2; 146 for (o = PetscMax(-No, user->orntBounds[0]); o < PetscMin(No, user->orntBounds[1]); ++o) { 147 if (ignoreOrnt(user, o)) continue; 148 PetscCall(CreateMesh(PetscObjectComm((PetscObject) dm), user, &odm)); 149 PetscCall(ReorientCell(odm, 0, o, PETSC_TRUE)); 150 PetscCall(PetscPrintf(PetscObjectComm((PetscObject) dm), "%s orientation %D\n", name, o)); 151 PetscCall(DMViewFromOptions(odm, NULL, "-gen_dm_view")); 152 PetscCall(CheckCellVertices(odm, 0, o)); 153 PetscCall(DMDestroy(&odm)); 154 } 155 PetscFunctionReturn(0); 156 } 157 158 static PetscErrorCode VerifyCayleyTable(DM dm, AppCtx *user) 159 { 160 DM dm1, dm2; 161 DMPolytopeType ct; 162 const PetscInt *refcone, *cone; 163 PetscInt No, o1, o2, o3, o4; 164 PetscBool equal; 165 const char *name; 166 167 PetscFunctionBeginUser; 168 if (!user->genArr) PetscFunctionReturn(0); 169 PetscCall(PetscObjectGetName((PetscObject) dm, &name)); 170 PetscCall(DMPlexGetCellType(dm, 0, &ct)); 171 PetscCall(DMPlexGetCone(dm, 0, &refcone)); 172 No = DMPolytopeTypeGetNumArrangments(ct)/2; 173 if (user->printTable) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cayley Table for %s\n", DMPolytopeTypes[ct])); 174 for (o1 = PetscMax(-No, user->orntBounds[0]); o1 < PetscMin(No, user->orntBounds[1]); ++o1) { 175 for (o2 = PetscMax(-No, user->orntBounds[0]); o2 < PetscMin(No, user->orntBounds[1]); ++o2) { 176 PetscCall(CreateMesh(PetscObjectComm((PetscObject) dm), user, &dm1)); 177 PetscCall(DMPlexOrientPoint(dm1, 0, o2)); 178 PetscCall(DMPlexCheckFaces(dm1, 0)); 179 PetscCall(DMPlexOrientPoint(dm1, 0, o1)); 180 PetscCall(DMPlexCheckFaces(dm1, 0)); 181 o3 = DMPolytopeTypeComposeOrientation(ct, o1, o2); 182 /* First verification */ 183 PetscCall(CreateMesh(PetscObjectComm((PetscObject) dm), user, &dm2)); 184 PetscCall(DMPlexOrientPoint(dm2, 0, o3)); 185 PetscCall(DMPlexCheckFaces(dm2, 0)); 186 PetscCall(DMPlexEqual(dm1, dm2, &equal)); 187 if (!equal) { 188 PetscCall(DMViewFromOptions(dm1, NULL, "-error_dm_view")); 189 PetscCall(DMViewFromOptions(dm2, NULL, "-error_dm_view")); 190 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Cayley table error for %s: %D * %D != %D", DMPolytopeTypes[ct], o1, o2, o3); 191 } 192 /* Second verification */ 193 PetscCall(DMPlexGetCone(dm1, 0, &cone)); 194 PetscCall(DMPolytopeGetOrientation(ct, refcone, cone, &o4)); 195 if (user->printTable) PetscCall(PetscPrintf(PETSC_COMM_SELF, "%D, ", o4)); 196 PetscCheck(o3 == o4,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Cayley table error for %s: %D * %D = %D != %D", DMPolytopeTypes[ct], o1, o2, o3, o4); 197 PetscCall(DMDestroy(&dm1)); 198 PetscCall(DMDestroy(&dm2)); 199 } 200 if (user->printTable) PetscCall(PetscPrintf(PETSC_COMM_SELF, "\n")); 201 } 202 PetscFunctionReturn(0); 203 } 204 205 static PetscErrorCode VerifyInverse(DM dm, AppCtx *user) 206 { 207 DM dm1, dm2; 208 DMPolytopeType ct; 209 const PetscInt *refcone, *cone; 210 PetscInt No, o, oi, o2; 211 PetscBool equal; 212 const char *name; 213 214 PetscFunctionBeginUser; 215 if (!user->genArr) PetscFunctionReturn(0); 216 PetscCall(PetscObjectGetName((PetscObject) dm, &name)); 217 PetscCall(DMPlexGetCellType(dm, 0, &ct)); 218 PetscCall(DMPlexGetCone(dm, 0, &refcone)); 219 No = DMPolytopeTypeGetNumArrangments(ct)/2; 220 if (user->printTable) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Inverse table for %s\n", DMPolytopeTypes[ct])); 221 for (o = PetscMax(-No, user->orntBounds[0]); o < PetscMin(No, user->orntBounds[1]); ++o) { 222 if (ignoreOrnt(user, o)) continue; 223 oi = DMPolytopeTypeComposeOrientationInv(ct, 0, o); 224 PetscCall(CreateMesh(PetscObjectComm((PetscObject) dm), user, &dm1)); 225 PetscCall(DMPlexOrientPoint(dm1, 0, o)); 226 PetscCall(DMPlexCheckFaces(dm1, 0)); 227 PetscCall(DMPlexOrientPoint(dm1, 0, oi)); 228 PetscCall(DMPlexCheckFaces(dm1, 0)); 229 /* First verification */ 230 PetscCall(CreateMesh(PetscObjectComm((PetscObject) dm), user, &dm2)); 231 PetscCall(DMPlexEqual(dm1, dm2, &equal)); 232 if (!equal) { 233 PetscCall(DMViewFromOptions(dm1, NULL, "-error_dm_view")); 234 PetscCall(DMViewFromOptions(dm2, NULL, "-error_dm_view")); 235 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inverse error for %s: %D * %D != 0", DMPolytopeTypes[ct], o, oi); 236 } 237 /* Second verification */ 238 PetscCall(DMPlexGetCone(dm1, 0, &cone)); 239 PetscCall(DMPolytopeGetOrientation(ct, refcone, cone, &o2)); 240 if (user->printTable) PetscCall(PetscPrintf(PETSC_COMM_SELF, "%D, ", oi)); 241 PetscCheck(o2 == 0,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inverse error for %s: %D * %D = %D != 0", DMPolytopeTypes[ct], o, oi, o2); 242 PetscCall(DMDestroy(&dm1)); 243 PetscCall(DMDestroy(&dm2)); 244 } 245 if (user->printTable) PetscCall(PetscPrintf(PETSC_COMM_SELF, "\n")); 246 PetscFunctionReturn(0); 247 } 248 249 /* Suppose that point p has the same arrangement as o from canonical, compare the subcells to canonical subcells */ 250 static PetscErrorCode CheckSubcells(DM dm, DM odm, PetscInt p, PetscInt o, AppCtx *user) 251 { 252 DMPlexTransform tr, otr; 253 DMPolytopeType ct; 254 DMPolytopeType *rct; 255 const PetscInt *cone, *ornt, *ocone, *oornt; 256 PetscInt *rsize, *rcone, *rornt; 257 PetscInt Nct, n, oi, debug = 0; 258 259 PetscFunctionBeginUser; 260 PetscCall(DMPlexTransformCreate(PetscObjectComm((PetscObject) dm), &tr)); 261 PetscCall(DMPlexTransformSetDM(tr, dm)); 262 PetscCall(DMPlexTransformSetFromOptions(tr)); 263 PetscCall(DMPlexTransformSetUp(tr)); 264 265 PetscCall(DMPlexTransformCreate(PetscObjectComm((PetscObject) odm), &otr)); 266 PetscCall(DMPlexTransformSetDM(otr, odm)); 267 PetscCall(DMPlexTransformSetFromOptions(otr)); 268 PetscCall(DMPlexTransformSetUp(otr)); 269 270 PetscCall(DMPlexGetCellType(dm, p, &ct)); 271 PetscCall(DMPlexGetCone(dm, p, &cone)); 272 PetscCall(DMPlexGetConeOrientation(dm, p, &ornt)); 273 PetscCall(DMPlexGetCone(odm, p, &ocone)); 274 PetscCall(DMPlexGetConeOrientation(odm, p, &oornt)); 275 oi = DMPolytopeTypeComposeOrientationInv(ct, 0, o); 276 if (user->printTable) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Orientation %D\n", oi)); 277 278 PetscCall(DMPlexTransformCellTransform(tr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt)); 279 for (n = 0; n < Nct; ++n) { 280 DMPolytopeType ctNew = rct[n]; 281 PetscInt r, ro; 282 283 if (debug) PetscCall(PetscPrintf(PETSC_COMM_SELF, " Checking type %s\n", DMPolytopeTypes[ctNew])); 284 for (r = 0; r < rsize[n]; ++r) { 285 const PetscInt *qcone, *qornt, *oqcone, *oqornt; 286 PetscInt pNew, opNew, oo, pr, fo; 287 PetscBool restore = PETSC_TRUE; 288 289 PetscCall(DMPlexTransformGetTargetPoint(tr, ct, ctNew, p, r, &pNew)); 290 PetscCall(DMPlexTransformGetCone(tr, pNew, &qcone, &qornt)); 291 if (debug) { 292 PetscInt c; 293 294 PetscCall(PetscPrintf(PETSC_COMM_SELF, " Checking replica %D (%D)\n Original Cone", r, pNew)); 295 for (c = 0; c < DMPolytopeTypeGetConeSize(ctNew); ++c) PetscCall(PetscPrintf(PETSC_COMM_SELF, " %D (%D)", qcone[c], qornt[c])); 296 PetscCall(PetscPrintf(PETSC_COMM_SELF, "\n")); 297 } 298 for (ro = 0; ro < rsize[n]; ++ro) { 299 PetscBool found; 300 301 PetscCall(DMPlexTransformGetTargetPoint(otr, ct, ctNew, p, ro, &opNew)); 302 PetscCall(DMPlexTransformGetConeOriented(otr, opNew, o, &oqcone, &oqornt)); 303 PetscCall(DMPolytopeMatchOrientation(ctNew, oqcone, qcone, &oo, &found)); 304 if (found) break; 305 PetscCall(DMPlexTransformRestoreCone(otr, pNew, &oqcone, &oqornt)); 306 } 307 if (debug) { 308 PetscInt c; 309 310 PetscCall(PetscPrintf(PETSC_COMM_SELF, " Checking transform replica %D (%D) (%D)\n Transform Cone", ro, opNew, o)); 311 for (c = 0; c < DMPolytopeTypeGetConeSize(ctNew); ++c) PetscCall(PetscPrintf(PETSC_COMM_SELF, " %D (%D)", oqcone[c], oqornt[c])); 312 PetscCall(PetscPrintf(PETSC_COMM_SELF, "\n")); 313 PetscCall(PetscPrintf(PETSC_COMM_SELF, " Matched %D\n", oo)); 314 } 315 if (ro == rsize[n]) { 316 /* The tetrahedron has 3 pairs of opposing edges, and any pair can be connected by the interior segment */ 317 if (ct == DM_POLYTOPE_TETRAHEDRON) { 318 /* The segment in a tetrahedron does not map into itself under the group action */ 319 if (ctNew == DM_POLYTOPE_SEGMENT) {restore = PETSC_FALSE; ro = r; oo = 0;} 320 /* The last four interior faces do not map into themselves under the group action */ 321 if (r > 3 && ctNew == DM_POLYTOPE_TRIANGLE) {restore = PETSC_FALSE; ro = r; oo = 0;} 322 /* The last four interior faces do not map into themselves under the group action */ 323 if (r > 3 && ctNew == DM_POLYTOPE_TETRAHEDRON) {restore = PETSC_FALSE; ro = r; oo = 0;} 324 } 325 PetscCheck(!restore,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unable to find matching %s %D orientation for cell orientation %D", DMPolytopeTypes[ctNew], r, o); 326 } 327 if (user->printTable) PetscCall(PetscPrintf(PETSC_COMM_SELF, "%D, %D, ", ro, oo)); 328 PetscCall(DMPlexTransformGetSubcellOrientation(tr, ct, p, oi, ctNew, r, 0, &pr, &fo)); 329 if (!user->printTable) { 330 PetscCheck(pr == ro,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Choose wrong replica %D != %D", pr, ro); 331 PetscCheck(fo == oo,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Choose wrong orientation %D != %D", fo, oo); 332 } 333 PetscCall(DMPlexTransformRestoreCone(tr, pNew, &qcone, &qornt)); 334 if (restore) PetscCall(DMPlexTransformRestoreCone(otr, pNew, &oqcone, &oqornt)); 335 } 336 if (user->printTable) PetscCall(PetscPrintf(PETSC_COMM_SELF, "\n")); 337 } 338 PetscCall(DMPlexTransformDestroy(&tr)); 339 PetscCall(DMPlexTransformDestroy(&otr)); 340 PetscFunctionReturn(0); 341 } 342 343 static PetscErrorCode RefineArrangments(DM dm, AppCtx *user) 344 { 345 DM odm, rdm; 346 DMPolytopeType ct; 347 PetscInt No, o; 348 const char *name; 349 350 PetscFunctionBeginUser; 351 if (!user->refArr) PetscFunctionReturn(0); 352 PetscCall(PetscObjectGetName((PetscObject) dm, &name)); 353 PetscCall(DMPlexGetCellType(dm, 0, &ct)); 354 No = DMPolytopeTypeGetNumArrangments(ct)/2; 355 for (o = PetscMax(-No, user->orntBounds[0]); o < PetscMin(No, user->orntBounds[1]); ++o) { 356 if (ignoreOrnt(user, o)) continue; 357 PetscCall(CreateMesh(PetscObjectComm((PetscObject) dm), user, &odm)); 358 if (user->initOrnt) PetscCall(ReorientCell(odm, 0, user->initOrnt, PETSC_FALSE)); 359 PetscCall(ReorientCell(odm, 0, o, PETSC_TRUE)); 360 PetscCall(DMViewFromOptions(odm, NULL, "-orig_dm_view")); 361 PetscCall(DMRefine(odm, MPI_COMM_NULL, &rdm)); 362 PetscCall(DMSetFromOptions(rdm)); 363 PetscCall(PetscPrintf(PetscObjectComm((PetscObject) dm), "%s orientation %D\n", name, o)); 364 PetscCall(DMViewFromOptions(rdm, NULL, "-ref_dm_view")); 365 PetscCall(CheckSubcells(dm, odm, 0, o, user)); 366 PetscCall(DMDestroy(&odm)); 367 PetscCall(DMDestroy(&rdm)); 368 } 369 PetscFunctionReturn(0); 370 } 371 372 int main(int argc, char **argv) 373 { 374 DM dm; 375 AppCtx user; 376 377 PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 378 PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user)); 379 PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &dm)); 380 if (user.initOrnt) { 381 PetscCall(ReorientCell(dm, 0, user.initOrnt, PETSC_FALSE)); 382 PetscCall(DMViewFromOptions(dm, NULL, "-ornt_dm_view")); 383 } 384 PetscCall(GenerateArrangments(dm, &user)); 385 PetscCall(VerifyCayleyTable(dm, &user)); 386 PetscCall(VerifyInverse(dm, &user)); 387 PetscCall(RefineArrangments(dm, &user)); 388 PetscCall(DMDestroy(&dm)); 389 PetscCall(PetscFinalize()); 390 return 0; 391 } 392 393 /*TEST 394 395 testset: 396 args: -dm_coord_space 0 -dm_plex_reference_cell_domain -gen_arrangements \ 397 -gen_dm_view ::ascii_latex -dm_plex_view_tikzscale 0.5 398 399 test: 400 suffix: segment 401 args: -dm_plex_cell segment \ 402 -dm_plex_view_numbers_depth 1,0 -dm_plex_view_colors_depth 1,0 403 404 test: 405 suffix: triangle 406 args: -dm_plex_cell triangle \ 407 -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 408 409 test: 410 suffix: quadrilateral 411 args: -dm_plex_cell quadrilateral \ 412 -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 413 414 test: 415 suffix: tensor_segment 416 args: -dm_plex_cell tensor_quad \ 417 -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 418 419 test: 420 suffix: tetrahedron 421 args: -dm_plex_cell tetrahedron \ 422 -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 423 424 test: 425 suffix: hexahedron 426 args: -dm_plex_cell hexahedron \ 427 -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 -dm_plex_view_tikzscale 0.3 428 429 test: 430 suffix: triangular_prism 431 args: -dm_plex_cell triangular_prism \ 432 -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 433 434 test: 435 suffix: tensor_triangular_prism 436 args: -dm_plex_cell tensor_triangular_prism \ 437 -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 438 439 test: 440 suffix: tensor_quadrilateral_prism 441 args: -dm_plex_cell tensor_quadrilateral_prism \ 442 -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 443 444 test: 445 suffix: pyramid 446 args: -dm_plex_cell pyramid \ 447 -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 448 449 testset: 450 args: -dm_coord_space 0 -dm_plex_reference_cell_domain -ref_arrangements -dm_plex_check_all \ 451 -ref_dm_view ::ascii_latex -dm_plex_view_tikzscale 1.0 452 453 test: 454 suffix: ref_segment 455 args: -dm_plex_cell segment \ 456 -dm_plex_view_numbers_depth 1,0 -dm_plex_view_colors_depth 1,0 457 458 test: 459 suffix: ref_triangle 460 args: -dm_plex_cell triangle \ 461 -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 462 463 test: 464 suffix: ref_quadrilateral 465 args: -dm_plex_cell quadrilateral \ 466 -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 467 468 test: 469 suffix: ref_tensor_segment 470 args: -dm_plex_cell tensor_quad \ 471 -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 472 473 test: 474 suffix: ref_tetrahedron 475 args: -dm_plex_cell tetrahedron \ 476 -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 477 478 test: 479 suffix: ref_hexahedron 480 args: -dm_plex_cell hexahedron \ 481 -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 482 483 test: 484 suffix: ref_triangular_prism 485 args: -dm_plex_cell triangular_prism \ 486 -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 487 488 test: 489 suffix: ref_tensor_triangular_prism 490 args: -dm_plex_cell tensor_triangular_prism \ 491 -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 492 493 test: 494 suffix: ref_tensor_quadrilateral_prism 495 args: -dm_plex_cell tensor_quadrilateral_prism \ 496 -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 497 498 # ToBox should recreate the coordinate space since the cell shape changes 499 testset: 500 args: -dm_coord_space 0 -dm_plex_transform_type refine_tobox -ref_arrangements -dm_plex_check_all 501 502 test: 503 suffix: tobox_triangle 504 args: -dm_plex_reference_cell_domain -dm_plex_cell triangle \ 505 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 -dm_plex_view_tikzscale 1.0 506 507 test: 508 suffix: tobox_tensor_segment 509 args: -dm_plex_reference_cell_domain -dm_plex_cell tensor_quad \ 510 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 -dm_plex_view_tikzscale 1.0 511 512 test: 513 suffix: tobox_tetrahedron 514 args: -dm_plex_reference_cell_domain -dm_plex_cell tetrahedron \ 515 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 -dm_plex_view_tikzscale 1.0 516 517 test: 518 suffix: tobox_triangular_prism 519 args: -dm_plex_reference_cell_domain -dm_plex_cell triangular_prism \ 520 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 -dm_plex_view_tikzscale 1.0 521 522 test: 523 suffix: tobox_tensor_triangular_prism 524 args: -dm_plex_reference_cell_domain -dm_plex_cell tensor_triangular_prism \ 525 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 -dm_plex_view_tikzscale 1.0 526 527 test: 528 suffix: tobox_tensor_quadrilateral_prism 529 args: -dm_plex_reference_cell_domain -dm_plex_cell tensor_quadrilateral_prism \ 530 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 -dm_plex_view_tikzscale 1.0 531 532 testset: 533 args: -dm_coord_space 0 -dm_plex_transform_type refine_alfeld -ref_arrangements -dm_plex_check_all 534 535 test: 536 suffix: alfeld_triangle 537 args: -dm_plex_reference_cell_domain -dm_plex_cell triangle \ 538 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 -dm_plex_view_tikzscale 1.0 539 540 test: 541 suffix: alfeld_tetrahedron 542 args: -dm_plex_reference_cell_domain -dm_plex_cell tetrahedron \ 543 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 -dm_plex_view_tikzscale 1.0 544 545 testset: 546 args: -dm_plex_transform_type refine_sbr -ref_arrangements -dm_plex_check_all 547 548 # This splits edge 1 of the triangle, and reflects about the added edge 549 test: 550 suffix: sbr_triangle_0 551 args: -dm_plex_reference_cell_domain -dm_plex_cell triangle -dm_plex_transform_sbr_ref_cell 5 -ornts -2,0 \ 552 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 -dm_plex_view_tikzscale 1.0 553 554 # This splits edge 0 of the triangle, and reflects about the added edge 555 test: 556 suffix: sbr_triangle_1 557 args: -dm_plex_reference_cell_domain -dm_plex_cell triangle -dm_plex_transform_sbr_ref_cell 5 -init_ornt 1 -ornts -3,0 \ 558 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 -dm_plex_view_tikzscale 1.0 559 560 # This splits edge 2 of the triangle, and reflects about the added edge 561 test: 562 suffix: sbr_triangle_2 563 args: -dm_plex_reference_cell_domain -dm_plex_cell triangle -dm_plex_transform_sbr_ref_cell 5 -init_ornt 2 -ornts -1,0 \ 564 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 -dm_plex_view_tikzscale 1.0 565 566 # This splits edges 1 and 2 of the triangle 567 test: 568 suffix: sbr_triangle_3 569 args: -dm_plex_reference_cell_domain -dm_plex_cell triangle -dm_plex_transform_sbr_ref_cell 5,6 -ornts 0 \ 570 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 -dm_plex_view_tikzscale 1.0 571 572 # This splits edges 1 and 0 of the triangle 573 test: 574 suffix: sbr_triangle_4 575 args: -dm_plex_reference_cell_domain -dm_plex_cell triangle -dm_plex_transform_sbr_ref_cell 4,5 -ornts 0 \ 576 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 -dm_plex_view_tikzscale 1.0 577 578 # This splits edges 0 and 1 of the triangle 579 test: 580 suffix: sbr_triangle_5 581 args: -dm_plex_reference_cell_domain -dm_plex_cell triangle -dm_plex_transform_sbr_ref_cell 5,6 -init_ornt 1 -ornts 0 \ 582 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 -dm_plex_view_tikzscale 1.0 583 584 # This splits edges 0 and 2 of the triangle 585 test: 586 suffix: sbr_triangle_6 587 args: -dm_plex_reference_cell_domain -dm_plex_cell triangle -dm_plex_transform_sbr_ref_cell 4,5 -init_ornt 1 -ornts 0 \ 588 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 -dm_plex_view_tikzscale 1.0 589 590 # This splits edges 2 and 0 of the triangle 591 test: 592 suffix: sbr_triangle_7 593 args: -dm_plex_reference_cell_domain -dm_plex_cell triangle -dm_plex_transform_sbr_ref_cell 5,6 -init_ornt 2 -ornts 0 \ 594 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 -dm_plex_view_tikzscale 1.0 595 596 # This splits edges 2 and 1 of the triangle 597 test: 598 suffix: sbr_triangle_8 599 args: -dm_plex_reference_cell_domain -dm_plex_cell triangle -dm_plex_transform_sbr_ref_cell 4,5 -init_ornt 2 -ornts 0 \ 600 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 -dm_plex_view_tikzscale 1.0 601 602 testset: 603 args: -dm_plex_transform_type refine_boundary_layer -dm_plex_transform_bl_splits 2 -ref_arrangements -dm_plex_check_all 604 605 test: 606 suffix: bl_tensor_segment 607 args: -dm_plex_reference_cell_domain -dm_plex_cell tensor_quad \ 608 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,1,0 -dm_plex_view_colors_depth 1,1,0 -dm_plex_view_tikzscale 1.0 609 610 # The subcell check is broken because at orientation 3, the internal triangles do not get properly permuted for the check 611 test: 612 suffix: bl_tensor_triangular_prism 613 requires: TODO 614 args: -dm_plex_reference_cell_domain -dm_plex_cell tensor_triangular_prism \ 615 -ref_dm_view ::ascii_latex -dm_plex_view_numbers_depth 1,0,0,0 -dm_plex_view_colors_depth 1,0,0,0 -dm_plex_view_tikzscale 1.0 616 617 TEST*/ 618