1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2412e9a14SMatthew G. Knepley #include <petsc/private/petscfeimpl.h> /* For PetscFEInterpolate_Static() */ 375d3a19aSMatthew G. Knepley #include <petscsf.h> 475d3a19aSMatthew G. Knepley 5*cf4091a3SMatthew G. Knepley const char * const DMPlexCellRefinerTypes[] = {"Regular", "ToBox", "ToSimplex", "Alfeld2D", "Alfeld3D", "PowellSabin", "BoundaryLayer", "DMPlexCellRefinerTypes", "DM_REFINER_", 0}; 675d3a19aSMatthew G. Knepley 709789c4cSMatthew G. Knepley /* 809789c4cSMatthew G. Knepley Note that j and invj are non-square: 909789c4cSMatthew G. Knepley v0 + j x_face = x_cell 1009789c4cSMatthew G. Knepley invj (x_cell - v0) = x_face 1109789c4cSMatthew G. Knepley */ 12412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[]) 1309789c4cSMatthew G. Knepley { 1409789c4cSMatthew G. Knepley /* 1509789c4cSMatthew G. Knepley 2 1609789c4cSMatthew G. Knepley |\ 1709789c4cSMatthew G. Knepley | \ 1809789c4cSMatthew G. Knepley | \ 1909789c4cSMatthew G. Knepley | \ 2009789c4cSMatthew G. Knepley | \ 2109789c4cSMatthew G. Knepley | \ 2209789c4cSMatthew G. Knepley | \ 2309789c4cSMatthew G. Knepley 2 1 2409789c4cSMatthew G. Knepley | \ 2509789c4cSMatthew G. Knepley | \ 2609789c4cSMatthew G. Knepley | \ 2709789c4cSMatthew G. Knepley 0---0-------1 28412e9a14SMatthew G. Knepley v0[Nf][dc]: 3 x 2 29412e9a14SMatthew G. Knepley J[Nf][df][dc]: 3 x 1 x 2 30412e9a14SMatthew G. Knepley invJ[Nf][dc][df]: 3 x 2 x 1 31412e9a14SMatthew G. Knepley detJ[Nf]: 3 3209789c4cSMatthew G. Knepley */ 33412e9a14SMatthew G. Knepley static PetscReal tri_v0[] = {0.0, -1.0, 0.0, 0.0, -1.0, 0.0}; 34412e9a14SMatthew G. Knepley static PetscReal tri_J[] = {1.0, 0.0, -1.0, 1.0, 0.0, -1.0}; 35412e9a14SMatthew G. Knepley static PetscReal tri_invJ[] = {1.0, 0.0, -0.5, 0.5, 0.0, -1.0}; 36412e9a14SMatthew G. Knepley static PetscReal tri_detJ[] = {1.0, 1.414213562373095, 1.0}; 3709789c4cSMatthew G. Knepley /* 3809789c4cSMatthew G. Knepley 3---------2---------2 3909789c4cSMatthew G. Knepley | | 4009789c4cSMatthew G. Knepley | | 4109789c4cSMatthew G. Knepley | | 4209789c4cSMatthew G. Knepley 3 1 4309789c4cSMatthew G. Knepley | | 4409789c4cSMatthew G. Knepley | | 4509789c4cSMatthew G. Knepley | | 4609789c4cSMatthew G. Knepley 0---------0---------1 47412e9a14SMatthew G. Knepley 48412e9a14SMatthew G. Knepley v0[Nf][dc]: 4 x 2 49412e9a14SMatthew G. Knepley J[Nf][df][dc]: 4 x 1 x 2 50412e9a14SMatthew G. Knepley invJ[Nf][dc][df]: 4 x 2 x 1 51412e9a14SMatthew G. Knepley detJ[Nf]: 4 5209789c4cSMatthew G. Knepley */ 53412e9a14SMatthew G. Knepley static PetscReal quad_v0[] = {0.0, -1.0, 1.0, 0.0, 0.0, 1.0 -1.0, 0.0}; 54412e9a14SMatthew G. Knepley static PetscReal quad_J[] = {1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, -1.0}; 55412e9a14SMatthew G. Knepley static PetscReal quad_invJ[] = {1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, -1.0}; 56412e9a14SMatthew G. Knepley static PetscReal quad_detJ[] = {1.0, 1.0, 1.0, 1.0}; 57412e9a14SMatthew G. Knepley 58412e9a14SMatthew G. Knepley PetscFunctionBegin; 59412e9a14SMatthew G. Knepley switch (ct) { 60412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: if (Nf) *Nf = 3; if (v0) *v0 = tri_v0; if (J) *J = tri_J; if (invJ) *invJ = tri_invJ; if (detJ) *detJ = tri_detJ; break; 61412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: if (Nf) *Nf = 4; if (v0) *v0 = quad_v0; if (J) *J = quad_J; if (invJ) *invJ = quad_invJ; if (detJ) *detJ = quad_detJ; break; 6209789c4cSMatthew G. Knepley default: 63412e9a14SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 6409789c4cSMatthew G. Knepley } 6509789c4cSMatthew G. Knepley PetscFunctionReturn(0); 6609789c4cSMatthew G. Knepley } 6709789c4cSMatthew G. Knepley 68bed052eaSMatthew G. Knepley /* Gets the affine map from the original cell to each subcell */ 69412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetAffineTransforms_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[]) 70bed052eaSMatthew G. Knepley { 71260b6d3fSMatthew G. Knepley /* 72260b6d3fSMatthew G. Knepley 2 73260b6d3fSMatthew G. Knepley |\ 74260b6d3fSMatthew G. Knepley | \ 75260b6d3fSMatthew G. Knepley | \ 76260b6d3fSMatthew G. Knepley | \ 77260b6d3fSMatthew G. Knepley | C \ 78260b6d3fSMatthew G. Knepley | \ 79260b6d3fSMatthew G. Knepley | \ 80260b6d3fSMatthew G. Knepley 2---1---1 81260b6d3fSMatthew G. Knepley |\ D / \ 82260b6d3fSMatthew G. Knepley | 2 0 \ 83260b6d3fSMatthew G. Knepley |A \ / B \ 84260b6d3fSMatthew G. Knepley 0---0-------1 85260b6d3fSMatthew G. Knepley */ 86412e9a14SMatthew G. Knepley static PetscReal tri_v0[] = {-1.0, -1.0, 0.0, -1.0, -1.0, 0.0, 0.0, -1.0}; 87412e9a14SMatthew G. Knepley static PetscReal tri_J[] = {0.5, 0.0, 88412e9a14SMatthew G. Knepley 0.0, 0.5, 89412e9a14SMatthew G. Knepley 90412e9a14SMatthew G. Knepley 0.5, 0.0, 91412e9a14SMatthew G. Knepley 0.0, 0.5, 92412e9a14SMatthew G. Knepley 93412e9a14SMatthew G. Knepley 0.5, 0.0, 94412e9a14SMatthew G. Knepley 0.0, 0.5, 95412e9a14SMatthew G. Knepley 96412e9a14SMatthew G. Knepley 0.0, -0.5, 97412e9a14SMatthew G. Knepley 0.5, 0.5}; 98412e9a14SMatthew G. Knepley static PetscReal tri_invJ[] = {2.0, 0.0, 99412e9a14SMatthew G. Knepley 0.0, 2.0, 100412e9a14SMatthew G. Knepley 101412e9a14SMatthew G. Knepley 2.0, 0.0, 102412e9a14SMatthew G. Knepley 0.0, 2.0, 103412e9a14SMatthew G. Knepley 104412e9a14SMatthew G. Knepley 2.0, 0.0, 105412e9a14SMatthew G. Knepley 0.0, 2.0, 106412e9a14SMatthew G. Knepley 107412e9a14SMatthew G. Knepley 2.0, 2.0, 108412e9a14SMatthew G. Knepley -2.0, 0.0}; 109260b6d3fSMatthew G. Knepley /* 110260b6d3fSMatthew G. Knepley 3---------2---------2 111260b6d3fSMatthew G. Knepley | | | 112260b6d3fSMatthew G. Knepley | D 2 C | 113260b6d3fSMatthew G. Knepley | | | 114260b6d3fSMatthew G. Knepley 3----3----0----1----1 115260b6d3fSMatthew G. Knepley | | | 116260b6d3fSMatthew G. Knepley | A 0 B | 117260b6d3fSMatthew G. Knepley | | | 118260b6d3fSMatthew G. Knepley 0---------0---------1 119260b6d3fSMatthew G. Knepley */ 120412e9a14SMatthew G. Knepley static PetscReal quad_v0[] = {-1.0, -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0}; 121412e9a14SMatthew G. Knepley static PetscReal quad_J[] = {0.5, 0.0, 122412e9a14SMatthew G. Knepley 0.0, 0.5, 123412e9a14SMatthew G. Knepley 124412e9a14SMatthew G. Knepley 0.5, 0.0, 125412e9a14SMatthew G. Knepley 0.0, 0.5, 126412e9a14SMatthew G. Knepley 127412e9a14SMatthew G. Knepley 0.5, 0.0, 128412e9a14SMatthew G. Knepley 0.0, 0.5, 129412e9a14SMatthew G. Knepley 130412e9a14SMatthew G. Knepley 0.5, 0.0, 131412e9a14SMatthew G. Knepley 0.0, 0.5}; 132412e9a14SMatthew G. Knepley static PetscReal quad_invJ[] = {2.0, 0.0, 133412e9a14SMatthew G. Knepley 0.0, 2.0, 134412e9a14SMatthew G. Knepley 135412e9a14SMatthew G. Knepley 2.0, 0.0, 136412e9a14SMatthew G. Knepley 0.0, 2.0, 137412e9a14SMatthew G. Knepley 138412e9a14SMatthew G. Knepley 2.0, 0.0, 139412e9a14SMatthew G. Knepley 0.0, 2.0, 140412e9a14SMatthew G. Knepley 141412e9a14SMatthew G. Knepley 2.0, 0.0, 142412e9a14SMatthew G. Knepley 0.0, 2.0}; 143c1879b55SMatthew G. Knepley /* 144c1879b55SMatthew G. Knepley Bottom (viewed from top) Top 145c1879b55SMatthew G. Knepley 1---------2---------2 7---------2---------6 146c1879b55SMatthew G. Knepley | | | | | | 147c1879b55SMatthew G. Knepley | B 2 C | | H 2 G | 148c1879b55SMatthew G. Knepley | | | | | | 149c1879b55SMatthew G. Knepley 3----3----0----1----1 3----3----0----1----1 150c1879b55SMatthew G. Knepley | | | | | | 151c1879b55SMatthew G. Knepley | A 0 D | | E 0 F | 152c1879b55SMatthew G. Knepley | | | | | | 153c1879b55SMatthew G. Knepley 0---------0---------3 4---------0---------5 154c1879b55SMatthew G. Knepley */ 155412e9a14SMatthew G. Knepley static PetscReal hex_v0[] = {-1.0, -1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0, -1.0, 156412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0}; 157412e9a14SMatthew G. Knepley static PetscReal hex_J[] = {0.5, 0.0, 0.0, 158412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 159412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 160bed052eaSMatthew G. Knepley 161412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 162412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 163412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 164412e9a14SMatthew G. Knepley 165412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 166412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 167412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 168412e9a14SMatthew G. Knepley 169412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 170412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 171412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 172412e9a14SMatthew G. Knepley 173412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 174412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 175412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 176412e9a14SMatthew G. Knepley 177412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 178412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 179412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 180412e9a14SMatthew G. Knepley 181412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 182412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 183412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 184412e9a14SMatthew G. Knepley 185412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 186412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 187412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5}; 188412e9a14SMatthew G. Knepley static PetscReal hex_invJ[] = {2.0, 0.0, 0.0, 189412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 190412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 191412e9a14SMatthew G. Knepley 192412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 193412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 194412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 195412e9a14SMatthew G. Knepley 196412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 197412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 198412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 199412e9a14SMatthew G. Knepley 200412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 201412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 202412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 203412e9a14SMatthew G. Knepley 204412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 205412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 206412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 207412e9a14SMatthew G. Knepley 208412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 209412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 210412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 211412e9a14SMatthew G. Knepley 212412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 213412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 214412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 215412e9a14SMatthew G. Knepley 216412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 217412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 218412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0}; 219bed052eaSMatthew G. Knepley 220bed052eaSMatthew G. Knepley PetscFunctionBegin; 221412e9a14SMatthew G. Knepley switch (ct) { 222412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: if (Nc) *Nc = 4; if (v0) *v0 = tri_v0; if (J) *J = tri_J; if (invJ) *invJ = tri_invJ; break; 223412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: if (Nc) *Nc = 4; if (v0) *v0 = quad_v0; if (J) *J = quad_J; if (invJ) *invJ = quad_invJ; break; 224412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: if (Nc) *Nc = 8; if (v0) *v0 = hex_v0; if (J) *J = hex_J; if (invJ) *invJ = hex_invJ; break; 225412e9a14SMatthew G. Knepley default: 226412e9a14SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 227412e9a14SMatthew G. Knepley } 228bed052eaSMatthew G. Knepley PetscFunctionReturn(0); 229bed052eaSMatthew G. Knepley } 230bed052eaSMatthew G. Knepley 23180389061SMatthew G. Knepley /* Should this be here or in the DualSpace somehow? */ 232412e9a14SMatthew G. Knepley PetscErrorCode CellRefinerInCellTest_Internal(DMPolytopeType ct, const PetscReal point[], PetscBool *inside) 23380389061SMatthew G. Knepley { 23480389061SMatthew G. Knepley PetscReal sum = 0.0; 23580389061SMatthew G. Knepley PetscInt d; 23680389061SMatthew G. Knepley 23780389061SMatthew G. Knepley PetscFunctionBegin; 23880389061SMatthew G. Knepley *inside = PETSC_TRUE; 239412e9a14SMatthew G. Knepley switch (ct) { 240412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 241412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 242412e9a14SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) { 24380389061SMatthew G. Knepley if (point[d] < -1.0) {*inside = PETSC_FALSE; break;} 24480389061SMatthew G. Knepley sum += point[d]; 24580389061SMatthew G. Knepley } 246412e9a14SMatthew G. Knepley if (sum > PETSC_SMALL) {*inside = PETSC_FALSE; break;} 24780389061SMatthew G. Knepley break; 248412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 249412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 250412e9a14SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) 251412e9a14SMatthew G. Knepley if (PetscAbsReal(point[d]) > 1.+PETSC_SMALL) {*inside = PETSC_FALSE; break;} 25294339e62SJed Brown break; 25380389061SMatthew G. Knepley default: 254412e9a14SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 25580389061SMatthew G. Knepley } 25680389061SMatthew G. Knepley PetscFunctionReturn(0); 25780389061SMatthew G. Knepley } 25880389061SMatthew G. Knepley 259412e9a14SMatthew G. Knepley /* Regular Refinment of Hybrid Meshes 26075d3a19aSMatthew G. Knepley 261412e9a14SMatthew G. Knepley We would like to express regular refinement as a small set of rules that can be applied on every point of the Plex 262412e9a14SMatthew G. Knepley to automatically generate a refined Plex. In fact, we would like these rules to be general enough to encompass other 263412e9a14SMatthew G. Knepley transformations, such as changing from one type of cell to another, as simplex to hex. 26475d3a19aSMatthew G. Knepley 265412e9a14SMatthew G. Knepley To start, we can create a function that takes an original cell type and returns the number of new cells replacing it 266412e9a14SMatthew G. Knepley and the types of the new cells. 267518a8359SMatthew G. Knepley 268412e9a14SMatthew G. Knepley We need the group multiplication table for group actions from the dihedral group for each cell type. 26942525629SMatthew G. Knepley 270412e9a14SMatthew G. Knepley We need an operator which takes in a cell, and produces a new set of cells with new faces and correct orientations. I think 271412e9a14SMatthew G. Knepley we can just write this operator for faces with identity, and then compose the face orientation actions to get the actual 272412e9a14SMatthew G. Knepley (face, orient) pairs for each subcell. 273412e9a14SMatthew G. Knepley */ 2740314a74cSLawrence Mitchell 27575d3a19aSMatthew G. Knepley /* 276412e9a14SMatthew G. Knepley Input Parameters: 277412e9a14SMatthew G. Knepley + ct - The type of the input cell 278412e9a14SMatthew G. Knepley . co - The orientation of this cell in it parent 279412e9a14SMatthew G. Knepley - cp - The requested cone point of this cell assuming orientation 0 280412e9a14SMatthew G. Knepley 281412e9a14SMatthew G. Knepley Output Parameters: 282412e9a14SMatthew G. Knepley . cpnew - The new cone point, taking inout account the orientation co 283412e9a14SMatthew G. Knepley */ 284412e9a14SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPolytopeMapCell(DMPolytopeType ct, PetscInt co, PetscInt cp, PetscInt *cpnew) 285412e9a14SMatthew G. Knepley { 286412e9a14SMatthew G. Knepley const PetscInt csize = DMPolytopeTypeGetConeSize(ct); 287412e9a14SMatthew G. Knepley 288412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 289412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_POINT) {*cpnew = cp;} 290412e9a14SMatthew G. Knepley else {*cpnew = (co < 0 ? -(co+1)-cp+csize : co+cp)%csize;} 291412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 292412e9a14SMatthew G. Knepley } 293412e9a14SMatthew G. Knepley 294412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCellVertices_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 295412e9a14SMatthew G. Knepley { 296412e9a14SMatthew G. Knepley static PetscReal seg_v[] = {-1.0, 0.0, 1.0}; 297412e9a14SMatthew G. Knepley static PetscReal tri_v[] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0}; 298412e9a14SMatthew G. Knepley static PetscReal quad_v[] = {-1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0}; 299412e9a14SMatthew G. Knepley static PetscReal tet_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 300412e9a14SMatthew G. Knepley -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, -1.0, 1.0, -1.0, 301412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, -1.0, 1.0}; 302412e9a14SMatthew G. Knepley static PetscReal hex_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 303412e9a14SMatthew G. Knepley -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0, -1.0, 304412e9a14SMatthew G. Knepley -1.0, 1.0, -1.0, 0.0, 1.0, -1.0, 1.0, 1.0, -1.0, 305412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0, -1.0, 0.0, 306412e9a14SMatthew G. Knepley -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 307412e9a14SMatthew G. Knepley -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 308412e9a14SMatthew G. Knepley -1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 1.0, -1.0, 1.0, 309412e9a14SMatthew G. Knepley -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 310412e9a14SMatthew G. Knepley -1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0}; 311412e9a14SMatthew G. Knepley 312412e9a14SMatthew G. Knepley PetscFunctionBegin; 313412e9a14SMatthew G. Knepley switch (ct) { 314412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nv = 3; *subcellV = seg_v; break; 315412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 6; *subcellV = tri_v; break; 316412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nv = 9; *subcellV = quad_v; break; 317412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 10; *subcellV = tet_v; break; 318412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nv = 27; *subcellV = hex_v; break; 319412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 320412e9a14SMatthew G. Knepley } 321412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 322412e9a14SMatthew G. Knepley } 323412e9a14SMatthew G. Knepley 32496ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerGetCellVertices_ToBox(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 325412e9a14SMatthew G. Knepley { 326412e9a14SMatthew G. Knepley static PetscReal tri_v[] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0/3.0, -1.0/3.0}; 327412e9a14SMatthew G. Knepley static PetscReal tet_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 328412e9a14SMatthew G. Knepley -1.0, 0.0, -1.0, -1.0/3.0, -1.0/3.0, -1.0, 0.0, 0.0, -1.0, -1.0, 1.0, -1.0, 329412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, -1.0/3.0, -1.0, -1.0/3.0, 0.0, -1.0, 0.0, 330412e9a14SMatthew G. Knepley -1.0, -1.0/3.0, -1.0/3.0, -1.0/3.0, -1.0/3.0, -1.0/3.0, -1.0, 0.0, 0.0, 331412e9a14SMatthew G. Knepley -1.0, -1.0, 1.0, -0.5, -0.5, -0.5}; 332412e9a14SMatthew G. Knepley PetscErrorCode ierr; 333412e9a14SMatthew G. Knepley 334412e9a14SMatthew G. Knepley PetscFunctionBegin; 335412e9a14SMatthew G. Knepley switch (ct) { 336412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 337412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 338412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 339412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCellVertices_Regular(cr, ct, Nv, subcellV);CHKERRQ(ierr);break; 340412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 7; *subcellV = tri_v; break; 341412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 15; *subcellV = tet_v; break; 342412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 343412e9a14SMatthew G. Knepley } 344412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 345412e9a14SMatthew G. Knepley } 346412e9a14SMatthew G. Knepley 347412e9a14SMatthew G. Knepley /* 348412e9a14SMatthew G. Knepley DMPlexCellRefinerGetCellVertices - Get the set of refined vertices lying in the closure of a reference cell of given type 349412e9a14SMatthew G. Knepley 350412e9a14SMatthew G. Knepley Input Parameters: 351412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 352412e9a14SMatthew G. Knepley - ct - The cell type 353412e9a14SMatthew G. Knepley 354412e9a14SMatthew G. Knepley Output Parameters: 355412e9a14SMatthew G. Knepley + Nv - The number of refined vertices in the closure of the reference cell of given type 356412e9a14SMatthew G. Knepley - subcellV - The coordinates of these vertices in the reference cell 357412e9a14SMatthew G. Knepley 358412e9a14SMatthew G. Knepley Level: developer 359412e9a14SMatthew G. Knepley 360412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetSubcellVertices() 361412e9a14SMatthew G. Knepley */ 362412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCellVertices(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 363412e9a14SMatthew G. Knepley { 364412e9a14SMatthew G. Knepley PetscErrorCode ierr; 365412e9a14SMatthew G. Knepley 366412e9a14SMatthew G. Knepley PetscFunctionBegin; 367412e9a14SMatthew G. Knepley ierr = (*cr->ops->getcellvertices)(cr, ct, Nv, subcellV);CHKERRQ(ierr); 368412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 369412e9a14SMatthew G. Knepley } 370412e9a14SMatthew G. Knepley 371412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 372412e9a14SMatthew G. Knepley { 373412e9a14SMatthew G. Knepley static PetscInt seg_v[] = {0, 1, 1, 2}; 374412e9a14SMatthew G. Knepley static PetscInt tri_v[] = {0, 3, 5, 3, 1, 4, 5, 4, 2, 3, 4, 5}; 375412e9a14SMatthew G. Knepley static PetscInt quad_v[] = {0, 4, 8, 7, 4, 1, 5, 8, 8, 5, 2, 6, 7, 8, 6, 3}; 376412e9a14SMatthew G. Knepley static PetscInt tet_v[] = {0, 3, 1, 6, 3, 2, 4, 8, 1, 4, 5, 7, 6, 8, 7, 9, 377412e9a14SMatthew G. Knepley 1, 6, 3, 7, 8, 4, 3, 7, 7, 3, 1, 4, 7, 3, 8, 6}; 378412e9a14SMatthew G. Knepley static PetscInt hex_v[] = {0, 3, 4, 1, 9, 10, 13, 12, 3, 6, 7, 4, 12, 13, 16, 15, 4, 7, 8, 5, 13, 14, 17, 16, 1, 4 , 5 , 2, 10, 11, 14, 13, 379412e9a14SMatthew G. Knepley 9, 12, 13, 10, 18, 19, 22, 21, 10, 13, 14, 11, 19, 20, 23, 22, 13, 16, 17, 14, 22, 23, 26, 25, 12, 15, 16, 13, 21, 22, 25, 24}; 380412e9a14SMatthew G. Knepley 381412e9a14SMatthew G. Knepley PetscFunctionBegin; 382412e9a14SMatthew G. Knepley if (ct != rct) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Cell type %s does not produce %s", DMPolytopeTypes[ct], DMPolytopeTypes[rct]); 383412e9a14SMatthew G. Knepley switch (ct) { 384412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nv = 2; *subcellV = &seg_v[r*(*Nv)]; break; 385412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 3; *subcellV = &tri_v[r*(*Nv)]; break; 386412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nv = 4; *subcellV = &quad_v[r*(*Nv)]; break; 387412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 4; *subcellV = &tet_v[r*(*Nv)]; break; 388412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nv = 8; *subcellV = &hex_v[r*(*Nv)]; break; 389412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 390412e9a14SMatthew G. Knepley } 391412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 392412e9a14SMatthew G. Knepley } 393412e9a14SMatthew G. Knepley 39496ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerGetSubcellVertices_ToBox(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 395412e9a14SMatthew G. Knepley { 396412e9a14SMatthew G. Knepley static PetscInt tri_v[] = {0, 3, 6, 5, 3, 1, 4, 6, 5, 6, 4, 2}; 397412e9a14SMatthew G. Knepley static PetscInt tet_v[] = {0, 3, 4, 1, 7, 8, 14, 10, 6, 12, 11, 5, 3, 4, 14, 10, 2, 5, 11, 9, 1, 8, 14, 4, 13, 12 , 10, 7, 9, 8, 14, 11}; 398412e9a14SMatthew G. Knepley PetscErrorCode ierr; 399412e9a14SMatthew G. Knepley 400412e9a14SMatthew G. Knepley PetscFunctionBegin; 401412e9a14SMatthew G. Knepley switch (ct) { 402412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 403412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 404412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 405412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetSubcellVertices_Regular(cr, ct, rct, r, Nv, subcellV);CHKERRQ(ierr);break; 406412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 407412e9a14SMatthew G. Knepley if (rct != DM_POLYTOPE_QUADRILATERAL) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Cell type %s does not produce %s", DMPolytopeTypes[ct], DMPolytopeTypes[rct]); 408412e9a14SMatthew G. Knepley *Nv = 4; *subcellV = &tri_v[r*(*Nv)]; break; 409412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 410412e9a14SMatthew G. Knepley if (rct != DM_POLYTOPE_HEXAHEDRON) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Cell type %s does not produce %s", DMPolytopeTypes[ct], DMPolytopeTypes[rct]); 411412e9a14SMatthew G. Knepley *Nv = 8; *subcellV = &tet_v[r*(*Nv)]; break; 412412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 413412e9a14SMatthew G. Knepley } 414412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 415412e9a14SMatthew G. Knepley } 416412e9a14SMatthew G. Knepley 417412e9a14SMatthew G. Knepley /* 418412e9a14SMatthew G. Knepley DMPlexCellRefinerGetSubcellVertices - Get the set of refined vertices defining a subcell in the reference cell of given type 419412e9a14SMatthew G. Knepley 420412e9a14SMatthew G. Knepley Input Parameters: 421412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 422412e9a14SMatthew G. Knepley . ct - The cell type 423412e9a14SMatthew G. Knepley . rct - The type of subcell 424412e9a14SMatthew G. Knepley - r - The subcell index 425412e9a14SMatthew G. Knepley 426412e9a14SMatthew G. Knepley Output Parameters: 427412e9a14SMatthew G. Knepley + Nv - The number of refined vertices in the subcell 428412e9a14SMatthew G. Knepley - subcellV - The indices of these vertices in the set of vertices returned by DMPlexCellRefinerGetCellVertices() 429412e9a14SMatthew G. Knepley 430412e9a14SMatthew G. Knepley Level: developer 431412e9a14SMatthew G. Knepley 432412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetCellVertices() 433412e9a14SMatthew G. Knepley */ 434412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 435412e9a14SMatthew G. Knepley { 436412e9a14SMatthew G. Knepley PetscErrorCode ierr; 437412e9a14SMatthew G. Knepley 438412e9a14SMatthew G. Knepley PetscFunctionBegin; 439412e9a14SMatthew G. Knepley ierr = (*cr->ops->getsubcellvertices)(cr, ct, rct, r, Nv, subcellV);CHKERRQ(ierr); 440412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 441412e9a14SMatthew G. Knepley } 442412e9a14SMatthew G. Knepley 443412e9a14SMatthew G. Knepley /* 444412e9a14SMatthew G. Knepley Input Parameters: 445412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner 446412e9a14SMatthew G. Knepley . pct - The cell type of the parent, from whom the new cell is being produced 447412e9a14SMatthew G. Knepley . po - The orientation of the parent cell in its enclosing parent 448412e9a14SMatthew G. Knepley . ct - The type being produced 449412e9a14SMatthew G. Knepley . r - The replica number requested for the produced cell type 450412e9a14SMatthew G. Knepley - o - The relative orientation of the replica 451412e9a14SMatthew G. Knepley 452412e9a14SMatthew G. Knepley Output Parameters: 453412e9a14SMatthew G. Knepley + rnew - The replica number, given the orientation of of the parent 454412e9a14SMatthew G. Knepley - onew - The replica orientation, given the orientation of the parent 455412e9a14SMatthew G. Knepley */ 456412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 457412e9a14SMatthew G. Knepley { 458412e9a14SMatthew G. Knepley PetscErrorCode ierr; 459412e9a14SMatthew G. Knepley 460412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 461412e9a14SMatthew G. Knepley ierr = (*cr->ops->mapsubcells)(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 462412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 463412e9a14SMatthew G. Knepley } 464412e9a14SMatthew G. Knepley 465*cf4091a3SMatthew G. Knepley /* 466*cf4091a3SMatthew G. Knepley This is the group multiplication table for the dihedral group of the cell. 467*cf4091a3SMatthew G. Knepley */ 468*cf4091a3SMatthew G. Knepley static PetscErrorCode ComposeOrientation_Private(PetscInt n, PetscInt o1, PetscInt o2, PetscInt *o) 469*cf4091a3SMatthew G. Knepley { 470*cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 471*cf4091a3SMatthew G. Knepley if (!n) {*o = 0;} 472*cf4091a3SMatthew G. Knepley else if (o1 >= 0 && o2 >= 0) {*o = ( o1 + o2) % n;} 473*cf4091a3SMatthew G. Knepley else if (o1 < 0 && o2 < 0) {*o = (-o1 - o2) % n;} 474*cf4091a3SMatthew G. Knepley else if (o1 < 0) {*o = -((-(o1+1) + o2) % n + 1);} 475*cf4091a3SMatthew G. Knepley else if (o2 < 0) {*o = -((-(o2+1) + o1) % n + 1);} 476*cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 477*cf4091a3SMatthew G. Knepley } 478*cf4091a3SMatthew G. Knepley 479*cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_None(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 480*cf4091a3SMatthew G. Knepley { 481*cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 482*cf4091a3SMatthew G. Knepley 483*cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 484*cf4091a3SMatthew G. Knepley *rnew = r; 485*cf4091a3SMatthew G. Knepley ierr = ComposeOrientation_Private(DMPolytopeTypeGetConeSize(ct), po, o, onew);CHKERRQ(ierr); 486*cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 487*cf4091a3SMatthew G. Knepley } 488*cf4091a3SMatthew G. Knepley 489412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_Regular(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 490412e9a14SMatthew G. Knepley { 491412e9a14SMatthew G. Knepley /* We shift any input orientation in order to make it non-negative 492412e9a14SMatthew G. Knepley The orientation array o[po][o] gives the orientation the new replica rnew has to have in order to reproduce the face sequence from (r, o) 493412e9a14SMatthew G. Knepley The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 494412e9a14SMatthew G. Knepley Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 495412e9a14SMatthew G. Knepley */ 496412e9a14SMatthew G. Knepley PetscInt tri_seg_o[] = {-2, 0, 497412e9a14SMatthew G. Knepley -2, 0, 498412e9a14SMatthew G. Knepley -2, 0, 499412e9a14SMatthew G. Knepley 0, -2, 500412e9a14SMatthew G. Knepley 0, -2, 501412e9a14SMatthew G. Knepley 0, -2}; 502412e9a14SMatthew G. Knepley PetscInt tri_seg_r[] = {1, 0, 2, 503412e9a14SMatthew G. Knepley 0, 2, 1, 504412e9a14SMatthew G. Knepley 2, 1, 0, 505412e9a14SMatthew G. Knepley 0, 1, 2, 506412e9a14SMatthew G. Knepley 1, 2, 0, 507412e9a14SMatthew G. Knepley 2, 0, 1}; 508412e9a14SMatthew G. Knepley PetscInt tri_tri_o[] = {0, 1, 2, -3, -2, -1, 509412e9a14SMatthew G. Knepley 2, 0, 1, -2, -1, -3, 510412e9a14SMatthew G. Knepley 1, 2, 0, -1, -3, -2, 511412e9a14SMatthew G. Knepley -3, -2, -1, 0, 1, 2, 512412e9a14SMatthew G. Knepley -1, -3, -2, 1, 2, 0, 513412e9a14SMatthew G. Knepley -2, -1, -3, 2, 0, 1}; 514412e9a14SMatthew G. Knepley /* orientation if the replica is the center triangle */ 515412e9a14SMatthew G. Knepley PetscInt tri_tri_o_c[] = {2, 0, 1, -2, -1, -3, 516412e9a14SMatthew G. Knepley 1, 2, 0, -1, -3, -2, 517412e9a14SMatthew G. Knepley 0, 1, 2, -3, -2, -1, 518412e9a14SMatthew G. Knepley -3, -2, -1, 0, 1, 2, 519412e9a14SMatthew G. Knepley -1, -3, -2, 1, 2, 0, 520412e9a14SMatthew G. Knepley -2, -1, -3, 2, 0, 1}; 521412e9a14SMatthew G. Knepley PetscInt tri_tri_r[] = {0, 2, 1, 3, 522412e9a14SMatthew G. Knepley 2, 1, 0, 3, 523412e9a14SMatthew G. Knepley 1, 0, 2, 3, 524412e9a14SMatthew G. Knepley 0, 1, 2, 3, 525412e9a14SMatthew G. Knepley 1, 2, 0, 3, 526412e9a14SMatthew G. Knepley 2, 0, 1, 3}; 527412e9a14SMatthew G. Knepley PetscInt quad_seg_r[] = {3, 2, 1, 0, 528412e9a14SMatthew G. Knepley 2, 1, 0, 3, 529412e9a14SMatthew G. Knepley 1, 0, 3, 2, 530412e9a14SMatthew G. Knepley 0, 3, 2, 1, 531412e9a14SMatthew G. Knepley 0, 1, 2, 3, 532412e9a14SMatthew G. Knepley 1, 2, 3, 0, 533412e9a14SMatthew G. Knepley 2, 3, 0, 1, 534412e9a14SMatthew G. Knepley 3, 0, 1, 2}; 535412e9a14SMatthew G. Knepley PetscInt quad_quad_o[] = { 0, 1, 2, 3, -4, -3, -2, -1, 536412e9a14SMatthew G. Knepley 4, 0, 1, 2, -3, -2, -1, -4, 537412e9a14SMatthew G. Knepley 3, 4, 0, 1, -2, -1, -4, -3, 538412e9a14SMatthew G. Knepley 2, 3, 4, 0, -1, -4, -3, -2, 539412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 540412e9a14SMatthew G. Knepley -1, -4, -3, -2, 1, 2, 3, 0, 541412e9a14SMatthew G. Knepley -2, -1, -4, -3, 2, 3, 0, 1, 542412e9a14SMatthew G. Knepley -3, -2, -1, -4, 3, 0, 1, 2}; 543412e9a14SMatthew G. Knepley PetscInt quad_quad_r[] = {0, 3, 2, 1, 544412e9a14SMatthew G. Knepley 3, 2, 1, 0, 545412e9a14SMatthew G. Knepley 2, 1, 0, 3, 546412e9a14SMatthew G. Knepley 1, 0, 3, 2, 547412e9a14SMatthew G. Knepley 0, 1, 2, 3, 548412e9a14SMatthew G. Knepley 1, 2, 3, 0, 549412e9a14SMatthew G. Knepley 2, 3, 0, 1, 550412e9a14SMatthew G. Knepley 3, 0, 1, 2}; 551412e9a14SMatthew G. Knepley PetscInt tquad_tquad_o[] = { 0, 1, -2, -1, 552412e9a14SMatthew G. Knepley 1, 0, -1, -2, 553412e9a14SMatthew G. Knepley -2, -1, 0, 1, 554412e9a14SMatthew G. Knepley -1, -2, 1, 0}; 555412e9a14SMatthew G. Knepley PetscInt tquad_tquad_r[] = {1, 0, 556412e9a14SMatthew G. Knepley 1, 0, 557412e9a14SMatthew G. Knepley 0, 1, 558412e9a14SMatthew G. Knepley 0, 1}; 559412e9a14SMatthew G. Knepley 560412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 561412e9a14SMatthew G. Knepley /* The default is no transformation */ 562412e9a14SMatthew G. Knepley *rnew = r; 563412e9a14SMatthew G. Knepley *onew = o; 564412e9a14SMatthew G. Knepley switch (pct) { 565412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 566412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_SEGMENT) { 567412e9a14SMatthew G. Knepley if (po == 0 || po == -1) {*rnew = r; *onew = o;} 568412e9a14SMatthew G. Knepley else if (po == 1 || po == -2) {*rnew = (r+1)%2; *onew = (o == 0 || o == -1) ? -2 : 0;} 569412e9a14SMatthew G. Knepley else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid orientation %D for segment", po); 570412e9a14SMatthew G. Knepley } 571412e9a14SMatthew G. Knepley break; 572412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 573412e9a14SMatthew G. Knepley switch (ct) { 574412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 575412e9a14SMatthew G. Knepley if (o == -1) o = 0; 576412e9a14SMatthew G. Knepley if (o == -2) o = 1; 577412e9a14SMatthew G. Knepley *onew = tri_seg_o[(po+3)*2+o]; 578412e9a14SMatthew G. Knepley *rnew = tri_seg_r[(po+3)*3+r]; 579412e9a14SMatthew G. Knepley break; 580412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 581412e9a14SMatthew G. Knepley *onew = r == 3 && po < 0 ? tri_tri_o_c[((po+3)%3)*6+o+3] : tri_tri_o[(po+3)*6+o+3]; 582412e9a14SMatthew G. Knepley *rnew = tri_tri_r[(po+3)*4+r]; 583412e9a14SMatthew G. Knepley break; 584412e9a14SMatthew G. Knepley default: break; 585412e9a14SMatthew G. Knepley } 586412e9a14SMatthew G. Knepley break; 587412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 588412e9a14SMatthew G. Knepley switch (ct) { 589412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 590412e9a14SMatthew G. Knepley *onew = o; 591412e9a14SMatthew G. Knepley *rnew = quad_seg_r[(po+4)*4+r]; 592412e9a14SMatthew G. Knepley break; 593412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 594412e9a14SMatthew G. Knepley *onew = quad_quad_o[(po+4)*8+o+4]; 595412e9a14SMatthew G. Knepley *rnew = quad_quad_r[(po+4)*4+r]; 596412e9a14SMatthew G. Knepley break; 597412e9a14SMatthew G. Knepley default: break; 598412e9a14SMatthew G. Knepley } 599412e9a14SMatthew G. Knepley break; 600412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 601412e9a14SMatthew G. Knepley switch (ct) { 602412e9a14SMatthew G. Knepley /* DM_POLYTOPE_POINT_PRISM_TENSOR does not change */ 603412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 604412e9a14SMatthew G. Knepley *onew = tquad_tquad_o[(po+2)*4+o+2]; 605412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 606412e9a14SMatthew G. Knepley break; 607412e9a14SMatthew G. Knepley default: break; 608412e9a14SMatthew G. Knepley } 609412e9a14SMatthew G. Knepley break; 610412e9a14SMatthew G. Knepley default: break; 611412e9a14SMatthew G. Knepley } 612412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 613412e9a14SMatthew G. Knepley } 614412e9a14SMatthew G. Knepley 61596ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerMapSubcells_ToBox(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 616412e9a14SMatthew G. Knepley { 617412e9a14SMatthew G. Knepley PetscErrorCode ierr; 618412e9a14SMatthew G. Knepley /* We shift any input orientation in order to make it non-negative 619412e9a14SMatthew G. Knepley The orientation array o[po][o] gives the orientation the new replica rnew has to have in order to reproduce the face sequence from (r, o) 620412e9a14SMatthew G. Knepley The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 621412e9a14SMatthew G. Knepley Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 622412e9a14SMatthew G. Knepley */ 623412e9a14SMatthew G. Knepley PetscInt tri_seg_o[] = {0, -2, 624412e9a14SMatthew G. Knepley 0, -2, 625412e9a14SMatthew G. Knepley 0, -2, 626412e9a14SMatthew G. Knepley 0, -2, 627412e9a14SMatthew G. Knepley 0, -2, 628412e9a14SMatthew G. Knepley 0, -2}; 629412e9a14SMatthew G. Knepley PetscInt tri_seg_r[] = {2, 1, 0, 630412e9a14SMatthew G. Knepley 1, 0, 2, 631412e9a14SMatthew G. Knepley 0, 2, 1, 632412e9a14SMatthew G. Knepley 0, 1, 2, 633412e9a14SMatthew G. Knepley 1, 2, 0, 634412e9a14SMatthew G. Knepley 2, 0, 1}; 635412e9a14SMatthew G. Knepley PetscInt tri_tri_o[] = {0, 1, 2, 3, -4, -3, -2, -1, 636412e9a14SMatthew G. Knepley 3, 0, 1, 2, -3, -2, -1, -4, 637412e9a14SMatthew G. Knepley 1, 2, 3, 0, -1, -4, -3, -2, 638412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 639412e9a14SMatthew G. Knepley -1, -4, -3, -2, 1, 2, 3, 0, 640412e9a14SMatthew G. Knepley -3, -2, -1, -4, 3, 0, 1, 2}; 641412e9a14SMatthew G. Knepley PetscInt tri_tri_r[] = {0, 2, 1, 642412e9a14SMatthew G. Knepley 2, 1, 0, 643412e9a14SMatthew G. Knepley 1, 0, 2, 644412e9a14SMatthew G. Knepley 0, 1, 2, 645412e9a14SMatthew G. Knepley 1, 2, 0, 646412e9a14SMatthew G. Knepley 2, 0, 1}; 647412e9a14SMatthew G. Knepley PetscInt tquad_tquad_o[] = { 0, 1, -2, -1, 648412e9a14SMatthew G. Knepley 1, 0, -1, -2, 649412e9a14SMatthew G. Knepley -2, -1, 0, 1, 650412e9a14SMatthew G. Knepley -1, -2, 1, 0}; 651412e9a14SMatthew G. Knepley PetscInt tquad_tquad_r[] = {1, 0, 652412e9a14SMatthew G. Knepley 1, 0, 653412e9a14SMatthew G. Knepley 0, 1, 654412e9a14SMatthew G. Knepley 0, 1}; 655412e9a14SMatthew G. Knepley PetscInt tquad_quad_o[] = {-2, -1, -4, -3, 2, 3, 0, 1, 656412e9a14SMatthew G. Knepley 1, 2, 3, 0, -1, -4, -3, -2, 657412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 658412e9a14SMatthew G. Knepley 1, 0, 3, 2, -3, -4, -1, -2}; 659412e9a14SMatthew G. Knepley 660412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 661412e9a14SMatthew G. Knepley *rnew = r; 662412e9a14SMatthew G. Knepley *onew = o; 663412e9a14SMatthew G. Knepley switch (pct) { 664412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 665412e9a14SMatthew G. Knepley switch (ct) { 666412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 667412e9a14SMatthew G. Knepley if (o == -1) o = 0; 668412e9a14SMatthew G. Knepley if (o == -2) o = 1; 669412e9a14SMatthew G. Knepley *onew = tri_seg_o[(po+3)*2+o]; 670412e9a14SMatthew G. Knepley *rnew = tri_seg_r[(po+3)*3+r]; 671412e9a14SMatthew G. Knepley break; 672412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 673412e9a14SMatthew G. Knepley *onew = tri_tri_o[(po+3)*8+o+4]; 674412e9a14SMatthew G. Knepley /* TODO See sheet, for fixing po == 1 and 2 */ 675412e9a14SMatthew G. Knepley if (po == 2 && r == 2 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+3)%4)+4]; 676412e9a14SMatthew G. Knepley if (po == 2 && r == 2 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+5)%4)]; 677412e9a14SMatthew G. Knepley if (po == 1 && r == 1 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+1)%4)+4]; 678412e9a14SMatthew G. Knepley if (po == 1 && r == 1 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+7)%4)]; 679412e9a14SMatthew G. Knepley if (po == -1 && r == 2 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+3)%4)+4]; 680412e9a14SMatthew G. Knepley if (po == -1 && r == 2 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+5)%4)]; 681412e9a14SMatthew G. Knepley if (po == -2 && r == 1 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+1)%4)+4]; 682412e9a14SMatthew G. Knepley if (po == -2 && r == 1 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+7)%4)]; 683412e9a14SMatthew G. Knepley *rnew = tri_tri_r[(po+3)*3+r]; 684412e9a14SMatthew G. Knepley break; 685412e9a14SMatthew G. Knepley default: break; 686412e9a14SMatthew G. Knepley } 687412e9a14SMatthew G. Knepley break; 688412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 689412e9a14SMatthew G. Knepley switch (ct) { 690412e9a14SMatthew G. Knepley /* DM_POLYTOPE_POINT_PRISM_TENSOR does not change */ 691412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 692412e9a14SMatthew G. Knepley *onew = tquad_tquad_o[(po+2)*4+o+2]; 693412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 694412e9a14SMatthew G. Knepley break; 695412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 696412e9a14SMatthew G. Knepley *onew = tquad_quad_o[(po+2)*8+o+4]; 697412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 698412e9a14SMatthew G. Knepley break; 699412e9a14SMatthew G. Knepley default: break; 700412e9a14SMatthew G. Knepley } 701412e9a14SMatthew G. Knepley break; 702412e9a14SMatthew G. Knepley default: 703412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapSubcells_Regular(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 704412e9a14SMatthew G. Knepley } 705412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 706412e9a14SMatthew G. Knepley } 707412e9a14SMatthew G. Knepley 708412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 709412e9a14SMatthew G. Knepley { 710412e9a14SMatthew G. Knepley return DMPlexCellRefinerMapSubcells_Regular(cr, pct, po, ct, r, o, rnew, onew); 711412e9a14SMatthew G. Knepley } 712412e9a14SMatthew G. Knepley 713*cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_BL(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 714*cf4091a3SMatthew G. Knepley { 715*cf4091a3SMatthew G. Knepley /* We shift any input orientation in order to make it non-negative 716*cf4091a3SMatthew G. Knepley The orientation array o[po][o] gives the orientation the new replica rnew has to have in order to reproduce the face sequence from (r, o) 717*cf4091a3SMatthew G. Knepley The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 718*cf4091a3SMatthew G. Knepley Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 719*cf4091a3SMatthew G. Knepley */ 720*cf4091a3SMatthew G. Knepley PetscInt tquad_seg_o[] = { 0, 1, -2, -1, 721*cf4091a3SMatthew G. Knepley 0, 1, -2, -1, 722*cf4091a3SMatthew G. Knepley -2, -1, 0, 1, 723*cf4091a3SMatthew G. Knepley -2, -1, 0, 1}; 724*cf4091a3SMatthew G. Knepley PetscInt tquad_tquad_o[] = { 0, 1, -2, -1, 725*cf4091a3SMatthew G. Knepley 1, 0, -1, -2, 726*cf4091a3SMatthew G. Knepley -2, -1, 0, 1, 727*cf4091a3SMatthew G. Knepley -1, -2, 1, 0}; 728*cf4091a3SMatthew G. Knepley PetscInt tquad_tquad_r[] = {1, 0, 729*cf4091a3SMatthew G. Knepley 0, 1, 730*cf4091a3SMatthew G. Knepley 0, 1, 731*cf4091a3SMatthew G. Knepley 1, 0}; 732*cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 733*cf4091a3SMatthew G. Knepley 734*cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 735*cf4091a3SMatthew G. Knepley *rnew = r; 736*cf4091a3SMatthew G. Knepley *onew = o; 737*cf4091a3SMatthew G. Knepley switch (pct) { 738*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 739*cf4091a3SMatthew G. Knepley if (ct == DM_POLYTOPE_POINT_PRISM_TENSOR) { 740*cf4091a3SMatthew G. Knepley if (po == 0 || po == -1) {*rnew = r; *onew = o;} 741*cf4091a3SMatthew G. Knepley else if (po == 1 || po == -2) {*rnew = (r+1)%2; *onew = (o == 0 || o == -1) ? -2 : 0;} 742*cf4091a3SMatthew G. Knepley else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid orientation %D for tensor segment", po); 743*cf4091a3SMatthew G. Knepley } 744*cf4091a3SMatthew G. Knepley break; 745*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 746*cf4091a3SMatthew G. Knepley switch (ct) { 747*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 748*cf4091a3SMatthew G. Knepley *onew = tquad_seg_o[(po+2)*4+o+2]; 749*cf4091a3SMatthew G. Knepley break; 750*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 751*cf4091a3SMatthew G. Knepley *onew = tquad_tquad_o[(po+2)*4+o+2]; 752*cf4091a3SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 753*cf4091a3SMatthew G. Knepley break; 754*cf4091a3SMatthew G. Knepley default: break; 755*cf4091a3SMatthew G. Knepley } 756*cf4091a3SMatthew G. Knepley break; 757*cf4091a3SMatthew G. Knepley default: 758*cf4091a3SMatthew G. Knepley ierr = DMPlexCellRefinerMapSubcells_None(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 759*cf4091a3SMatthew G. Knepley } 760*cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 761*cf4091a3SMatthew G. Knepley } 762*cf4091a3SMatthew G. Knepley 763412e9a14SMatthew G. Knepley /*@ 764412e9a14SMatthew G. Knepley DMPlexCellRefinerRefine - Return a description of the refinement for a given cell type 765412e9a14SMatthew G. Knepley 766412e9a14SMatthew G. Knepley Input Parameter: 767412e9a14SMatthew G. Knepley . source - The cell type for a source point 768412e9a14SMatthew G. Knepley 769412e9a14SMatthew G. Knepley Output Parameter: 770412e9a14SMatthew G. Knepley + Nt - The number of cell types generated by refinement 771412e9a14SMatthew G. Knepley . target - The cell types generated 772412e9a14SMatthew G. Knepley . size - The number of subcells of each type, ordered by dimension 773412e9a14SMatthew G. Knepley . cone - A list of the faces for each subcell of the same type as source 774412e9a14SMatthew G. Knepley - ornt - A list of the face orientations for each subcell of the same type as source 775412e9a14SMatthew G. Knepley 776412e9a14SMatthew G. Knepley Note: The cone array gives the cone of each subcell listed by the first three outputs. For the each cone point, we 777412e9a14SMatthew G. Knepley need the cell type, point identifier, and orientation within the subcell. The orientation is with respect to the canonical 778412e9a14SMatthew G. Knepley division (described in these outputs) of the cell in the original mesh. The point identifier is given by 779412e9a14SMatthew G. Knepley $ the number of cones to be taken, or 0 for the current cell 780412e9a14SMatthew G. Knepley $ the cell cone point number at each level from which it is subdivided 781412e9a14SMatthew G. Knepley $ the replica number r of the subdivision. 782412e9a14SMatthew G. Knepley The orientation is with respect to the canonical cone orientation. For example, the prescription for edge division is 783412e9a14SMatthew G. Knepley $ Nt = 2 784412e9a14SMatthew G. Knepley $ target = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT} 785412e9a14SMatthew G. Knepley $ size = {1, 2} 786412e9a14SMatthew G. Knepley $ cone = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, DM_POLYTOPE_POINT, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0} 787412e9a14SMatthew G. Knepley $ ornt = { 0, 0, 0, 0} 788412e9a14SMatthew G. Knepley 789412e9a14SMatthew G. Knepley Level: developer 790412e9a14SMatthew G. Knepley 79196ca5757SLisandro Dalcin .seealso: DMPlexCellRefinerCreate(), DMPlexRefineUniform() 792412e9a14SMatthew G. Knepley @*/ 793412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerRefine(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 794412e9a14SMatthew G. Knepley { 795412e9a14SMatthew G. Knepley PetscErrorCode ierr; 796412e9a14SMatthew G. Knepley 797412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 798412e9a14SMatthew G. Knepley ierr = (*cr->ops->refine)(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 799412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 800412e9a14SMatthew G. Knepley } 801412e9a14SMatthew G. Knepley 802*cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_None(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 803*cf4091a3SMatthew G. Knepley { 804*cf4091a3SMatthew G. Knepley static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT}; 805*cf4091a3SMatthew G. Knepley static PetscInt vertexS[] = {1}; 806*cf4091a3SMatthew G. Knepley static PetscInt vertexC[] = {0}; 807*cf4091a3SMatthew G. Knepley static PetscInt vertexO[] = {0}; 808*cf4091a3SMatthew G. Knepley static DMPolytopeType edgeT[] = {DM_POLYTOPE_SEGMENT}; 809*cf4091a3SMatthew G. Knepley static PetscInt edgeS[] = {1}; 810*cf4091a3SMatthew G. Knepley static PetscInt edgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 811*cf4091a3SMatthew G. Knepley static PetscInt edgeO[] = {0, 0}; 812*cf4091a3SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR}; 813*cf4091a3SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 814*cf4091a3SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 815*cf4091a3SMatthew G. Knepley static PetscInt tedgeO[] = {0, 0}; 816*cf4091a3SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_TRIANGLE}; 817*cf4091a3SMatthew G. Knepley static PetscInt triS[] = {1}; 818*cf4091a3SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0}; 819*cf4091a3SMatthew G. Knepley static PetscInt triO[] = {0, 0, 0}; 820*cf4091a3SMatthew G. Knepley static DMPolytopeType quadT[] = {DM_POLYTOPE_QUADRILATERAL}; 821*cf4091a3SMatthew G. Knepley static PetscInt quadS[] = {1}; 822*cf4091a3SMatthew G. Knepley static PetscInt quadC[] = {DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0}; 823*cf4091a3SMatthew G. Knepley static PetscInt quadO[] = {0, 0, 0, 0}; 824*cf4091a3SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_SEG_PRISM_TENSOR}; 825*cf4091a3SMatthew G. Knepley static PetscInt tquadS[] = {1}; 826*cf4091a3SMatthew G. Knepley static PetscInt tquadC[] = {DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0}; 827*cf4091a3SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 0, 0}; 828*cf4091a3SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_TETRAHEDRON}; 829*cf4091a3SMatthew G. Knepley static PetscInt tetS[] = {1}; 830*cf4091a3SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 1, 3, 0}; 831*cf4091a3SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 0, 0}; 832*cf4091a3SMatthew G. Knepley static DMPolytopeType hexT[] = {DM_POLYTOPE_HEXAHEDRON}; 833*cf4091a3SMatthew G. Knepley static PetscInt hexS[] = {1}; 834*cf4091a3SMatthew G. Knepley static PetscInt hexC[] = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, 835*cf4091a3SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0, DM_POLYTOPE_QUADRILATERAL, 1, 5, 0}; 836*cf4091a3SMatthew G. Knepley static PetscInt hexO[] = {0, 0, 0, 0, 0, 0}; 837*cf4091a3SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_TRI_PRISM}; 838*cf4091a3SMatthew G. Knepley static PetscInt tripS[] = {1}; 839*cf4091a3SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, 840*cf4091a3SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0}; 841*cf4091a3SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 0, 0, 0}; 842*cf4091a3SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_TRI_PRISM_TENSOR}; 843*cf4091a3SMatthew G. Knepley static PetscInt ttripS[] = {1}; 844*cf4091a3SMatthew G. Knepley static PetscInt ttripC[] = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, 845*cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0}; 846*cf4091a3SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 0, 0, 0}; 847*cf4091a3SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_QUAD_PRISM_TENSOR}; 848*cf4091a3SMatthew G. Knepley static PetscInt tquadpS[] = {1}; 849*cf4091a3SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, 850*cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 0}; 851*cf4091a3SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 0, 0, 0, 0}; 852*cf4091a3SMatthew G. Knepley 853*cf4091a3SMatthew G. Knepley PetscFunctionBegin; 854*cf4091a3SMatthew G. Knepley switch (source) { 855*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT: *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break; 856*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nt = 1; *target = edgeT; *size = edgeS; *cone = edgeC; *ornt = edgeO; break; 857*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 858*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 1; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 859*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nt = 1; *target = quadT; *size = quadS; *cone = quadC; *ornt = quadO; break; 860*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 1; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 861*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 1; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 862*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nt = 1; *target = hexT; *size = hexS; *cone = hexC; *ornt = hexO; break; 863*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 1; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 864*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 1; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 865*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 1; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 866*cf4091a3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 867*cf4091a3SMatthew G. Knepley } 868*cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 869*cf4091a3SMatthew G. Knepley } 870*cf4091a3SMatthew G. Knepley 871412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Regular(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 872412e9a14SMatthew G. Knepley { 873412e9a14SMatthew G. Knepley /* All vertices remain in the refined mesh */ 874412e9a14SMatthew G. Knepley static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT}; 875412e9a14SMatthew G. Knepley static PetscInt vertexS[] = {1}; 876412e9a14SMatthew G. Knepley static PetscInt vertexC[] = {0}; 877412e9a14SMatthew G. Knepley static PetscInt vertexO[] = {0}; 878412e9a14SMatthew G. Knepley /* Split all edges with a new vertex, making two new 2 edges 879412e9a14SMatthew G. Knepley 0--0--0--1--1 880412e9a14SMatthew G. Knepley */ 881412e9a14SMatthew G. Knepley static DMPolytopeType edgeT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT}; 882412e9a14SMatthew G. Knepley static PetscInt edgeS[] = {1, 2}; 883412e9a14SMatthew G. Knepley static PetscInt edgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, DM_POLYTOPE_POINT, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 884412e9a14SMatthew G. Knepley static PetscInt edgeO[] = { 0, 0, 0, 0}; 885412e9a14SMatthew G. Knepley /* Do not split tensor edges */ 886412e9a14SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR}; 887412e9a14SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 888412e9a14SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 889412e9a14SMatthew G. Knepley static PetscInt tedgeO[] = { 0, 0}; 890412e9a14SMatthew G. Knepley /* Add 3 edges inside every triangle, making 4 new triangles. 89175d3a19aSMatthew G. Knepley 2 89275d3a19aSMatthew G. Knepley |\ 89375d3a19aSMatthew G. Knepley | \ 89475d3a19aSMatthew G. Knepley | \ 895412e9a14SMatthew G. Knepley 0 1 89675d3a19aSMatthew G. Knepley | C \ 89775d3a19aSMatthew G. Knepley | \ 89875d3a19aSMatthew G. Knepley | \ 89975d3a19aSMatthew G. Knepley 2---1---1 90075d3a19aSMatthew G. Knepley |\ D / \ 901412e9a14SMatthew G. Knepley 1 2 0 0 90275d3a19aSMatthew G. Knepley |A \ / B \ 903412e9a14SMatthew G. Knepley 0-0-0---1---1 90475d3a19aSMatthew G. Knepley */ 905412e9a14SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE}; 906412e9a14SMatthew G. Knepley static PetscInt triS[] = {3, 4}; 907412e9a14SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 908412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 1, 2, 0, 909412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 0, 0, 910412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 911412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 0, 912412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, 913412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2}; 914412e9a14SMatthew G. Knepley static PetscInt triO[] = {0, 0, 915412e9a14SMatthew G. Knepley 0, 0, 916412e9a14SMatthew G. Knepley 0, 0, 917412e9a14SMatthew G. Knepley 0, -2, 0, 918412e9a14SMatthew G. Knepley 0, 0, -2, 919412e9a14SMatthew G. Knepley -2, 0, 0, 920412e9a14SMatthew G. Knepley 0, 0, 0}; 921412e9a14SMatthew G. Knepley /* Add a vertex in the center of each quadrilateral, and 4 edges inside, making 4 new quads. 922412e9a14SMatthew G. Knepley 3----1----2----0----2 923412e9a14SMatthew G. Knepley | | | 924412e9a14SMatthew G. Knepley 0 D 2 C 1 925412e9a14SMatthew G. Knepley | | | 926412e9a14SMatthew G. Knepley 3----3----0----1----1 927412e9a14SMatthew G. Knepley | | | 928412e9a14SMatthew G. Knepley 1 A 0 B 0 929412e9a14SMatthew G. Knepley | | | 930412e9a14SMatthew G. Knepley 0----0----0----1----1 931412e9a14SMatthew G. Knepley */ 932412e9a14SMatthew G. Knepley static DMPolytopeType quadT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 933412e9a14SMatthew G. Knepley static PetscInt quadS[] = {1, 4, 4}; 934412e9a14SMatthew G. Knepley static PetscInt quadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 935412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 936412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 937412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 938412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, 939412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 940412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, 941412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0}; 942412e9a14SMatthew G. Knepley static PetscInt quadO[] = {0, 0, 943412e9a14SMatthew G. Knepley 0, 0, 944412e9a14SMatthew G. Knepley 0, 0, 945412e9a14SMatthew G. Knepley 0, 0, 946412e9a14SMatthew G. Knepley 0, 0, -2, 0, 947412e9a14SMatthew G. Knepley 0, 0, 0, -2, 948412e9a14SMatthew G. Knepley -2, 0, 0, 0, 949412e9a14SMatthew G. Knepley 0, -2, 0, 0}; 950412e9a14SMatthew G. Knepley /* Add 1 edge inside every tensor quad, making 2 new tensor quads 951412e9a14SMatthew G. Knepley 2----2----1----3----3 952412e9a14SMatthew G. Knepley | | | 953412e9a14SMatthew G. Knepley | | | 954412e9a14SMatthew G. Knepley | | | 955412e9a14SMatthew G. Knepley 4 A 6 B 5 956412e9a14SMatthew G. Knepley | | | 957412e9a14SMatthew G. Knepley | | | 958412e9a14SMatthew G. Knepley | | | 959412e9a14SMatthew G. Knepley 0----0----0----1----1 960412e9a14SMatthew G. Knepley */ 961412e9a14SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR}; 962412e9a14SMatthew G. Knepley static PetscInt tquadS[] = {1, 2}; 963412e9a14SMatthew G. Knepley static PetscInt tquadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 964412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0, 965412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0}; 966412e9a14SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 967412e9a14SMatthew G. Knepley 0, 0, 0, 0, 968412e9a14SMatthew G. Knepley 0, 0, 0, 0}; 969412e9a14SMatthew G. Knepley /* Add 1 edge and 8 triangles inside every cell, making 8 new tets 970412e9a14SMatthew G. Knepley The vertices of our reference tet are [(-1, -1, -1), (-1, 1, -1), (1, -1, -1), (-1, -1, 1)], which we call [v0, v1, v2, v3]. The first 971412e9a14SMatthew G. Knepley three edges are [v0, v1], [v1, v2], [v2, v0] called e0, e1, and e2, and then three edges to the top point [v0, v3], [v1, v3], [v2, v3] 972412e9a14SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 973412e9a14SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 974412e9a14SMatthew G. Knepley The first four tets just cut off the corners, using the replica notation for new vertices, 975412e9a14SMatthew G. Knepley [v0, (e0, 0), (e2, 0), (e3, 0)] 976412e9a14SMatthew G. Knepley [(e0, 0), v1, (e1, 0), (e4, 0)] 977412e9a14SMatthew G. Knepley [(e2, 0), (e1, 0), v2, (e5, 0)] 978412e9a14SMatthew G. Knepley [(e3, 0), (e4, 0), (e5, 0), v3 ] 979412e9a14SMatthew G. Knepley The next four tets match a vertex to the newly created faces from cutting off those first tets. 980412e9a14SMatthew G. Knepley [(e2, 0), (e3, 0), (e0, 0), (e5, 0)] 981412e9a14SMatthew G. Knepley [(e4, 0), (e1, 0), (e0, 0), (e5, 0)] 982412e9a14SMatthew G. Knepley [(e5, 0), (e0, 0), (e2, 0), (e1, 0)] 983412e9a14SMatthew G. Knepley [(e5, 0), (e0, 0), (e4, 0), (e3, 0)] 984412e9a14SMatthew G. Knepley We can see that a new edge is introduced in the cell [(e0, 0), (e5, 0)] which we call (-1, 0). The first four faces created are 985412e9a14SMatthew G. Knepley [(e2, 0), (e0, 0), (e3, 0)] 986412e9a14SMatthew G. Knepley [(e0, 0), (e1, 0), (e4, 0)] 987412e9a14SMatthew G. Knepley [(e2, 0), (e5, 0), (e1, 0)] 988412e9a14SMatthew G. Knepley [(e3, 0), (e4, 0), (e5, 0)] 989412e9a14SMatthew G. Knepley The next four, from the second group of tets, are 990412e9a14SMatthew G. Knepley [(e2, 0), (e0, 0), (e5, 0)] 991412e9a14SMatthew G. Knepley [(e4, 0), (e0, 0), (e5, 0)] 992412e9a14SMatthew G. Knepley [(e0, 0), (e1, 0), (e5, 0)] 993412e9a14SMatthew G. Knepley [(e5, 0), (e3, 0), (e0, 0)] 994412e9a14SMatthew G. Knepley I could write a program to generate these orientations by comparing the faces from GetRawFaces() with my existing table. 995412e9a14SMatthew G. Knepley */ 996412e9a14SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON}; 997412e9a14SMatthew G. Knepley static PetscInt tetS[] = {1, 8, 8}; 998412e9a14SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 2, 2, 1, 0, 999412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 2, 2, 1000412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 1, 1, 1001412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 1, 0, 1, 1002412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 2, 1, 1003412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1004412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, 1005412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 0, 1006412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0, 0, 1007412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 0, 0, 1008412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 1, DM_POLYTOPE_TRIANGLE, 1, 1, 2, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 1, 3, 1, 1009412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 2, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 1, 2, 1, DM_POLYTOPE_TRIANGLE, 1, 3, 0, 1010412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 1, 1, 1, DM_POLYTOPE_TRIANGLE, 1, 2, 2, DM_POLYTOPE_TRIANGLE, 1, 3, 2, 1011412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 2, 3, DM_POLYTOPE_TRIANGLE, 0, 4, DM_POLYTOPE_TRIANGLE, 0, 7, 1012412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 1, 3, 3, DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 6, 1013412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 4, DM_POLYTOPE_TRIANGLE, 0, 6, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 1, 0, 3, 1014412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 7, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 1, 1, 3}; 1015412e9a14SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 1016412e9a14SMatthew G. Knepley 0, 0, 0, 1017412e9a14SMatthew G. Knepley 0, 0, 0, 1018412e9a14SMatthew G. Knepley 0, 0, 0, 1019412e9a14SMatthew G. Knepley 0, 0, 0, 1020412e9a14SMatthew G. Knepley 0, 0, -2, 1021412e9a14SMatthew G. Knepley 0, 0, -2, 1022412e9a14SMatthew G. Knepley 0, -2, -2, 1023412e9a14SMatthew G. Knepley 0, -2, 0, 1024412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1025412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1026412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1027412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1028412e9a14SMatthew G. Knepley -3, 0, 0, -2, 1029412e9a14SMatthew G. Knepley -2, 1, 0, 0, 1030412e9a14SMatthew G. Knepley -2, -2, -1, 2, 1031412e9a14SMatthew G. Knepley -2, 0, -2, 1}; 1032412e9a14SMatthew G. Knepley /* Add a vertex in the center of each cell, add 6 edges and 12 quads inside every cell, making 8 new hexes 1033412e9a14SMatthew G. Knepley The vertices of our reference hex are (-1, -1, -1), (-1, 1, -1), (1, 1, -1), (1, -1, -1), (-1, -1, 1), (1, -1, 1), (1, 1, 1), (-1, 1, 1) which we call [v0, v1, v2, v3, v4, v5, v6, v7]. The fours edges around the bottom [v0, v1], [v1, v2], [v2, v3], [v3, v0] are [e0, e1, e2, e3], and likewise around the top [v4, v5], [v5, v6], [v6, v7], [v7, v4] are [e4, e5, e6, e7]. Finally [v0, v4], [v1, v7], [v2, v6], [v3, v5] are [e9, e10, e11, e8]. The faces of a hex, given in DMPlexGetRawFaces_Internal(), oriented with outward normals, are 1034412e9a14SMatthew G. Knepley [v0, v1, v2, v3] f0 bottom 1035412e9a14SMatthew G. Knepley [v4, v5, v6, v7] f1 top 1036412e9a14SMatthew G. Knepley [v0, v3, v5, v4] f2 front 1037412e9a14SMatthew G. Knepley [v2, v1, v7, v6] f3 back 1038412e9a14SMatthew G. Knepley [v3, v2, v6, v5] f4 right 1039412e9a14SMatthew G. Knepley [v0, v4, v7, v1] f5 left 1040412e9a14SMatthew G. Knepley The eight hexes are divided into four on the bottom, and four on the top, 1041412e9a14SMatthew G. Knepley [v0, (e0, 0), (f0, 0), (e3, 0), (e9, 0), (f2, 0), (c0, 0), (f5, 0)] 1042412e9a14SMatthew G. Knepley [(e0, 0), v1, (e1, 0), (f0, 0), (f5, 0), (c0, 0), (f3, 0), (e10, 0)] 1043412e9a14SMatthew G. Knepley [(f0, 0), (e1, 0), v2, (e2, 0), (c0, 0), (f4, 0), (e11, 0), (f3, 0)] 1044412e9a14SMatthew G. Knepley [(e3, 0), (f0, 0), (e2, 0), v3, (f2, 0), (e8, 0), (f4, 0), (c0, 0)] 1045412e9a14SMatthew G. Knepley [(e9, 0), (f5, 0), (c0, 0), (f2, 0), v4, (e4, 0), (f1, 0), (e7, 0)] 1046412e9a14SMatthew G. Knepley [(f2, 0), (c0, 0), (f4, 0), (e8, 0), (e4, 0), v5, (e5, 0), (f1, 0)] 1047412e9a14SMatthew G. Knepley [(c0, 0), (f3, 0), (e11, 0), (f4, 0), (f1, 0), (e5, 0), v6, (e6, 0)] 1048412e9a14SMatthew G. Knepley [(f5, 0), (e10, 0), (f3, 0), (c0, 0), (e7, 0), (f1, 0), (e6, 0), v7] 1049412e9a14SMatthew G. Knepley The 6 internal edges will go from the faces to the central vertex. The 12 internal faces can be divided into groups of 4 by the plane on which they sit. First the faces on the x-y plane are, 1050412e9a14SMatthew G. Knepley [(e9, 0), (f2, 0), (c0, 0), (f5, 0)] 1051412e9a14SMatthew G. Knepley [(f5, 0), (c0, 0), (f3, 0), (e10, 0)] 1052412e9a14SMatthew G. Knepley [(c0, 0), (f4, 0), (e11, 0), (f3, 0)] 1053412e9a14SMatthew G. Knepley [(f2, 0), (e8, 0), (f4, 0), (c0, 0)] 1054412e9a14SMatthew G. Knepley and on the x-z plane, 1055412e9a14SMatthew G. Knepley [(f0, 0), (e0, 0), (f5, 0), (c0, 0)] 1056412e9a14SMatthew G. Knepley [(c0, 0), (f5, 0), (e7, 0), (f1, 0)] 1057412e9a14SMatthew G. Knepley [(f4, 0), (c0, 0), (f1, 0), (e5, 0)] 1058412e9a14SMatthew G. Knepley [(e2, 0), (f0, 0), (c0, 0), (f4, 0)] 1059412e9a14SMatthew G. Knepley and on the y-z plane, 1060412e9a14SMatthew G. Knepley [(e3, 0), (f2, 0), (c0, 0), (f0, 0)] 1061412e9a14SMatthew G. Knepley [(f2, 0), (e4, 0), (f1, 0), (c0, 0)] 1062412e9a14SMatthew G. Knepley [(c0, 0), (f1, 0), (e6, 0), (f3, 0)] 1063412e9a14SMatthew G. Knepley [(f0, 0), (c0, 0), (f3, 0), (e1, 0)] 1064412e9a14SMatthew G. Knepley */ 1065412e9a14SMatthew G. Knepley static DMPolytopeType hexT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1066412e9a14SMatthew G. Knepley static PetscInt hexS[] = {1, 6, 12, 8}; 1067412e9a14SMatthew G. Knepley static PetscInt hexC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1068412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1069412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1070412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1071412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0, 1072412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 5, 0, DM_POLYTOPE_POINT, 0, 0, 1073412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 1, 5, 0, 1074412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 5, 2, 1075412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 3, 1076412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 2, 1077412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 5, 3, DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 0, 0, 1078412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 1, 5, 1, DM_POLYTOPE_SEGMENT, 1, 1, 3, DM_POLYTOPE_SEGMENT, 0, 1, 1079412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 4, 2, 1080412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 0, 1081412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 0, 3, 1082412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 1083412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 3, 1084412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1, 1085412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 0, 4, DM_POLYTOPE_QUADRILATERAL, 0, 8, DM_POLYTOPE_QUADRILATERAL, 1, 5, 0, 1086412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 1, DM_POLYTOPE_QUADRILATERAL, 0, 1, DM_POLYTOPE_QUADRILATERAL, 0, 4, DM_POLYTOPE_QUADRILATERAL, 1, 3, 1, DM_POLYTOPE_QUADRILATERAL, 0, 11, DM_POLYTOPE_QUADRILATERAL, 1, 5, 3, 1087412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 2, DM_POLYTOPE_QUADRILATERAL, 0, 2, DM_POLYTOPE_QUADRILATERAL, 0, 7, DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 1, DM_POLYTOPE_QUADRILATERAL, 0, 11, 1088412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 3, DM_POLYTOPE_QUADRILATERAL, 0, 3, DM_POLYTOPE_QUADRILATERAL, 1, 2, 1, DM_POLYTOPE_QUADRILATERAL, 0, 7, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0, DM_POLYTOPE_QUADRILATERAL, 0, 8, 1089412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 3, DM_POLYTOPE_QUADRILATERAL, 0, 5, DM_POLYTOPE_QUADRILATERAL, 0, 9, DM_POLYTOPE_QUADRILATERAL, 1, 5, 1, 1090412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 0, 3, DM_POLYTOPE_QUADRILATERAL, 1, 1, 1, DM_POLYTOPE_QUADRILATERAL, 1, 2, 2, DM_POLYTOPE_QUADRILATERAL, 0, 6, DM_POLYTOPE_QUADRILATERAL, 1, 4, 3, DM_POLYTOPE_QUADRILATERAL, 0, 9, 1091412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 0, 2, DM_POLYTOPE_QUADRILATERAL, 1, 1, 2, DM_POLYTOPE_QUADRILATERAL, 0, 6, DM_POLYTOPE_QUADRILATERAL, 1, 3, 3, DM_POLYTOPE_QUADRILATERAL, 1, 4, 2, DM_POLYTOPE_QUADRILATERAL, 0, 10, 1092412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 1, 3, DM_POLYTOPE_QUADRILATERAL, 0, 5, DM_POLYTOPE_QUADRILATERAL, 1, 3, 2, DM_POLYTOPE_QUADRILATERAL, 0, 10, DM_POLYTOPE_QUADRILATERAL, 1, 5, 2}; 1093412e9a14SMatthew G. Knepley static PetscInt hexO[] = {0, 0, 1094412e9a14SMatthew G. Knepley 0, 0, 1095412e9a14SMatthew G. Knepley 0, 0, 1096412e9a14SMatthew G. Knepley 0, 0, 1097412e9a14SMatthew G. Knepley 0, 0, 1098412e9a14SMatthew G. Knepley 0, 0, 1099412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1100412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1101412e9a14SMatthew G. Knepley -2, -2, 0, 0, 1102412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1103412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1104412e9a14SMatthew G. Knepley -2, -2, 0, 0, 1105412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1106412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1107412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1108412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1109412e9a14SMatthew G. Knepley -2, -2, 0, 0, 1110412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1111412e9a14SMatthew G. Knepley 0, 0, 0, 0, -4, 0, 1112412e9a14SMatthew G. Knepley 0, 0, -1, 0, -4, 0, 1113412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1114412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 1115412e9a14SMatthew G. Knepley -4, 0, 0, 0, -4, 0, 1116412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, 0, 1117412e9a14SMatthew G. Knepley -4, 0, -1, 0, 0, 0, 1118412e9a14SMatthew G. Knepley -4, 0, -1, 0, -4, 0}; 1119412e9a14SMatthew G. Knepley /* Add 3 quads inside every triangular prism, making 4 new prisms. */ 1120412e9a14SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_TRI_PRISM}; 1121412e9a14SMatthew G. Knepley static PetscInt tripS[] = {3, 4, 6, 8}; 1122412e9a14SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 3, 0, 1123412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 1, 4, 0, 1124412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 1, 2, 0, 1125412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 4, 1, 1126412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 0, 1127412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, 1128412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 1129412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1130412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 4, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0, 1131412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 4, 0, 1132412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 2, 1133412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 4, 2, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 3, 2, 1134412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 4, 2, 1135412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 0, 2, DM_POLYTOPE_QUADRILATERAL, 1, 4, 1, 1136412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 2, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 2, 1, DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 0, 0, 1137412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_QUADRILATERAL, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 3, 1, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0, 1138412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_QUADRILATERAL, 0, 0, DM_POLYTOPE_QUADRILATERAL, 0, 1, DM_POLYTOPE_QUADRILATERAL, 0, 2, 1139412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 3, DM_POLYTOPE_QUADRILATERAL, 0, 5, DM_POLYTOPE_QUADRILATERAL, 1, 4, 2, 1140412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 1, 1, 1, DM_POLYTOPE_QUADRILATERAL, 1, 2, 2, DM_POLYTOPE_QUADRILATERAL, 1, 3, 3, DM_POLYTOPE_QUADRILATERAL, 0, 3, 1141412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 1, 1, 2, DM_POLYTOPE_QUADRILATERAL, 0, 4, DM_POLYTOPE_QUADRILATERAL, 1, 3, 2, DM_POLYTOPE_QUADRILATERAL, 1, 4, 3, 1142412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 1, 1, 3, DM_POLYTOPE_QUADRILATERAL, 0, 3, DM_POLYTOPE_QUADRILATERAL, 0, 4, DM_POLYTOPE_QUADRILATERAL, 0, 5}; 1143412e9a14SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 1144412e9a14SMatthew G. Knepley 0, 0, 1145412e9a14SMatthew G. Knepley 0, 0, 1146412e9a14SMatthew G. Knepley 0, -2, -2, 1147412e9a14SMatthew G. Knepley -2, 0, -2, 1148412e9a14SMatthew G. Knepley -2, -2, 0, 1149412e9a14SMatthew G. Knepley 0, 0, 0, 1150412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1151412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1152412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1153412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1154412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1155412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1156412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1157412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1158412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 1159412e9a14SMatthew G. Knepley 2, 0, 0, 0, 0, 1160412e9a14SMatthew G. Knepley -3, 0, 0, -1, 0, 1161412e9a14SMatthew G. Knepley -3, 0, 0, 0, -1, 1162412e9a14SMatthew G. Knepley -3, 0, -1, 0, 0, 1163412e9a14SMatthew G. Knepley -3, 0, 0, 0, 0}; 1164412e9a14SMatthew G. Knepley /* Add 3 tensor quads inside every tensor triangular prism, making 4 new prisms. 1165412e9a14SMatthew G. Knepley 2 1166412e9a14SMatthew G. Knepley |\ 1167412e9a14SMatthew G. Knepley | \ 1168412e9a14SMatthew G. Knepley | \ 1169412e9a14SMatthew G. Knepley 0---1 117075d3a19aSMatthew G. Knepley 1171412e9a14SMatthew G. Knepley 2 117275d3a19aSMatthew G. Knepley 1173412e9a14SMatthew G. Knepley 0 1 117475d3a19aSMatthew G. Knepley 1175412e9a14SMatthew G. Knepley 2 1176412e9a14SMatthew G. Knepley |\ 1177412e9a14SMatthew G. Knepley | \ 1178412e9a14SMatthew G. Knepley | \ 1179412e9a14SMatthew G. Knepley 0---1 1180412e9a14SMatthew G. Knepley */ 1181412e9a14SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_TRI_PRISM_TENSOR}; 1182412e9a14SMatthew G. Knepley static PetscInt ttripS[] = {3, 4}; 1183412e9a14SMatthew G. Knepley static PetscInt ttripC[] = {DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0, 1184412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 4, 0, 1185412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, 1186412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 2, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 1, 1187412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 1, DM_POLYTOPE_TRIANGLE, 1, 1, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 0, 1188412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 2, DM_POLYTOPE_TRIANGLE, 1, 1, 2, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0, 1189412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 3, DM_POLYTOPE_TRIANGLE, 1, 1, 3, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 2}; 1190412e9a14SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 0, 0, 1191412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1192412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1193412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1194412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1195412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 1196412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0}; 1197412e9a14SMatthew G. Knepley /* Add 1 edge and 4 tensor quads inside every tensor quad prism, making 4 new prisms. */ 1198412e9a14SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1199412e9a14SMatthew G. Knepley static PetscInt tquadpS[] = {1, 4, 4}; 1200412e9a14SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1201412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0, 1202412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0, 1203412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0, 1204412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 3, DM_POLYTOPE_SEGMENT, 1, 1, 3, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 5, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0, 1205412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 3, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 1, 1206412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 1, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 0, 1207412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 2, DM_POLYTOPE_QUADRILATERAL, 1, 1, 2, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 2, 1208412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 3, DM_POLYTOPE_QUADRILATERAL, 1, 1, 3, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 3, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 2, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 0}; 1209412e9a14SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 1210412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1211412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1212412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1213412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1214412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1215412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1216412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1217412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 121875d3a19aSMatthew G. Knepley 1219412e9a14SMatthew G. Knepley PetscFunctionBegin; 1220412e9a14SMatthew G. Knepley switch (source) { 1221412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break; 1222412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nt = 2; *target = edgeT; *size = edgeS; *cone = edgeC; *ornt = edgeO; break; 1223412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 1224412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 2; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1225412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nt = 3; *target = quadT; *size = quadS; *cone = quadC; *ornt = quadO; break; 1226412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 2; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 1227412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 3; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1228412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nt = 4; *target = hexT; *size = hexS; *cone = hexC; *ornt = hexO; break; 1229412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1230412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 2; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 1231412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 1232412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1233412e9a14SMatthew G. Knepley } 1234412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1235412e9a14SMatthew G. Knepley } 123675d3a19aSMatthew G. Knepley 123796ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerRefine_ToBox(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1238412e9a14SMatthew G. Knepley { 1239412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1240412e9a14SMatthew G. Knepley /* Change tensor edges to segments */ 1241412e9a14SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_SEGMENT}; 1242412e9a14SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 1243412e9a14SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 1244412e9a14SMatthew G. Knepley static PetscInt tedgeO[] = { 0, 0}; 1245412e9a14SMatthew G. Knepley /* Add 1 vertex, 3 edges inside every triangle, making 3 new quadrilaterals. 1246e5337592SStefano Zampini 2 1247e5337592SStefano Zampini |\ 1248e5337592SStefano Zampini | \ 1249e5337592SStefano Zampini | \ 1250e5337592SStefano Zampini | \ 1251412e9a14SMatthew G. Knepley 0 1 1252412e9a14SMatthew G. Knepley | \ 1253e5337592SStefano Zampini | \ 1254e5337592SStefano Zampini 2 1 1255e5337592SStefano Zampini |\ / \ 1256e5337592SStefano Zampini | 2 1 \ 1257e5337592SStefano Zampini | \ / \ 1258412e9a14SMatthew G. Knepley 1 | 0 1259e5337592SStefano Zampini | 0 \ 1260e5337592SStefano Zampini | | \ 1261412e9a14SMatthew G. Knepley | | \ 1262412e9a14SMatthew G. Knepley 0-0-0-----1-----1 1263e5337592SStefano Zampini */ 1264412e9a14SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 1265412e9a14SMatthew G. Knepley static PetscInt triS[] = {1, 3, 3}; 1266412e9a14SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1267412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1268412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1269412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 1270412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1271412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0}; 1272412e9a14SMatthew G. Knepley static PetscInt triO[] = {0, 0, 1273412e9a14SMatthew G. Knepley 0, 0, 1274412e9a14SMatthew G. Knepley 0, 0, 1275412e9a14SMatthew G. Knepley 0, 0, -2, 0, 1276412e9a14SMatthew G. Knepley 0, 0, 0, -2, 1277412e9a14SMatthew G. Knepley 0, -2, 0, 0}; 1278412e9a14SMatthew G. Knepley /* Add 1 edge inside every tensor quad, making 2 new quadrilaterals 1279412e9a14SMatthew G. Knepley 2----2----1----3----3 12804330a3fcSStefano Zampini | | | 12814330a3fcSStefano Zampini | | | 12824330a3fcSStefano Zampini | | | 1283412e9a14SMatthew G. Knepley 4 A 6 B 5 12844330a3fcSStefano Zampini | | | 1285412e9a14SMatthew G. Knepley | | | 1286412e9a14SMatthew G. Knepley | | | 1287412e9a14SMatthew G. Knepley 0----0----0----1----1 12884330a3fcSStefano Zampini */ 1289412e9a14SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 1290412e9a14SMatthew G. Knepley static PetscInt tquadS[] = {1, 2}; 1291412e9a14SMatthew G. Knepley static PetscInt tquadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1292412e9a14SMatthew G. Knepley /* TODO Fix these */ 1293412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1294412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0, 0}; 1295412e9a14SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 1296412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1297412e9a14SMatthew G. Knepley 0, 0, -2, -2}; 1298412e9a14SMatthew G. Knepley /* Add 6 triangles inside every cell, making 4 new hexs 1299412e9a14SMatthew G. Knepley TODO: Need different SubcellMap(). Need to make a struct with the function pointers in it 1300412e9a14SMatthew G. Knepley The vertices of our reference tet are [(-1, -1, -1), (-1, 1, -1), (1, -1, -1), (-1, -1, 1)], which we call [v0, v1, v2, v3]. The first 1301412e9a14SMatthew G. Knepley three edges are [v0, v1], [v1, v2], [v2, v0] called e0, e1, and e2, and then three edges to the top point [v0, v3], [v1, v3], [v2, v3] 1302412e9a14SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 1303412e9a14SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 1304412e9a14SMatthew G. Knepley We make a new hex in each corner 1305412e9a14SMatthew G. Knepley [v0, (e0, 0), (f0, 0), (e2, 0), (e3, 0), (f2, 0), (c0, 0), (f1, 0)] 1306412e9a14SMatthew G. Knepley [v1, (e4, 0), (f3, 0), (e1, 0), (e0, 0), (f0, 0), (c0, 0), (f1, 0)] 1307412e9a14SMatthew G. Knepley [v2, (e1, 0), (f3, 0), (e5, 0), (e2, 0), (f2, 0), (c0, 0), (f0, 0)] 1308412e9a14SMatthew G. Knepley [v3, (e4, 0), (f1, 0), (e3, 0), (e5, 0), (f2, 0), (c0, 0), (f3, 0)] 1309412e9a14SMatthew G. Knepley We create a new face for each edge 1310412e9a14SMatthew G. Knepley [(e3, 0), (f2, 0), (c0, 0), (f1, 0)] 1311412e9a14SMatthew G. Knepley [(f0, 0), (e0, 0), (f1, 0), (c0, 0)] 1312412e9a14SMatthew G. Knepley [(e2, 0), (f0, 0), (c0, 0), (f2, 0)] 1313412e9a14SMatthew G. Knepley [(f3, 0), (e4, 0), (f1, 0), (c0, 0)] 1314412e9a14SMatthew G. Knepley [(e1, 0), (f3, 0), (c0, 0), (f0, 0)] 1315412e9a14SMatthew G. Knepley [(e5, 0), (f3, 0), (c0, 0), (f2, 0)] 1316412e9a14SMatthew G. Knepley I could write a program to generate these from the first hex by acting with the symmetry group to take one subcell into another. 131775d3a19aSMatthew G. Knepley */ 1318412e9a14SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1319412e9a14SMatthew G. Knepley static PetscInt tetS[] = {1, 4, 6, 4}; 1320412e9a14SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1321412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1322412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1323412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1324412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, 1325412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1326412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1327412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 3, 1328412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1, 1329412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 1330412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 0, 1, DM_POLYTOPE_QUADRILATERAL, 0, 2, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, 1331412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 3, 1, DM_POLYTOPE_QUADRILATERAL, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 0, 1, DM_POLYTOPE_QUADRILATERAL, 0, 3, DM_POLYTOPE_QUADRILATERAL, 0, 4, DM_POLYTOPE_QUADRILATERAL, 1, 1, 2, 1332412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 0, 2, DM_POLYTOPE_QUADRILATERAL, 1, 2, 1, DM_POLYTOPE_QUADRILATERAL, 0, 4, DM_POLYTOPE_QUADRILATERAL, 0, 5, DM_POLYTOPE_QUADRILATERAL, 1, 0, 2, 1333412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 1, 1, DM_POLYTOPE_QUADRILATERAL, 0, 5, DM_POLYTOPE_QUADRILATERAL, 1, 2, 2, DM_POLYTOPE_QUADRILATERAL, 0, 3, DM_POLYTOPE_QUADRILATERAL, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 3, 2}; 1334412e9a14SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 1335412e9a14SMatthew G. Knepley 0, 0, 1336412e9a14SMatthew G. Knepley 0, 0, 1337412e9a14SMatthew G. Knepley 0, 0, 1338412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1339412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1340412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1341412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1342412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1343412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1344412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 1345412e9a14SMatthew G. Knepley 1, -1, 1, 0, 0, 3, 1346412e9a14SMatthew G. Knepley 0, -4, 1, -1, 0, 3, 1347412e9a14SMatthew G. Knepley 1, -4, 3, -2, -4, 3}; 1348412e9a14SMatthew G. Knepley /* Add 3 quads inside every triangular prism, making 4 new prisms. */ 1349412e9a14SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1350412e9a14SMatthew G. Knepley static PetscInt tripS[] = {1, 5, 9, 6}; 1351412e9a14SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1352412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1353412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1354412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1355412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0, 1356412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 1, 1357412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, 1358412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, 1359412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1360412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 0, 1361412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 0, 1362412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 2, 1363412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 3, 2, 1364412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 4, 2, 1365412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 0, 5, DM_POLYTOPE_QUADRILATERAL, 0, 3, DM_POLYTOPE_QUADRILATERAL, 1, 4, 1, 1366412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 2, DM_POLYTOPE_QUADRILATERAL, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 2, 1, DM_POLYTOPE_QUADRILATERAL, 0, 4, DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 0, 3, 1367412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 1, DM_POLYTOPE_QUADRILATERAL, 0, 2, DM_POLYTOPE_QUADRILATERAL, 0, 5, DM_POLYTOPE_QUADRILATERAL, 1, 3, 1, DM_POLYTOPE_QUADRILATERAL, 0, 4, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0, 1368412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 3, DM_POLYTOPE_QUADRILATERAL, 0, 8, DM_POLYTOPE_QUADRILATERAL, 0, 6, DM_POLYTOPE_QUADRILATERAL, 1, 4, 2, 1369412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 1, 1, DM_POLYTOPE_QUADRILATERAL, 1, 2, 2, DM_POLYTOPE_QUADRILATERAL, 0, 7, DM_POLYTOPE_QUADRILATERAL, 1, 3, 3, DM_POLYTOPE_QUADRILATERAL, 0, 6, 1370412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 0, 2, DM_POLYTOPE_QUADRILATERAL, 1, 1, 2, DM_POLYTOPE_QUADRILATERAL, 0, 8, DM_POLYTOPE_QUADRILATERAL, 1, 3, 2, DM_POLYTOPE_QUADRILATERAL, 0, 7, DM_POLYTOPE_QUADRILATERAL, 1, 4, 3}; 1371412e9a14SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 1372412e9a14SMatthew G. Knepley 0, 0, 1373412e9a14SMatthew G. Knepley 0, 0, 1374412e9a14SMatthew G. Knepley 0, 0, 1375412e9a14SMatthew G. Knepley 0, 0, 1376412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1377412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1378412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1379412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1380412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1381412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1382412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1383412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1384412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1385412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1, 1386412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -4, 1387412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1, 1388412e9a14SMatthew G. Knepley -4, 0, 0, -1, 0, 1, 1389412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, -4, 1390412e9a14SMatthew G. Knepley -4, 0, 0, 0, -1, 1}; 1391412e9a14SMatthew G. Knepley /* Add 3 tensor quads inside every tensor triangular prism, making 4 new tensor triangular prisms. 1392412e9a14SMatthew G. Knepley 2 1393412e9a14SMatthew G. Knepley |\ 1394412e9a14SMatthew G. Knepley | \ 1395412e9a14SMatthew G. Knepley | \ 1396412e9a14SMatthew G. Knepley 0---1 139775d3a19aSMatthew G. Knepley 1398412e9a14SMatthew G. Knepley 2 139975d3a19aSMatthew G. Knepley 1400412e9a14SMatthew G. Knepley 0 1 140175d3a19aSMatthew G. Knepley 1402412e9a14SMatthew G. Knepley 2 1403412e9a14SMatthew G. Knepley |\ 1404412e9a14SMatthew G. Knepley | \ 1405412e9a14SMatthew G. Knepley | \ 1406412e9a14SMatthew G. Knepley 0---1 140775d3a19aSMatthew G. Knepley */ 1408412e9a14SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1409412e9a14SMatthew G. Knepley static PetscInt ttripS[] = {1, 3, 3}; 1410412e9a14SMatthew G. Knepley static PetscInt ttripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1411412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0, 1412412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0, 1413412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0, 1414412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 2, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 1, 1415412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 1, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 0, 1416412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 2, DM_POLYTOPE_QUADRILATERAL, 1, 1, 2, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 2, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0}; 1417412e9a14SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 1418412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1419412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1420412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1421412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1422412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1423412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 1424412e9a14SMatthew G. Knepley /* TODO Add 3 quads inside every tensor triangular prism, making 4 new triangular prisms. 1425412e9a14SMatthew G. Knepley 2 1426412e9a14SMatthew G. Knepley |\ 1427412e9a14SMatthew G. Knepley | \ 1428412e9a14SMatthew G. Knepley | \ 1429412e9a14SMatthew G. Knepley 0---1 143075d3a19aSMatthew G. Knepley 1431412e9a14SMatthew G. Knepley 2 143275d3a19aSMatthew G. Knepley 1433412e9a14SMatthew G. Knepley 0 1 143475d3a19aSMatthew G. Knepley 1435412e9a14SMatthew G. Knepley 2 1436412e9a14SMatthew G. Knepley |\ 1437412e9a14SMatthew G. Knepley | \ 1438412e9a14SMatthew G. Knepley | \ 1439412e9a14SMatthew G. Knepley 0---1 1440a97b51b8SMatthew G. Knepley */ 1441412e9a14SMatthew G. Knepley static DMPolytopeType ctripT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1442412e9a14SMatthew G. Knepley static PetscInt ctripS[] = {1, 3, 3}; 1443412e9a14SMatthew G. Knepley static PetscInt ctripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1444412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1445412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0, 1446412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 4, 0, 1447412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 0, 2, DM_POLYTOPE_QUADRILATERAL, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 1, 1448412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 1, 1, DM_POLYTOPE_QUADRILATERAL, 1, 2, 1, DM_POLYTOPE_QUADRILATERAL, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 0, 0, 1449412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 2, DM_POLYTOPE_QUADRILATERAL, 1, 1, 2, DM_POLYTOPE_QUADRILATERAL, 0, 2, DM_POLYTOPE_QUADRILATERAL, 1, 3, 1, DM_POLYTOPE_QUADRILATERAL, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0}; 1450412e9a14SMatthew G. Knepley static PetscInt ctripO[] = {0, 0, 1451412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1452412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1453412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1454412e9a14SMatthew G. Knepley -4, 0, 0, -1, 0, 1, 1455412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, -4, 1456412e9a14SMatthew G. Knepley -4, 0, 0, 0, -1, 1}; 1457412e9a14SMatthew G. Knepley /* Add 1 edge and 4 quads inside every tensor quad prism, making 4 new hexahedra. */ 1458412e9a14SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1459412e9a14SMatthew G. Knepley static PetscInt tquadpS[] = {1, 4, 4}; 1460412e9a14SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1461412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0, 1462412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0, 1463412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0, 1464412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 3, DM_POLYTOPE_SEGMENT, 1, 1, 3, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 5, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0, 1465412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 3, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 1, 1466412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 1, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 0, 1467412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 2, DM_POLYTOPE_QUADRILATERAL, 1, 1, 2, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 2, 1468412e9a14SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 3, DM_POLYTOPE_QUADRILATERAL, 1, 1, 3, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 3, DM_POLYTOPE_SEG_PRISM_TENSOR, 0, 2, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 0}; 1469412e9a14SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 1470412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1471412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1472412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1473412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1474412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1475412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1476412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1477412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 1478412e9a14SMatthew G. Knepley PetscBool convertTensor = PETSC_TRUE; 1479a97b51b8SMatthew G. Knepley 1480412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 1481412e9a14SMatthew G. Knepley if (convertTensor) { 1482412e9a14SMatthew G. Knepley switch (source) { 1483412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1484412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1485412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1486412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1487412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1488a97b51b8SMatthew G. Knepley break; 1489412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 1490412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 2; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 1491412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 3; *target = ctripT; *size = ctripS; *cone = ctripC; *ornt = ctripO; break; 1492412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 1493412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1494412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1495412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1496412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1497b5da9499SMatthew G. Knepley } 1498b5da9499SMatthew G. Knepley } else { 1499412e9a14SMatthew G. Knepley switch (source) { 1500412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1501412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1502412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1503412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1504412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1505412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1506412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1507412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1508b5da9499SMatthew G. Knepley break; 1509412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1510412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1511412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1512412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 3; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 1513412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 151427fcede3SMatthew G. Knepley } 151575d3a19aSMatthew G. Knepley } 151675d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 151775d3a19aSMatthew G. Knepley } 151875d3a19aSMatthew G. Knepley 1519412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 152075d3a19aSMatthew G. Knepley { 1521412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1522412e9a14SMatthew G. Knepley 1523412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 1524412e9a14SMatthew G. Knepley switch (source) { 1525412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1526412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1527412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1528412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1529412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 1530412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1531412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 1532412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1533412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1534412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1535412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1536412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1537412e9a14SMatthew G. Knepley break; 1538412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1539412e9a14SMatthew G. Knepley } 1540412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1541412e9a14SMatthew G. Knepley } 1542412e9a14SMatthew G. Knepley 1543*cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Alfeld2D(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1544*cf4091a3SMatthew G. Knepley { 1545*cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 1546*cf4091a3SMatthew G. Knepley /* Add 1 vertex, 3 edges inside every triangle, making 3 new triangles. 1547*cf4091a3SMatthew G. Knepley 2 1548*cf4091a3SMatthew G. Knepley |\ 1549*cf4091a3SMatthew G. Knepley |\\ 1550*cf4091a3SMatthew G. Knepley | |\ 1551*cf4091a3SMatthew G. Knepley | \ \ 1552*cf4091a3SMatthew G. Knepley | | \ 1553*cf4091a3SMatthew G. Knepley | \ \ 1554*cf4091a3SMatthew G. Knepley | | \ 1555*cf4091a3SMatthew G. Knepley 2 \ \ 1556*cf4091a3SMatthew G. Knepley | | 1 1557*cf4091a3SMatthew G. Knepley | 2 \ 1558*cf4091a3SMatthew G. Knepley | | \ 1559*cf4091a3SMatthew G. Knepley | /\ \ 1560*cf4091a3SMatthew G. Knepley | 0 1 | 1561*cf4091a3SMatthew G. Knepley | / \ | 1562*cf4091a3SMatthew G. Knepley |/ \| 1563*cf4091a3SMatthew G. Knepley 0---0----1 1564*cf4091a3SMatthew G. Knepley */ 1565*cf4091a3SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE}; 1566*cf4091a3SMatthew G. Knepley static PetscInt triS[] = {1, 3, 3}; 1567*cf4091a3SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1568*cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 2, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1569*cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 2, 2, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1570*cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1571*cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, 1572*cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2}; 1573*cf4091a3SMatthew G. Knepley static PetscInt triO[] = {0, 0, 1574*cf4091a3SMatthew G. Knepley 0, 0, 1575*cf4091a3SMatthew G. Knepley 0, 0, 1576*cf4091a3SMatthew G. Knepley 0, 0, -2, 1577*cf4091a3SMatthew G. Knepley 0, 0, -2, 1578*cf4091a3SMatthew G. Knepley 0, 0, -2}; 1579*cf4091a3SMatthew G. Knepley 1580*cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 1581*cf4091a3SMatthew G. Knepley switch (source) { 1582*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT: 1583*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1584*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1585*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1586*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1587*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 1588*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1589*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1590*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 1591*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1592*cf4091a3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1593*cf4091a3SMatthew G. Knepley break; 1594*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1595*cf4091a3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1596*cf4091a3SMatthew G. Knepley } 1597*cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 1598*cf4091a3SMatthew G. Knepley } 1599*cf4091a3SMatthew G. Knepley 1600*cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Alfeld3D(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1601*cf4091a3SMatthew G. Knepley { 1602*cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 1603*cf4091a3SMatthew G. Knepley /* Add 6 triangles inside every cell, making 4 new tets 1604*cf4091a3SMatthew G. Knepley The vertices of our reference tet are [(-1, -1, -1), (-1, 1, -1), (1, -1, -1), (-1, -1, 1)], which we call [v0, v1, v2, v3]. The first 1605*cf4091a3SMatthew G. Knepley three edges are [v0, v1], [v1, v2], [v2, v0] called e0, e1, and e2, and then three edges to the top point [v0, v3], [v1, v3], [v2, v3] 1606*cf4091a3SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 1607*cf4091a3SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 1608*cf4091a3SMatthew G. Knepley We make a new tet on each face 1609*cf4091a3SMatthew G. Knepley [v0, v1, v2, (c0, 0)] 1610*cf4091a3SMatthew G. Knepley [v0, v3, v1, (c0, 0)] 1611*cf4091a3SMatthew G. Knepley [v0, v2, v3, (c0, 0)] 1612*cf4091a3SMatthew G. Knepley [v2, v1, v3, (c0, 0)] 1613*cf4091a3SMatthew G. Knepley We create a new face for each edge 1614*cf4091a3SMatthew G. Knepley [v0, (c0, 0), v1 ] 1615*cf4091a3SMatthew G. Knepley [v0, v2, (c0, 0)] 1616*cf4091a3SMatthew G. Knepley [v2, v1, (c0, 0)] 1617*cf4091a3SMatthew G. Knepley [v0, (c0, 0), v3 ] 1618*cf4091a3SMatthew G. Knepley [v1, v3, (c0, 0)] 1619*cf4091a3SMatthew G. Knepley [v3, v2, (c0, 0)] 1620*cf4091a3SMatthew G. Knepley */ 1621*cf4091a3SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON}; 1622*cf4091a3SMatthew G. Knepley static PetscInt tetS[] = {1, 4, 6, 4}; 1623*cf4091a3SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 3, 0, 0, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1624*cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 3, 0, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1625*cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 3, 0, 2, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1626*cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 3, 1, 0, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1627*cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 2, 0, 0, 0, 1628*cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 0, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, 1629*cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 0, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 1630*cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 2, 1, 0, 0, 1631*cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 1, 1632*cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 2, 1, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 3, 1633*cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 2, 1634*cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 4, 1635*cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 5, 1636*cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 3, 0, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 4}; 1637*cf4091a3SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 1638*cf4091a3SMatthew G. Knepley 0, 0, 1639*cf4091a3SMatthew G. Knepley 0, 0, 1640*cf4091a3SMatthew G. Knepley 0, 0, 1641*cf4091a3SMatthew G. Knepley 0, -2, -2, 1642*cf4091a3SMatthew G. Knepley -2, 0, -2, 1643*cf4091a3SMatthew G. Knepley -2, 0, -2, 1644*cf4091a3SMatthew G. Knepley 0, -2, -2, 1645*cf4091a3SMatthew G. Knepley -2, 0, -2, 1646*cf4091a3SMatthew G. Knepley -2, 0, -2, 1647*cf4091a3SMatthew G. Knepley 0, 0, 0, 0, 1648*cf4091a3SMatthew G. Knepley 0, 0, -3, 0, 1649*cf4091a3SMatthew G. Knepley 0, -3, -3, 0, 1650*cf4091a3SMatthew G. Knepley 0, -3, -1, -1}; 1651*cf4091a3SMatthew G. Knepley 1652*cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 1653*cf4091a3SMatthew G. Knepley switch (source) { 1654*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT: 1655*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1656*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1657*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1658*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1659*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1660*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1661*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1662*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 1663*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1664*cf4091a3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1665*cf4091a3SMatthew G. Knepley break; 1666*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1667*cf4091a3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1668*cf4091a3SMatthew G. Knepley } 1669*cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 1670*cf4091a3SMatthew G. Knepley } 1671*cf4091a3SMatthew G. Knepley 1672*cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_BL(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1673*cf4091a3SMatthew G. Knepley { 1674*cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 1675*cf4091a3SMatthew G. Knepley /* Split all tensor edges with a new vertex, making two new 2 tensor edges 1676*cf4091a3SMatthew G. Knepley 0--0--0--1--1 1677*cf4091a3SMatthew G. Knepley */ 1678*cf4091a3SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_POINT_PRISM_TENSOR}; 1679*cf4091a3SMatthew G. Knepley static PetscInt tedgeS[] = {1, 2}; 1680*cf4091a3SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, DM_POLYTOPE_POINT, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 1681*cf4091a3SMatthew G. Knepley static PetscInt tedgeO[] = { 0, 0, 0, 0}; 1682*cf4091a3SMatthew G. Knepley /* Add 1 segment inside every tensor quad, making 2 new tensor quads 1683*cf4091a3SMatthew G. Knepley 2---------1---------3 1684*cf4091a3SMatthew G. Knepley | | 1685*cf4091a3SMatthew G. Knepley | B | 1686*cf4091a3SMatthew G. Knepley | | 1687*cf4091a3SMatthew G. Knepley 2---------2---------3 1688*cf4091a3SMatthew G. Knepley | | 1689*cf4091a3SMatthew G. Knepley | A | 1690*cf4091a3SMatthew G. Knepley | | 1691*cf4091a3SMatthew G. Knepley 0---------0---------1 1692*cf4091a3SMatthew G. Knepley */ 1693*cf4091a3SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_SEG_PRISM_TENSOR}; 1694*cf4091a3SMatthew G. Knepley static PetscInt tquadS[] = {1, 2}; 1695*cf4091a3SMatthew G. Knepley static PetscInt tquadC[] = {DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 3, 0, 1696*cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0, 1697*cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 1, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 1}; 1698*cf4091a3SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 1699*cf4091a3SMatthew G. Knepley 0, 0, 0, 0, 1700*cf4091a3SMatthew G. Knepley 0, 0, 0, 0}; 1701*cf4091a3SMatthew G. Knepley /* Add 1 triangle and make 2 new tensor triangular prisms */ 1702*cf4091a3SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TRI_PRISM_TENSOR}; 1703*cf4091a3SMatthew G. Knepley static PetscInt ttripS[] = {1, 2}; 1704*cf4091a3SMatthew G. Knepley static PetscInt ttripC[] = {DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 4, 0, 1705*cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0, 1706*cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 1}; 1707*cf4091a3SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 0, 1708*cf4091a3SMatthew G. Knepley 0, 0, 0, 0, 0, 1709*cf4091a3SMatthew G. Knepley 0, 0, 0, 0, 0, 1710*cf4091a3SMatthew G. Knepley 0, 0, 0, 0, 0, 1711*cf4091a3SMatthew G. Knepley 0, 0, 0, 0, 0}; 1712*cf4091a3SMatthew G. Knepley /* Add 1 quad and make 2 new tensor quad prisms */ 1713*cf4091a3SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1714*cf4091a3SMatthew G. Knepley static PetscInt tquadpS[] = {1, 2}; 1715*cf4091a3SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 4, 0, DM_POLYTOPE_SEGMENT, 1, 5, 0, 1716*cf4091a3SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 0, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 0, 1717*cf4091a3SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 1}; 1718*cf4091a3SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 0, 0, 1719*cf4091a3SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 1720*cf4091a3SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 1721*cf4091a3SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 1722*cf4091a3SMatthew G. Knepley 0, 0, 0, 0, 0, 0}; 1723*cf4091a3SMatthew G. Knepley 1724*cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 1725*cf4091a3SMatthew G. Knepley switch (source) { 1726*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT: 1727*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1728*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1729*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1730*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 1731*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1732*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1733*cf4091a3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1734*cf4091a3SMatthew G. Knepley break; 1735*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 2; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 1736*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 2; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 1737*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 2; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 1738*cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 2; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 1739*cf4091a3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1740*cf4091a3SMatthew G. Knepley } 1741*cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 1742*cf4091a3SMatthew G. Knepley } 1743*cf4091a3SMatthew G. Knepley 1744412e9a14SMatthew G. Knepley static PetscErrorCode CellRefinerCreateOffset_Internal(DMPlexCellRefiner cr, PetscInt ctOrder[], PetscInt ctStart[], PetscInt **offset) 1745412e9a14SMatthew G. Knepley { 1746412e9a14SMatthew G. Knepley PetscInt c, cN, *off; 174775d3a19aSMatthew G. Knepley PetscErrorCode ierr; 174875d3a19aSMatthew G. Knepley 174975d3a19aSMatthew G. Knepley PetscFunctionBegin; 1750412e9a14SMatthew G. Knepley ierr = PetscCalloc1(DM_NUM_POLYTOPES*DM_NUM_POLYTOPES, &off);CHKERRQ(ierr); 1751412e9a14SMatthew G. Knepley for (c = DM_POLYTOPE_POINT; c < DM_NUM_POLYTOPES; ++c) { 1752412e9a14SMatthew G. Knepley const DMPolytopeType ct = (DMPolytopeType) c; 1753412e9a14SMatthew G. Knepley for (cN = DM_POLYTOPE_POINT; cN < DM_NUM_POLYTOPES; ++cN) { 1754412e9a14SMatthew G. Knepley const DMPolytopeType ctNew = (DMPolytopeType) cN; 1755412e9a14SMatthew G. Knepley DMPolytopeType *rct; 1756412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 1757412e9a14SMatthew G. Knepley PetscInt Nct, n, i; 1758412e9a14SMatthew G. Knepley 1759412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ct) < 0 || DMPolytopeTypeGetDim(ctNew) < 0) {off[ct*DM_NUM_POLYTOPES+ctNew] = -1; break;} 1760412e9a14SMatthew G. Knepley off[ct*DM_NUM_POLYTOPES+ctNew] = 0; 1761412e9a14SMatthew G. Knepley for (i = DM_POLYTOPE_POINT; i < DM_NUM_POLYTOPES; ++i) { 1762412e9a14SMatthew G. Knepley const DMPolytopeType ict = (DMPolytopeType) ctOrder[i]; 1763412e9a14SMatthew G. Knepley const DMPolytopeType ictn = (DMPolytopeType) ctOrder[i+1]; 1764412e9a14SMatthew G. Knepley 1765412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ict, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 1766412e9a14SMatthew G. Knepley if (ict == ct) { 1767412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) break; 1768412e9a14SMatthew G. Knepley if (n == Nct) off[ct*DM_NUM_POLYTOPES+ctNew] = -1; 1769412e9a14SMatthew G. Knepley break; 1770412e9a14SMatthew G. Knepley } 1771412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) off[ct*DM_NUM_POLYTOPES+ctNew] += (ctStart[ictn]-ctStart[ict]) * rsize[n]; 1772412e9a14SMatthew G. Knepley } 1773412e9a14SMatthew G. Knepley } 1774412e9a14SMatthew G. Knepley } 1775412e9a14SMatthew G. Knepley *offset = off; 1776412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1777412e9a14SMatthew G. Knepley } 1778412e9a14SMatthew G. Knepley 1779412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetStarts(DMPlexCellRefiner cr, const PetscInt ctStart[], const PetscInt ctStartNew[]) 1780412e9a14SMatthew G. Knepley { 1781412e9a14SMatthew G. Knepley const PetscInt ctSize = DM_NUM_POLYTOPES+1; 1782412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1783412e9a14SMatthew G. Knepley 1784412e9a14SMatthew G. Knepley PetscFunctionBegin; 1785412e9a14SMatthew G. Knepley if (cr->setupcalled) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_ARG_WRONGSTATE, "Must call this function before DMPlexCellRefinerSetUp()"); 1786412e9a14SMatthew G. Knepley ierr = PetscCalloc2(ctSize, &cr->ctStart, ctSize, &cr->ctStartNew);CHKERRQ(ierr); 1787412e9a14SMatthew G. Knepley ierr = PetscArraycpy(cr->ctStart, ctStart, ctSize);CHKERRQ(ierr); 1788412e9a14SMatthew G. Knepley ierr = PetscArraycpy(cr->ctStartNew, ctStartNew, ctSize);CHKERRQ(ierr); 1789412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1790412e9a14SMatthew G. Knepley } 1791412e9a14SMatthew G. Knepley 1792412e9a14SMatthew G. Knepley /* Construct cell type order since we must loop over cell types in depth order */ 1793412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCreateCellTypeOrder_Internal(DMPolytopeType ctCell, PetscInt *ctOrder[], PetscInt *ctOrderInv[]) 1794412e9a14SMatthew G. Knepley { 1795412e9a14SMatthew G. Knepley PetscInt *ctO, *ctOInv; 1796412e9a14SMatthew G. Knepley PetscInt c, d, off = 0; 1797412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1798412e9a14SMatthew G. Knepley 1799412e9a14SMatthew G. Knepley PetscFunctionBegin; 1800412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctO, DM_NUM_POLYTOPES+1, &ctOInv);CHKERRQ(ierr); 1801412e9a14SMatthew G. Knepley for (d = 3; d >= DMPolytopeTypeGetDim(ctCell); --d) { 1802412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1803412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue; 1804412e9a14SMatthew G. Knepley ctO[off++] = c; 1805412e9a14SMatthew G. Knepley } 1806412e9a14SMatthew G. Knepley } 1807412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ctCell) != 0) { 1808412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1809412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != 0) continue; 1810412e9a14SMatthew G. Knepley ctO[off++] = c; 1811412e9a14SMatthew G. Knepley } 1812412e9a14SMatthew G. Knepley } 1813412e9a14SMatthew G. Knepley for (d = DMPolytopeTypeGetDim(ctCell)-1; d > 0; --d) { 1814412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1815412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue; 1816412e9a14SMatthew G. Knepley ctO[off++] = c; 1817412e9a14SMatthew G. Knepley } 1818412e9a14SMatthew G. Knepley } 1819412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1820412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) >= 0) continue; 1821412e9a14SMatthew G. Knepley ctO[off++] = c; 1822412e9a14SMatthew G. Knepley } 1823412e9a14SMatthew G. Knepley if (off != DM_NUM_POLYTOPES+1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid offset %D for cell type order", off); 1824412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1825412e9a14SMatthew G. Knepley ctOInv[ctO[c]] = c; 1826412e9a14SMatthew G. Knepley } 1827412e9a14SMatthew G. Knepley *ctOrder = ctO; 1828412e9a14SMatthew G. Knepley *ctOrderInv = ctOInv; 1829412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1830412e9a14SMatthew G. Knepley } 1831412e9a14SMatthew G. Knepley 1832412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerSetUp(DMPlexCellRefiner cr) 1833412e9a14SMatthew G. Knepley { 1834412e9a14SMatthew G. Knepley DM dm = cr->dm; 1835412e9a14SMatthew G. Knepley DMPolytopeType ctCell; 1836412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p, c; 1837412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1838412e9a14SMatthew G. Knepley 1839412e9a14SMatthew G. Knepley PetscFunctionBegin; 1840412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 1841412e9a14SMatthew G. Knepley if (cr->setupcalled) PetscFunctionReturn(0); 1842412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 1843412e9a14SMatthew G. Knepley if (pEnd > pStart) {ierr = DMPlexGetCellType(dm, 0, &ctCell);CHKERRQ(ierr);} 1844412e9a14SMatthew G. Knepley else { 1845412e9a14SMatthew G. Knepley PetscInt dim; 1846a57030b0SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1847412e9a14SMatthew G. Knepley switch (dim) { 1848412e9a14SMatthew G. Knepley case 0: ctCell = DM_POLYTOPE_POINT;break; 1849412e9a14SMatthew G. Knepley case 1: ctCell = DM_POLYTOPE_SEGMENT;break; 1850412e9a14SMatthew G. Knepley case 2: ctCell = DM_POLYTOPE_TRIANGLE;break; 1851412e9a14SMatthew G. Knepley case 3: ctCell = DM_POLYTOPE_TETRAHEDRON;break; 1852412e9a14SMatthew G. Knepley default: ctCell = DM_POLYTOPE_TETRAHEDRON; 1853412e9a14SMatthew G. Knepley } 1854412e9a14SMatthew G. Knepley } 1855412e9a14SMatthew G. Knepley ierr = DMPlexCreateCellTypeOrder_Internal(ctCell, &cr->ctOrder, &cr->ctOrderInv);CHKERRQ(ierr); 1856412e9a14SMatthew G. Knepley /* Construct sizes and offsets for each cell type */ 1857412e9a14SMatthew G. Knepley if (!cr->ctStart) { 1858412e9a14SMatthew G. Knepley PetscInt *ctS, *ctSN, *ctC, *ctCN; 1859412e9a14SMatthew G. Knepley 1860412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctS, DM_NUM_POLYTOPES+1, &ctSN);CHKERRQ(ierr); 1861412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctC, DM_NUM_POLYTOPES+1, &ctCN);CHKERRQ(ierr); 1862412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 1863412e9a14SMatthew G. Knepley DMPolytopeType ct; 1864412e9a14SMatthew G. Knepley DMPolytopeType *rct; 1865412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 1866412e9a14SMatthew G. Knepley PetscInt Nct, n; 1867412e9a14SMatthew G. Knepley 1868412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 1869412e9a14SMatthew G. Knepley if ((PetscInt) ct < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No cell type for point %D", p); 1870412e9a14SMatthew G. Knepley ++ctC[ct]; 1871412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 1872412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) ctCN[rct[n]] += rsize[n]; 1873412e9a14SMatthew G. Knepley } 1874412e9a14SMatthew G. Knepley for (c = 0; c < DM_NUM_POLYTOPES; ++c) { 1875412e9a14SMatthew G. Knepley const PetscInt ct = cr->ctOrder[c]; 1876412e9a14SMatthew G. Knepley const PetscInt ctn = cr->ctOrder[c+1]; 1877412e9a14SMatthew G. Knepley 1878412e9a14SMatthew G. Knepley ctS[ctn] = ctS[ct] + ctC[ct]; 1879412e9a14SMatthew G. Knepley ctSN[ctn] = ctSN[ct] + ctCN[ct]; 1880412e9a14SMatthew G. Knepley } 1881412e9a14SMatthew G. Knepley ierr = PetscFree2(ctC, ctCN);CHKERRQ(ierr); 1882412e9a14SMatthew G. Knepley cr->ctStart = ctS; 1883412e9a14SMatthew G. Knepley cr->ctStartNew = ctSN; 1884412e9a14SMatthew G. Knepley } 1885412e9a14SMatthew G. Knepley ierr = CellRefinerCreateOffset_Internal(cr, cr->ctOrder, cr->ctStart, &cr->offset);CHKERRQ(ierr); 1886412e9a14SMatthew G. Knepley cr->setupcalled = PETSC_TRUE; 1887412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1888412e9a14SMatthew G. Knepley } 1889412e9a14SMatthew G. Knepley 1890412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView_Ascii(DMPlexCellRefiner cr, PetscViewer v) 1891412e9a14SMatthew G. Knepley { 1892412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1893412e9a14SMatthew G. Knepley 1894412e9a14SMatthew G. Knepley PetscFunctionBegin; 1895412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(v, "Cell Refiner: %s\n", DMPlexCellRefinerTypes[cr->type]);CHKERRQ(ierr); 1896412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1897412e9a14SMatthew G. Knepley } 1898412e9a14SMatthew G. Knepley 1899412e9a14SMatthew G. Knepley /* 1900412e9a14SMatthew G. Knepley DMPlexCellRefinerView - Views a DMPlexCellRefiner object 1901412e9a14SMatthew G. Knepley 1902412e9a14SMatthew G. Knepley Collective on cr 1903412e9a14SMatthew G. Knepley 1904412e9a14SMatthew G. Knepley Input Parameters: 1905412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 1906412e9a14SMatthew G. Knepley - viewer - The PetscViewer object 1907412e9a14SMatthew G. Knepley 1908412e9a14SMatthew G. Knepley Level: beginner 1909412e9a14SMatthew G. Knepley 1910412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerCreate() 1911412e9a14SMatthew G. Knepley */ 1912412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView(DMPlexCellRefiner cr, PetscViewer viewer) 1913412e9a14SMatthew G. Knepley { 1914412e9a14SMatthew G. Knepley PetscBool iascii; 1915412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1916412e9a14SMatthew G. Knepley 1917412e9a14SMatthew G. Knepley PetscFunctionBegin; 1918412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 1919412e9a14SMatthew G. Knepley if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1920412e9a14SMatthew G. Knepley if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) cr), &viewer);CHKERRQ(ierr);} 1921412e9a14SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1922412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1923412e9a14SMatthew G. Knepley if (iascii) {ierr = DMPlexCellRefinerView_Ascii(cr, viewer);CHKERRQ(ierr);} 1924412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1925412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1926412e9a14SMatthew G. Knepley } 1927412e9a14SMatthew G. Knepley 1928412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerDestroy(DMPlexCellRefiner *cr) 1929412e9a14SMatthew G. Knepley { 1930412e9a14SMatthew G. Knepley PetscInt c; 1931412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1932412e9a14SMatthew G. Knepley 1933412e9a14SMatthew G. Knepley PetscFunctionBegin; 1934412e9a14SMatthew G. Knepley if (!*cr) PetscFunctionReturn(0); 1935412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(*cr, DM_CLASSID, 1); 1936412e9a14SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) (*cr)->dm);CHKERRQ(ierr); 1937412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->ctOrder, (*cr)->ctOrderInv);CHKERRQ(ierr); 1938412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->ctStart, (*cr)->ctStartNew);CHKERRQ(ierr); 1939412e9a14SMatthew G. Knepley ierr = PetscFree((*cr)->offset);CHKERRQ(ierr); 1940412e9a14SMatthew G. Knepley for (c = 0; c < DM_NUM_POLYTOPES; ++c) { 1941412e9a14SMatthew G. Knepley ierr = PetscFEDestroy(&(*cr)->coordFE[c]);CHKERRQ(ierr); 1942412e9a14SMatthew G. Knepley ierr = PetscFEGeomDestroy(&(*cr)->refGeom[c]);CHKERRQ(ierr); 1943412e9a14SMatthew G. Knepley } 1944412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->coordFE, (*cr)->refGeom);CHKERRQ(ierr); 1945412e9a14SMatthew G. Knepley ierr = PetscHeaderDestroy(cr);CHKERRQ(ierr); 1946412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1947412e9a14SMatthew G. Knepley } 1948412e9a14SMatthew G. Knepley 1949412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerCreate(DM dm, DMPlexCellRefiner *cr) 1950412e9a14SMatthew G. Knepley { 1951412e9a14SMatthew G. Knepley DMPlexCellRefiner tmp; 1952412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1953412e9a14SMatthew G. Knepley 1954412e9a14SMatthew G. Knepley PetscFunctionBegin; 1955412e9a14SMatthew G. Knepley PetscValidPointer(cr, 2); 1956412e9a14SMatthew G. Knepley *cr = NULL; 1957412e9a14SMatthew G. Knepley ierr = PetscHeaderCreate(tmp, DM_CLASSID, "DMPlexCellRefiner", "Cell Refiner", "DMPlexCellRefiner", PETSC_COMM_SELF, DMPlexCellRefinerDestroy, DMPlexCellRefinerView);CHKERRQ(ierr); 1958412e9a14SMatthew G. Knepley tmp->setupcalled = PETSC_FALSE; 1959412e9a14SMatthew G. Knepley 1960412e9a14SMatthew G. Knepley tmp->dm = dm; 1961412e9a14SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); 1962412e9a14SMatthew G. Knepley ierr = DMPlexGetCellRefinerType(dm, &tmp->type);CHKERRQ(ierr); 1963412e9a14SMatthew G. Knepley switch (tmp->type) { 196496ca5757SLisandro Dalcin case DM_REFINER_REGULAR: 1965412e9a14SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_Regular; 1966412e9a14SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_Regular; 1967412e9a14SMatthew G. Knepley tmp->ops->getcellvertices = DMPlexCellRefinerGetCellVertices_Regular; 1968412e9a14SMatthew G. Knepley tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_Regular; 1969412e9a14SMatthew G. Knepley tmp->ops->getaffinetransforms = DMPlexCellRefinerGetAffineTransforms_Regular; 1970412e9a14SMatthew G. Knepley tmp->ops->getaffinefacetransforms = DMPlexCellRefinerGetAffineFaceTransforms_Regular; 1971412e9a14SMatthew G. Knepley break; 197296ca5757SLisandro Dalcin case DM_REFINER_TO_BOX: 197396ca5757SLisandro Dalcin tmp->ops->refine = DMPlexCellRefinerRefine_ToBox; 197496ca5757SLisandro Dalcin tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToBox; 197596ca5757SLisandro Dalcin tmp->ops->getcellvertices = DMPlexCellRefinerGetCellVertices_ToBox; 197696ca5757SLisandro Dalcin tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_ToBox; 1977412e9a14SMatthew G. Knepley break; 197896ca5757SLisandro Dalcin case DM_REFINER_TO_SIMPLEX: 1979412e9a14SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_ToSimplex; 1980412e9a14SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToSimplex; 1981412e9a14SMatthew G. Knepley break; 1982*cf4091a3SMatthew G. Knepley case DM_REFINER_ALFELD2D: 1983*cf4091a3SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_Alfeld2D; 1984*cf4091a3SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_None; 1985*cf4091a3SMatthew G. Knepley break; 1986*cf4091a3SMatthew G. Knepley case DM_REFINER_ALFELD3D: 1987*cf4091a3SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_Alfeld3D; 1988*cf4091a3SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_None; 1989*cf4091a3SMatthew G. Knepley break; 1990*cf4091a3SMatthew G. Knepley case DM_REFINER_BL: 1991*cf4091a3SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_BL; 1992*cf4091a3SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_BL; 1993*cf4091a3SMatthew G. Knepley break; 1994412e9a14SMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Invalid cell refiner type %s", DMPlexCellRefinerTypes[tmp->type]); 1995412e9a14SMatthew G. Knepley } 1996412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES, &tmp->coordFE, DM_NUM_POLYTOPES, &tmp->refGeom);CHKERRQ(ierr); 1997412e9a14SMatthew G. Knepley *cr = tmp; 1998412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1999412e9a14SMatthew G. Knepley } 2000412e9a14SMatthew G. Knepley 2001412e9a14SMatthew G. Knepley /*@ 2002412e9a14SMatthew G. Knepley DMPlexCellRefinerGetAffineTransforms - Gets the affine map from the reference cell to each subcell 2003412e9a14SMatthew G. Knepley 2004412e9a14SMatthew G. Knepley Input Parameters: 2005412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 2006412e9a14SMatthew G. Knepley - ct - The cell type 2007412e9a14SMatthew G. Knepley 2008412e9a14SMatthew G. Knepley Output Parameters: 2009412e9a14SMatthew G. Knepley + Nc - The number of subcells produced from this cell type 2010412e9a14SMatthew G. Knepley . v0 - The translation of the first vertex for each subcell 2011412e9a14SMatthew G. Knepley . J - The Jacobian for each subcell (map from reference cell to subcell) 2012412e9a14SMatthew G. Knepley - invJ - The inverse Jacobian for each subcell 2013412e9a14SMatthew G. Knepley 2014412e9a14SMatthew G. Knepley Level: developer 2015412e9a14SMatthew G. Knepley 2016412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineFaceTransforms(), Create() 2017412e9a14SMatthew G. Knepley @*/ 2018412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[]) 2019412e9a14SMatthew G. Knepley { 2020412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2021412e9a14SMatthew G. Knepley 2022412e9a14SMatthew G. Knepley PetscFunctionBegin; 2023412e9a14SMatthew G. Knepley if (!cr->ops->getaffinetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine transforms from this refiner"); 2024412e9a14SMatthew G. Knepley ierr = (*cr->ops->getaffinetransforms)(cr, ct, Nc, v0, J, invJ);CHKERRQ(ierr); 2025412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2026412e9a14SMatthew G. Knepley } 2027412e9a14SMatthew G. Knepley 2028412e9a14SMatthew G. Knepley /*@ 2029412e9a14SMatthew G. Knepley DMPlexCellRefinerGetAffineFaceTransforms - Gets the affine map from the reference face cell to each face in the given cell 2030412e9a14SMatthew G. Knepley 2031412e9a14SMatthew G. Knepley Input Parameters: 2032412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 2033412e9a14SMatthew G. Knepley - ct - The cell type 2034412e9a14SMatthew G. Knepley 2035412e9a14SMatthew G. Knepley Output Parameters: 2036412e9a14SMatthew G. Knepley + Nf - The number of faces for this cell type 2037412e9a14SMatthew G. Knepley . v0 - The translation of the first vertex for each face 2038412e9a14SMatthew G. Knepley . J - The Jacobian for each face (map from original cell to subcell) 2039412e9a14SMatthew G. Knepley . invJ - The inverse Jacobian for each face 2040412e9a14SMatthew G. Knepley - detJ - The determinant of the Jacobian for each face 2041412e9a14SMatthew G. Knepley 2042412e9a14SMatthew G. Knepley Note: The Jacobian and inverse Jacboian will be rectangular, and the inverse is really a generalized inverse. 2043412e9a14SMatthew G. Knepley 2044412e9a14SMatthew G. Knepley Level: developer 2045412e9a14SMatthew G. Knepley 2046412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineTransforms(), Create() 2047412e9a14SMatthew G. Knepley @*/ 2048412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[]) 2049412e9a14SMatthew G. Knepley { 2050412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2051412e9a14SMatthew G. Knepley 2052412e9a14SMatthew G. Knepley PetscFunctionBegin; 2053412e9a14SMatthew G. Knepley if (!cr->ops->getaffinefacetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine face transforms from this refiner"); 2054412e9a14SMatthew G. Knepley ierr = (*cr->ops->getaffinefacetransforms)(cr, ct, Nf, v0, J, invJ, detJ);CHKERRQ(ierr); 2055412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2056412e9a14SMatthew G. Knepley } 2057412e9a14SMatthew G. Knepley 2058412e9a14SMatthew G. Knepley /* Numbering regularly refined meshes 2059412e9a14SMatthew G. Knepley 2060412e9a14SMatthew G. Knepley We want the numbering of the new mesh to respect the same depth stratification as the old mesh. We first compute 2061412e9a14SMatthew G. Knepley the number of new points at each depth. This means that offsets for each depth can be computed, making no assumptions 2062412e9a14SMatthew G. Knepley about the order of different cell types. 2063412e9a14SMatthew G. Knepley 2064412e9a14SMatthew G. Knepley However, when we want to order different depth strata, it will be very useful to make assumptions about contiguous 2065412e9a14SMatthew G. Knepley numbering of different cell types, especially if we want to compute new numberings without communication. Therefore, we 2066412e9a14SMatthew G. Knepley will require that cells are numbering contiguously for each cell type, and that those blocks come in the same order as 2067412e9a14SMatthew G. Knepley the cell type enumeration within a given depth stratum. 2068412e9a14SMatthew G. Knepley 2069412e9a14SMatthew G. Knepley Thus, at each depth, each cell type will add a certain number of points at that depth. To get the new point number, we 2070412e9a14SMatthew G. Knepley start at the new depth offset, run through all prior cell types incrementing by the total addition from that type, then 2071412e9a14SMatthew G. Knepley offset by the old cell type number and replica number for the insertion. 2072412e9a14SMatthew G. Knepley */ 2073412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetNewPoint(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType ctNew, PetscInt p, PetscInt r, PetscInt *pNew) 2074412e9a14SMatthew G. Knepley { 2075412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2076412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 2077412e9a14SMatthew G. Knepley PetscInt Nct, n; 2078412e9a14SMatthew G. Knepley PetscInt off = cr->offset[ct*DM_NUM_POLYTOPES+ctNew]; 2079412e9a14SMatthew G. Knepley PetscInt ctS = cr->ctStart[ct], ctE = cr->ctStart[cr->ctOrder[cr->ctOrderInv[ct]+1]]; 2080412e9a14SMatthew G. Knepley PetscInt ctSN = cr->ctStartNew[ctNew], ctEN = cr->ctStartNew[cr->ctOrder[cr->ctOrderInv[ctNew]+1]]; 2081412e9a14SMatthew G. Knepley PetscInt newp = ctSN; 2082412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2083412e9a14SMatthew G. Knepley 2084412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 2085412e9a14SMatthew G. Knepley if ((p < ctS) || (p >= ctE)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a %s [%D, %D)", p, DMPolytopeTypes[ct], ctS, ctE); 2086412e9a14SMatthew G. Knepley if (off < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell type %s does not produce type %s", DMPolytopeTypes[ct], DMPolytopeTypes[ctNew]); 2087412e9a14SMatthew G. Knepley 2088412e9a14SMatthew G. Knepley newp += off; 2089412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 2090412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2091412e9a14SMatthew G. Knepley if (rct[n] == ctNew) { 2092412e9a14SMatthew G. Knepley if (rsize[n] && r >= rsize[n]) 2093412e9a14SMatthew G. Knepley SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Replica number %D should be in [0, %D) for subcell type %s in cell type %s", r, rsize[n], DMPolytopeTypes[rct[n]], DMPolytopeTypes[ct]); 2094412e9a14SMatthew G. Knepley newp += (p - ctS) * rsize[n] + r; 2095412e9a14SMatthew G. Knepley break; 2096412e9a14SMatthew G. Knepley } 2097412e9a14SMatthew G. Knepley } 2098412e9a14SMatthew G. Knepley 2099412e9a14SMatthew G. Knepley if ((newp < ctSN) || (newp >= ctEN)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "New point %D is not a %s [%D, %D)", newp, DMPolytopeTypes[ctNew], ctSN, ctEN); 2100412e9a14SMatthew G. Knepley *pNew = newp; 2101412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2102412e9a14SMatthew G. Knepley } 2103412e9a14SMatthew G. Knepley 2104412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetConeSizes(DMPlexCellRefiner cr, DM rdm) 2105412e9a14SMatthew G. Knepley { 2106412e9a14SMatthew G. Knepley DM dm = cr->dm; 2107412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p, pNew; 2108412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2109412e9a14SMatthew G. Knepley 2110412e9a14SMatthew G. Knepley PetscFunctionBegin; 2111412e9a14SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 2112412e9a14SMatthew G. Knepley ierr = DMCreateLabel(rdm, "celltype");CHKERRQ(ierr); 2113412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2114412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2115412e9a14SMatthew G. Knepley DMPolytopeType ct; 2116412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2117412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2118412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2119412e9a14SMatthew G. Knepley 2120412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2121412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2122412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2123412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2124412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 2125412e9a14SMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, pNew, DMPolytopeTypeGetConeSize(rct[n]));CHKERRQ(ierr); 2126412e9a14SMatthew G. Knepley ierr = DMPlexSetCellType(rdm, pNew, rct[n]);CHKERRQ(ierr); 2127412e9a14SMatthew G. Knepley } 2128412e9a14SMatthew G. Knepley } 2129412e9a14SMatthew G. Knepley } 2130412e9a14SMatthew G. Knepley { 2131412e9a14SMatthew G. Knepley DMLabel ctLabel; 2132412e9a14SMatthew G. Knepley DM_Plex *plex = (DM_Plex *) rdm->data; 2133412e9a14SMatthew G. Knepley 2134412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(rdm, &ctLabel);CHKERRQ(ierr); 2135412e9a14SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) ctLabel, &plex->celltypeState);CHKERRQ(ierr); 2136412e9a14SMatthew G. Knepley } 2137412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2138412e9a14SMatthew G. Knepley } 2139412e9a14SMatthew G. Knepley 2140412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCones(DMPlexCellRefiner cr, DM rdm) 2141412e9a14SMatthew G. Knepley { 2142412e9a14SMatthew G. Knepley DM dm = cr->dm; 2143412e9a14SMatthew G. Knepley DMPolytopeType ct; 2144412e9a14SMatthew G. Knepley PetscInt *coneNew, *orntNew; 2145412e9a14SMatthew G. Knepley PetscInt maxConeSize = 0, pStart, pEnd, p, pNew; 2146412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2147412e9a14SMatthew G. Knepley 2148412e9a14SMatthew G. Knepley PetscFunctionBegin; 2149412e9a14SMatthew G. Knepley for (p = 0; p < DM_NUM_POLYTOPES; ++p) maxConeSize = PetscMax(maxConeSize, DMPolytopeTypeGetConeSize((DMPolytopeType) p)); 2150412e9a14SMatthew G. Knepley ierr = PetscMalloc2(maxConeSize, &coneNew, maxConeSize, &orntNew);CHKERRQ(ierr); 2151412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2152412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2153412e9a14SMatthew G. Knepley const PetscInt *cone, *ornt; 2154412e9a14SMatthew G. Knepley PetscInt coff, ooff, c; 2155412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2156412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2157412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2158412e9a14SMatthew G. Knepley 2159412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2160412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 2161412e9a14SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &ornt);CHKERRQ(ierr); 2162412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2163412e9a14SMatthew G. Knepley for (n = 0, coff = 0, ooff = 0; n < Nct; ++n) { 2164412e9a14SMatthew G. Knepley const DMPolytopeType ctNew = rct[n]; 2165412e9a14SMatthew G. Knepley const PetscInt csizeNew = DMPolytopeTypeGetConeSize(ctNew); 2166412e9a14SMatthew G. Knepley 2167412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2168412e9a14SMatthew G. Knepley /* pNew is a subcell produced by subdividing p */ 2169412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 2170412e9a14SMatthew G. Knepley for (c = 0; c < csizeNew; ++c) { 2171412e9a14SMatthew G. Knepley PetscInt ppp = -1; /* Parent Parent point: Parent of point pp */ 2172412e9a14SMatthew G. Knepley PetscInt pp = p; /* Parent point: Point in the original mesh producing new cone point */ 2173412e9a14SMatthew G. Knepley PetscInt po = 0; /* Orientation of parent point pp in parent parent point ppp */ 2174412e9a14SMatthew G. Knepley DMPolytopeType pct = ct; /* Parent type: Cell type for parent of new cone point */ 2175412e9a14SMatthew G. Knepley const PetscInt *pcone = cone; /* Parent cone: Cone of parent point pp */ 2176412e9a14SMatthew G. Knepley PetscInt pr = -1; /* Replica number of pp that produces new cone point */ 2177412e9a14SMatthew G. Knepley const DMPolytopeType ft = (DMPolytopeType) rcone[coff++]; /* Cell type for new cone point of pNew */ 2178412e9a14SMatthew G. Knepley const PetscInt fn = rcone[coff++]; /* Number of cones of p that need to be taken when producing new cone point */ 2179412e9a14SMatthew G. Knepley PetscInt fo = rornt[ooff++]; /* Orientation of new cone point in pNew */ 2180412e9a14SMatthew G. Knepley PetscInt lc; 2181412e9a14SMatthew G. Knepley 2182412e9a14SMatthew G. Knepley /* Get the type (pct) and point number (pp) of the parent point in the original mesh which produces this cone point */ 2183412e9a14SMatthew G. Knepley for (lc = 0; lc < fn; ++lc) { 2184412e9a14SMatthew G. Knepley const PetscInt *ppornt; 2185412e9a14SMatthew G. Knepley PetscInt pcp; 2186412e9a14SMatthew G. Knepley 2187412e9a14SMatthew G. Knepley ierr = DMPolytopeMapCell(pct, po, rcone[coff++], &pcp);CHKERRQ(ierr); 2188412e9a14SMatthew G. Knepley ppp = pp; 2189412e9a14SMatthew G. Knepley pp = pcone[pcp]; 2190412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, pp, &pct);CHKERRQ(ierr); 2191412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, pp, &pcone);CHKERRQ(ierr); 2192412e9a14SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, ppp, &ppornt);CHKERRQ(ierr); 2193*cf4091a3SMatthew G. Knepley if (po < 0 && pct != DM_POLYTOPE_POINT) { 2194*cf4091a3SMatthew G. Knepley const PetscInt pornt = ppornt[pcp]; 2195*cf4091a3SMatthew G. Knepley const PetscInt pcsize = DMPolytopeTypeGetConeSize(pct); 2196*cf4091a3SMatthew G. Knepley const PetscInt pcstart = pornt < 0 ? -(pornt+1) : pornt; 2197*cf4091a3SMatthew G. Knepley const PetscInt rcstart = (pcstart+pcsize-1)%pcsize; 2198*cf4091a3SMatthew G. Knepley po = pornt < 0 ? -(rcstart+1) : rcstart; 2199*cf4091a3SMatthew G. Knepley } else { 2200412e9a14SMatthew G. Knepley po = ppornt[pcp]; 2201412e9a14SMatthew G. Knepley } 2202*cf4091a3SMatthew G. Knepley } 2203412e9a14SMatthew G. Knepley pr = rcone[coff++]; 2204412e9a14SMatthew G. Knepley /* Orientation po of pp maps (pr, fo) -> (pr', fo') */ 2205412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapSubcells(cr, pct, po, ft, pr, fo, &pr, &fo);CHKERRQ(ierr); 2206412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, pct, ft, pp, pr, &coneNew[c]);CHKERRQ(ierr); 2207412e9a14SMatthew G. Knepley orntNew[c] = fo; 2208412e9a14SMatthew G. Knepley } 2209412e9a14SMatthew G. Knepley ierr = DMPlexSetCone(rdm, pNew, coneNew);CHKERRQ(ierr); 2210412e9a14SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, pNew, orntNew);CHKERRQ(ierr); 2211412e9a14SMatthew G. Knepley } 2212412e9a14SMatthew G. Knepley } 2213412e9a14SMatthew G. Knepley } 2214412e9a14SMatthew G. Knepley ierr = PetscFree2(coneNew, orntNew);CHKERRQ(ierr); 2215412e9a14SMatthew G. Knepley ierr = DMPlexSymmetrize(rdm);CHKERRQ(ierr); 2216412e9a14SMatthew G. Knepley ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 2217412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2218412e9a14SMatthew G. Knepley } 2219412e9a14SMatthew G. Knepley 2220412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCoordinateFE(DMPlexCellRefiner cr, DMPolytopeType ct, PetscFE *fe) 2221412e9a14SMatthew G. Knepley { 2222412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2223412e9a14SMatthew G. Knepley 2224412e9a14SMatthew G. Knepley PetscFunctionBegin; 2225412e9a14SMatthew G. Knepley if (!cr->coordFE[ct]) { 2226412e9a14SMatthew G. Knepley PetscInt dim, cdim; 2227412e9a14SMatthew G. Knepley PetscBool isSimplex; 2228412e9a14SMatthew G. Knepley 2229412e9a14SMatthew G. Knepley switch (ct) { 2230412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: dim = 1; isSimplex = PETSC_TRUE; break; 2231412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: dim = 2; isSimplex = PETSC_TRUE; break; 2232412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: dim = 2; isSimplex = PETSC_FALSE; break; 2233412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: dim = 3; isSimplex = PETSC_TRUE; break; 2234412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: dim = 3; isSimplex = PETSC_FALSE; break; 2235412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No coordinate FE for cell type %s", DMPolytopeTypes[ct]); 2236412e9a14SMatthew G. Knepley } 2237412e9a14SMatthew G. Knepley ierr = DMGetCoordinateDim(cr->dm, &cdim);CHKERRQ(ierr); 2238412e9a14SMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, cdim, isSimplex, 1, PETSC_DETERMINE, &cr->coordFE[ct]);CHKERRQ(ierr); 2239412e9a14SMatthew G. Knepley { 2240412e9a14SMatthew G. Knepley PetscDualSpace dsp; 2241412e9a14SMatthew G. Knepley PetscQuadrature quad; 2242412e9a14SMatthew G. Knepley DM K; 2243412e9a14SMatthew G. Knepley PetscFEGeom *cg; 2244412e9a14SMatthew G. Knepley PetscReal *Xq, *xq, *wq; 2245412e9a14SMatthew G. Knepley PetscInt Nq, q; 2246412e9a14SMatthew G. Knepley 2247412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCellVertices(cr, ct, &Nq, &Xq);CHKERRQ(ierr); 2248412e9a14SMatthew G. Knepley ierr = PetscMalloc1(Nq*cdim, &xq);CHKERRQ(ierr); 2249412e9a14SMatthew G. Knepley for (q = 0; q < Nq*cdim; ++q) xq[q] = Xq[q]; 2250412e9a14SMatthew G. Knepley ierr = PetscMalloc1(Nq, &wq);CHKERRQ(ierr); 2251412e9a14SMatthew G. Knepley for (q = 0; q < Nq; ++q) wq[q] = 1.0; 2252412e9a14SMatthew G. Knepley ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &quad);CHKERRQ(ierr); 2253412e9a14SMatthew G. Knepley ierr = PetscQuadratureSetData(quad, dim, 1, Nq, xq, wq);CHKERRQ(ierr); 2254412e9a14SMatthew G. Knepley ierr = PetscFESetQuadrature(cr->coordFE[ct], quad);CHKERRQ(ierr); 2255412e9a14SMatthew G. Knepley 2256412e9a14SMatthew G. Knepley ierr = PetscFEGetDualSpace(cr->coordFE[ct], &dsp);CHKERRQ(ierr); 2257412e9a14SMatthew G. Knepley ierr = PetscDualSpaceGetDM(dsp, &K);CHKERRQ(ierr); 2258412e9a14SMatthew G. Knepley ierr = PetscFEGeomCreate(quad, 1, cdim, PETSC_FALSE, &cr->refGeom[ct]);CHKERRQ(ierr); 2259412e9a14SMatthew G. Knepley cg = cr->refGeom[ct]; 2260412e9a14SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(K, 0, NULL, cg->v, cg->J, cg->invJ, cg->detJ);CHKERRQ(ierr); 2261412e9a14SMatthew G. Knepley ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr); 2262412e9a14SMatthew G. Knepley } 2263412e9a14SMatthew G. Knepley } 2264412e9a14SMatthew G. Knepley *fe = cr->coordFE[ct]; 2265412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2266412e9a14SMatthew G. Knepley } 2267412e9a14SMatthew G. Knepley 2268412e9a14SMatthew G. Knepley /* 2269412e9a14SMatthew G. Knepley DMPlexCellRefinerMapLocalizedCoordinates - Given a cell of type ct with localized coordinates x, we generate localized coordinates xr for subcell r of type rct. 2270412e9a14SMatthew G. Knepley 2271412e9a14SMatthew G. Knepley Not collective 2272412e9a14SMatthew G. Knepley 2273412e9a14SMatthew G. Knepley Input Parameters: 2274412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner 2275412e9a14SMatthew G. Knepley . ct - The type of the parent cell 2276412e9a14SMatthew G. Knepley . rct - The type of the produced cell 2277412e9a14SMatthew G. Knepley . r - The index of the produced cell 2278412e9a14SMatthew G. Knepley - x - The localized coordinates for the parent cell 2279412e9a14SMatthew G. Knepley 2280412e9a14SMatthew G. Knepley Output Parameter: 2281412e9a14SMatthew G. Knepley . xr - The localized coordinates for the produced cell 2282412e9a14SMatthew G. Knepley 2283412e9a14SMatthew G. Knepley Level: developer 2284412e9a14SMatthew G. Knepley 2285412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerSetCoordinates() 2286412e9a14SMatthew G. Knepley */ 2287412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapLocalizedCoordinates(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, const PetscScalar x[], PetscScalar xr[]) 2288412e9a14SMatthew G. Knepley { 2289412e9a14SMatthew G. Knepley PetscFE fe = NULL; 2290412e9a14SMatthew G. Knepley PetscInt cdim, Nv, v, *subcellV; 2291412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2292412e9a14SMatthew G. Knepley 2293412e9a14SMatthew G. Knepley PetscFunctionBegin; 2294412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCoordinateFE(cr, ct, &fe);CHKERRQ(ierr); 2295412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetSubcellVertices(cr, ct, rct, r, &Nv, &subcellV);CHKERRQ(ierr); 2296412e9a14SMatthew G. Knepley ierr = PetscFEGetNumComponents(fe, &cdim);CHKERRQ(ierr); 2297412e9a14SMatthew G. Knepley for (v = 0; v < Nv; ++v) { 2298412e9a14SMatthew G. Knepley ierr = PetscFEInterpolate_Static(fe, x, cr->refGeom[ct], subcellV[v], &xr[v*cdim]);CHKERRQ(ierr); 2299412e9a14SMatthew G. Knepley } 2300412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2301412e9a14SMatthew G. Knepley } 2302412e9a14SMatthew G. Knepley 2303412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCoordinates(DMPlexCellRefiner cr, DM rdm) 2304412e9a14SMatthew G. Knepley { 2305412e9a14SMatthew G. Knepley DM dm = cr->dm, cdm; 2306412e9a14SMatthew G. Knepley PetscSection coordSection, coordSectionNew; 2307412e9a14SMatthew G. Knepley Vec coordsLocal, coordsLocalNew; 2308412e9a14SMatthew G. Knepley const PetscScalar *coords; 2309412e9a14SMatthew G. Knepley PetscScalar *coordsNew; 2310412e9a14SMatthew G. Knepley const DMBoundaryType *bd; 2311412e9a14SMatthew G. Knepley const PetscReal *maxCell, *L; 2312412e9a14SMatthew G. Knepley PetscBool isperiodic, localizeVertices = PETSC_FALSE, localizeCells = PETSC_FALSE; 2313412e9a14SMatthew G. Knepley PetscInt dE, d, cStart, cEnd, c, vStartNew, vEndNew, v, pStart, pEnd, p, ocStart, ocEnd; 2314412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2315412e9a14SMatthew G. Knepley 2316412e9a14SMatthew G. Knepley PetscFunctionBegin; 2317412e9a14SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 231890b157c4SStefano Zampini ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 231990b157c4SStefano Zampini /* Determine if we need to localize coordinates when generating them */ 2320b9ccc978SStefano Zampini if (isperiodic) { 2321412e9a14SMatthew G. Knepley localizeVertices = PETSC_TRUE; 2322412e9a14SMatthew G. Knepley if (!maxCell) { 2323412e9a14SMatthew G. Knepley PetscBool localized; 2324412e9a14SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 2325412e9a14SMatthew G. Knepley if (!localized) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Cannot refine a periodic mesh if coordinates have not been localized"); 2326412e9a14SMatthew G. Knepley localizeCells = PETSC_TRUE; 2327b9ccc978SStefano Zampini } 2328b9ccc978SStefano Zampini } 2329b9ccc978SStefano Zampini 2330b9ccc978SStefano Zampini ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 2331412e9a14SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &dE);CHKERRQ(ierr); 2332412e9a14SMatthew G. Knepley if (maxCell) { 2333412e9a14SMatthew G. Knepley PetscReal maxCellNew[3]; 2334412e9a14SMatthew G. Knepley 2335412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) maxCellNew[d] = maxCell[d]/2.0; 2336412e9a14SMatthew G. Knepley ierr = DMSetPeriodicity(rdm, isperiodic, maxCellNew, L, bd);CHKERRQ(ierr); 2337412e9a14SMatthew G. Knepley } else { 2338412e9a14SMatthew G. Knepley ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 2339412e9a14SMatthew G. Knepley } 2340b9ccc978SStefano Zampini ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &coordSectionNew);CHKERRQ(ierr); 2341b9ccc978SStefano Zampini ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 2342412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dE);CHKERRQ(ierr); 2343412e9a14SMatthew G. Knepley ierr = DMPlexGetDepthStratum(rdm, 0, &vStartNew, &vEndNew);CHKERRQ(ierr); 2344412e9a14SMatthew G. Knepley if (localizeCells) {ierr = PetscSectionSetChart(coordSectionNew, 0, vEndNew);CHKERRQ(ierr);} 2345412e9a14SMatthew G. Knepley else {ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vEndNew);CHKERRQ(ierr);} 2346b9ccc978SStefano Zampini 2347412e9a14SMatthew G. Knepley /* Localization should be inherited */ 2348412e9a14SMatthew G. Knepley /* Stefano calculates parent cells for each new cell for localization */ 2349412e9a14SMatthew G. Knepley /* Localized cells need coordinates of closure */ 2350412e9a14SMatthew G. Knepley for (v = vStartNew; v < vEndNew; ++v) { 2351412e9a14SMatthew G. Knepley ierr = PetscSectionSetDof(coordSectionNew, v, dE);CHKERRQ(ierr); 2352412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dE);CHKERRQ(ierr); 2353412e9a14SMatthew G. Knepley } 2354412e9a14SMatthew G. Knepley if (localizeCells) { 2355412e9a14SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 2356412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 2357412e9a14SMatthew G. Knepley PetscInt dof; 235890b157c4SStefano Zampini 2359412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, c, &dof); CHKERRQ(ierr); 2360412e9a14SMatthew G. Knepley if (dof) { 2361412e9a14SMatthew G. Knepley DMPolytopeType ct; 2362412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2363412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2364412e9a14SMatthew G. Knepley PetscInt dim, cNew, Nct, n, r; 236590b157c4SStefano Zampini 2366412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 2367412e9a14SMatthew G. Knepley dim = DMPolytopeTypeGetDim(ct); 2368412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2369412e9a14SMatthew G. Knepley /* This allows for different cell types */ 2370412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2371412e9a14SMatthew G. Knepley if (dim != DMPolytopeTypeGetDim(rct[n])) continue; 2372412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2373412e9a14SMatthew G. Knepley PetscInt *closure = NULL; 2374412e9a14SMatthew G. Knepley PetscInt clSize, cl, Nv = 0; 237590b157c4SStefano Zampini 2376412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], c, r, &cNew);CHKERRQ(ierr); 2377412e9a14SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 2378412e9a14SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) {if ((closure[cl] >= vStartNew) && (closure[cl] < vEndNew)) ++Nv;} 2379412e9a14SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 2380412e9a14SMatthew G. Knepley ierr = PetscSectionSetDof(coordSectionNew, cNew, Nv * dE);CHKERRQ(ierr); 2381412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSectionNew, cNew, 0, Nv * dE);CHKERRQ(ierr); 23829fc2a3f3SStefano Zampini } 238390b157c4SStefano Zampini } 238490b157c4SStefano Zampini } 2385412e9a14SMatthew G. Knepley } 238675d3a19aSMatthew G. Knepley } 238775d3a19aSMatthew G. Knepley ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 2388412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-coarse_dm_view");CHKERRQ(ierr); 238946e270d4SMatthew G. Knepley ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 2390412e9a14SMatthew G. Knepley { 2391412e9a14SMatthew G. Knepley VecType vtype; 2392412e9a14SMatthew G. Knepley PetscInt coordSizeNew, bs; 2393412e9a14SMatthew G. Knepley const char *name; 2394412e9a14SMatthew G. Knepley 2395412e9a14SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); 2396412e9a14SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordsLocalNew);CHKERRQ(ierr); 239775d3a19aSMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 2398412e9a14SMatthew G. Knepley ierr = VecSetSizes(coordsLocalNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 2399412e9a14SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) coordsLocal, &name);CHKERRQ(ierr); 2400412e9a14SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordsLocalNew, name);CHKERRQ(ierr); 2401412e9a14SMatthew G. Knepley ierr = VecGetBlockSize(coordsLocal, &bs);CHKERRQ(ierr); 2402412e9a14SMatthew G. Knepley ierr = VecSetBlockSize(coordsLocalNew, bs);CHKERRQ(ierr); 2403412e9a14SMatthew G. Knepley ierr = VecGetType(coordsLocal, &vtype);CHKERRQ(ierr); 2404412e9a14SMatthew G. Knepley ierr = VecSetType(coordsLocalNew, vtype);CHKERRQ(ierr); 2405b5da9499SMatthew G. Knepley } 2406412e9a14SMatthew G. Knepley ierr = VecGetArrayRead(coordsLocal, &coords);CHKERRQ(ierr); 2407412e9a14SMatthew G. Knepley ierr = VecGetArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr); 2408412e9a14SMatthew G. Knepley ierr = PetscSectionGetChart(coordSection, &ocStart, &ocEnd);CHKERRQ(ierr); 2409412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2410412e9a14SMatthew G. Knepley /* First set coordinates for vertices*/ 2411412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2412412e9a14SMatthew G. Knepley DMPolytopeType ct; 2413412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2414412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2415412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2416412e9a14SMatthew G. Knepley PetscBool hasVertex = PETSC_FALSE, isLocalized = PETSC_FALSE; 241790b157c4SStefano Zampini 2418412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2419412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2420412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2421412e9a14SMatthew G. Knepley if (rct[n] == DM_POLYTOPE_POINT) {hasVertex = PETSC_TRUE; break;} 2422412e9a14SMatthew G. Knepley } 2423412e9a14SMatthew G. Knepley if (localizeVertices && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) { 2424412e9a14SMatthew G. Knepley PetscInt dof; 2425412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, p, &dof); CHKERRQ(ierr); 2426412e9a14SMatthew G. Knepley if (dof) isLocalized = PETSC_TRUE; 2427412e9a14SMatthew G. Knepley } 2428412e9a14SMatthew G. Knepley if (hasVertex) { 2429412e9a14SMatthew G. Knepley PetscScalar *pcoords = NULL; 2430412e9a14SMatthew G. Knepley PetscScalar vcoords[3] = {0., 0., 0.}; 2431412e9a14SMatthew G. Knepley PetscInt Nc, Nv, v, d; 243290b157c4SStefano Zampini 2433412e9a14SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr); 2434412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_POINT) { 2435412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) vcoords[d] = pcoords[d]; 24369fc2a3f3SStefano Zampini } else { 2437412e9a14SMatthew G. Knepley if (localizeVertices) { 2438412e9a14SMatthew G. Knepley PetscScalar anchor[3]; 243990b157c4SStefano Zampini 2440412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) anchor[d] = pcoords[d]; 2441412e9a14SMatthew G. Knepley if (!isLocalized) { 2442412e9a14SMatthew G. Knepley Nv = Nc/dE; 2443412e9a14SMatthew G. Knepley for (v = 0; v < Nv; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], vcoords);CHKERRQ(ierr);} 2444412e9a14SMatthew G. Knepley } else { 2445412e9a14SMatthew G. Knepley Nv = Nc/(2*dE); 2446412e9a14SMatthew G. Knepley for (v = Nv; v < Nv*2; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], vcoords);CHKERRQ(ierr);} 244790b157c4SStefano Zampini } 244890b157c4SStefano Zampini } else { 2449412e9a14SMatthew G. Knepley Nv = Nc/dE; 2450412e9a14SMatthew G. Knepley for (v = 0; v < Nv; ++v) for (d = 0; d < dE; ++d) vcoords[d] += pcoords[v*dE+d]; 2451b5da9499SMatthew G. Knepley } 2452412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) vcoords[d] /= Nv; 245390b157c4SStefano Zampini } 2454412e9a14SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr); 2455412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2456412e9a14SMatthew G. Knepley if (rct[n] != DM_POLYTOPE_POINT) continue; 2457eac51794SMatthew G. Knepley if (rsize[n] > 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Only support creating a single vertex in cell refinement, not %D", rsize[n]); 2458412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2459412e9a14SMatthew G. Knepley PetscInt vNew, off; 2460b5da9499SMatthew G. Knepley 2461412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &vNew);CHKERRQ(ierr); 2462412e9a14SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, vNew, &off);CHKERRQ(ierr); 2463eac51794SMatthew G. Knepley ierr = DMPlexSnapToGeomModel(dm, p, vcoords, &coordsNew[off]);CHKERRQ(ierr); 2464b5da9499SMatthew G. Knepley } 24659fc2a3f3SStefano Zampini } 2466412e9a14SMatthew G. Knepley } 2467412e9a14SMatthew G. Knepley } 2468412e9a14SMatthew G. Knepley /* Then set coordinates for cells by localizing */ 2469412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2470412e9a14SMatthew G. Knepley DMPolytopeType ct; 2471412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2472412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2473412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2474412e9a14SMatthew G. Knepley PetscBool isLocalized = PETSC_FALSE; 247590b157c4SStefano Zampini 2476412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2477412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2478412e9a14SMatthew G. Knepley if (localizeCells && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) { 2479412e9a14SMatthew G. Knepley PetscInt dof; 2480412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, p, &dof); CHKERRQ(ierr); 2481412e9a14SMatthew G. Knepley if (dof) isLocalized = PETSC_TRUE; 2482b5da9499SMatthew G. Knepley } 2483412e9a14SMatthew G. Knepley if (isLocalized) { 2484412e9a14SMatthew G. Knepley const PetscScalar *pcoords; 24859fc2a3f3SStefano Zampini 2486412e9a14SMatthew G. Knepley ierr = DMPlexPointLocalRead(cdm, p, coords, &pcoords);CHKERRQ(ierr); 2487412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2488412e9a14SMatthew G. Knepley const PetscInt Nr = rsize[n]; 248990b157c4SStefano Zampini 2490412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ct) != DMPolytopeTypeGetDim(rct[n])) continue; 2491412e9a14SMatthew G. Knepley for (r = 0; r < Nr; ++r) { 2492412e9a14SMatthew G. Knepley PetscInt pNew, offNew; 249390b157c4SStefano Zampini 2494412e9a14SMatthew G. Knepley /* It looks like Stefano and Lisandro are allowing localized coordinates without defining the periodic boundary, which means that 2495412e9a14SMatthew G. Knepley DMLocalizeCoordinate_Internal() will not work. Localized coordinates will have to have obtained by the affine map of the larger 2496412e9a14SMatthew G. Knepley cell to the ones it produces. */ 2497412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 2498412e9a14SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, pNew, &offNew);CHKERRQ(ierr); 2499412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapLocalizedCoordinates(cr, ct, rct[n], r, pcoords, &coordsNew[offNew]);CHKERRQ(ierr); 250090b157c4SStefano Zampini } 250190b157c4SStefano Zampini } 250290b157c4SStefano Zampini } 250390b157c4SStefano Zampini } 2504412e9a14SMatthew G. Knepley ierr = VecRestoreArrayRead(coordsLocal, &coords);CHKERRQ(ierr); 2505412e9a14SMatthew G. Knepley ierr = VecRestoreArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr); 2506412e9a14SMatthew G. Knepley ierr = DMSetCoordinatesLocal(rdm, coordsLocalNew);CHKERRQ(ierr); 2507412e9a14SMatthew G. Knepley /* TODO Stefano has a final reduction if some hybrid coordinates cannot be found. (needcoords) Should not be needed. */ 2508412e9a14SMatthew G. Knepley ierr = VecDestroy(&coordsLocalNew);CHKERRQ(ierr); 250975d3a19aSMatthew G. Knepley ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 2510412e9a14SMatthew G. Knepley if (!localizeCells) {ierr = DMLocalizeCoordinates(rdm);CHKERRQ(ierr);} 251175d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 251275d3a19aSMatthew G. Knepley } 251375d3a19aSMatthew G. Knepley 2514963fc26aSMatthew G. Knepley /*@ 2515963fc26aSMatthew G. Knepley DMPlexCreateProcessSF - Create an SF which just has process connectivity 2516963fc26aSMatthew G. Knepley 2517d083f849SBarry Smith Collective on dm 2518963fc26aSMatthew G. Knepley 2519963fc26aSMatthew G. Knepley Input Parameters: 2520963fc26aSMatthew G. Knepley + dm - The DM 2521963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity 2522963fc26aSMatthew G. Knepley 2523963fc26aSMatthew G. Knepley Output Parameters: 2524963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL 2525963fc26aSMatthew G. Knepley - sfProcess - An SF encoding the process connectivity, or NULL 2526963fc26aSMatthew G. Knepley 2527963fc26aSMatthew G. Knepley Level: developer 2528963fc26aSMatthew G. Knepley 2529963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 2530963fc26aSMatthew G. Knepley @*/ 2531963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 253275d3a19aSMatthew G. Knepley { 253375d3a19aSMatthew G. Knepley PetscInt numRoots, numLeaves, l; 253475d3a19aSMatthew G. Knepley const PetscInt *localPoints; 253575d3a19aSMatthew G. Knepley const PetscSFNode *remotePoints; 253675d3a19aSMatthew G. Knepley PetscInt *localPointsNew; 253775d3a19aSMatthew G. Knepley PetscSFNode *remotePointsNew; 253875d3a19aSMatthew G. Knepley PetscInt *ranks, *ranksNew; 25399852e123SBarry Smith PetscMPIInt size; 254075d3a19aSMatthew G. Knepley PetscErrorCode ierr; 254175d3a19aSMatthew G. Knepley 254275d3a19aSMatthew G. Knepley PetscFunctionBegin; 2543963fc26aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2544963fc26aSMatthew G. Knepley PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 2545963fc26aSMatthew G. Knepley if (processRanks) {PetscValidPointer(processRanks, 3);} 2546963fc26aSMatthew G. Knepley if (sfProcess) {PetscValidPointer(sfProcess, 4);} 25479852e123SBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 254875d3a19aSMatthew G. Knepley ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 2549785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 255075d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 255175d3a19aSMatthew G. Knepley ranks[l] = remotePoints[l].rank; 255275d3a19aSMatthew G. Knepley } 255375d3a19aSMatthew G. Knepley ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 2554785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 2555785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 2556785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 255775d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 255875d3a19aSMatthew G. Knepley ranksNew[l] = ranks[l]; 255975d3a19aSMatthew G. Knepley localPointsNew[l] = l; 256075d3a19aSMatthew G. Knepley remotePointsNew[l].index = 0; 256175d3a19aSMatthew G. Knepley remotePointsNew[l].rank = ranksNew[l]; 256275d3a19aSMatthew G. Knepley } 256375d3a19aSMatthew G. Knepley ierr = PetscFree(ranks);CHKERRQ(ierr); 2564963fc26aSMatthew G. Knepley if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 2565963fc26aSMatthew G. Knepley else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 2566963fc26aSMatthew G. Knepley if (sfProcess) { 256775d3a19aSMatthew G. Knepley ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 2568963fc26aSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 256975d3a19aSMatthew G. Knepley ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 25709852e123SBarry Smith ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 2571963fc26aSMatthew G. Knepley } 257275d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 257375d3a19aSMatthew G. Knepley } 257475d3a19aSMatthew G. Knepley 2575412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateSF(DMPlexCellRefiner cr, DM rdm) 257675d3a19aSMatthew G. Knepley { 2577412e9a14SMatthew G. Knepley DM dm = cr->dm; 2578412e9a14SMatthew G. Knepley DMPlexCellRefiner *crRem; 257975d3a19aSMatthew G. Knepley PetscSF sf, sfNew, sfProcess; 258075d3a19aSMatthew G. Knepley IS processRanks; 2581412e9a14SMatthew G. Knepley MPI_Datatype ctType; 258275d3a19aSMatthew G. Knepley PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 258375d3a19aSMatthew G. Knepley const PetscInt *localPoints, *neighbors; 258475d3a19aSMatthew G. Knepley const PetscSFNode *remotePoints; 258575d3a19aSMatthew G. Knepley PetscInt *localPointsNew; 258675d3a19aSMatthew G. Knepley PetscSFNode *remotePointsNew; 2587412e9a14SMatthew G. Knepley PetscInt *ctStartRem, *ctStartNewRem; 2588412e9a14SMatthew G. Knepley PetscInt ctSize = DM_NUM_POLYTOPES+1, numNeighbors, n, pStartNew, pEndNew, pNew, pNewRem; 258975d3a19aSMatthew G. Knepley PetscErrorCode ierr; 259075d3a19aSMatthew G. Knepley 259175d3a19aSMatthew G. Knepley PetscFunctionBegin; 259275d3a19aSMatthew G. Knepley ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 259375d3a19aSMatthew G. Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 259475d3a19aSMatthew G. Knepley ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 2595add09238SMatthew G. Knepley /* Calculate size of new SF */ 259675d3a19aSMatthew G. Knepley ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 259775d3a19aSMatthew G. Knepley if (numRoots < 0) PetscFunctionReturn(0); 259875d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 259975d3a19aSMatthew G. Knepley const PetscInt p = localPoints[l]; 2600412e9a14SMatthew G. Knepley DMPolytopeType ct; 2601412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2602412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2603412e9a14SMatthew G. Knepley PetscInt Nct, n; 260475d3a19aSMatthew G. Knepley 2605412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2606412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2607412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) numLeavesNew += rsize[n]; 26080314a74cSLawrence Mitchell } 2609412e9a14SMatthew G. Knepley /* Communicate ctStart and cStartNew for each remote rank */ 261075d3a19aSMatthew G. Knepley ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 261175d3a19aSMatthew G. Knepley ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 2612412e9a14SMatthew G. Knepley ierr = PetscMalloc2(ctSize*numNeighbors, &ctStartRem, ctSize*numNeighbors, &ctStartNewRem);CHKERRQ(ierr); 2613412e9a14SMatthew G. Knepley ierr = MPI_Type_contiguous(ctSize, MPIU_INT, &ctType);CHKERRQ(ierr); 2614412e9a14SMatthew G. Knepley ierr = MPI_Type_commit(&ctType);CHKERRQ(ierr); 2615412e9a14SMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr); 2616412e9a14SMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr); 2617412e9a14SMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr); 2618412e9a14SMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr); 2619412e9a14SMatthew G. Knepley ierr = MPI_Type_free(&ctType);CHKERRQ(ierr); 262075d3a19aSMatthew G. Knepley ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 2621412e9a14SMatthew G. Knepley ierr = PetscMalloc1(numNeighbors, &crRem);CHKERRQ(ierr); 2622412e9a14SMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) { 2623412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &crRem[n]);CHKERRQ(ierr); 2624412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetStarts(crRem[n], &ctStartRem[n*ctSize], &ctStartNewRem[n*ctSize]); 2625412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(crRem[n]);CHKERRQ(ierr); 2626412e9a14SMatthew G. Knepley } 2627412e9a14SMatthew G. Knepley ierr = PetscFree2(ctStartRem, ctStartNewRem);CHKERRQ(ierr); 262875d3a19aSMatthew G. Knepley /* Calculate new point SF */ 2629785e854fSJed Brown ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 2630785e854fSJed Brown ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 263175d3a19aSMatthew G. Knepley ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 263275d3a19aSMatthew G. Knepley for (l = 0, m = 0; l < numLeaves; ++l) { 263375d3a19aSMatthew G. Knepley PetscInt p = localPoints[l]; 2634412e9a14SMatthew G. Knepley PetscInt pRem = remotePoints[l].index; 2635412e9a14SMatthew G. Knepley PetscMPIInt rankRem = remotePoints[l].rank; 2636412e9a14SMatthew G. Knepley DMPolytopeType ct; 2637412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2638412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2639412e9a14SMatthew G. Knepley PetscInt neighbor, Nct, n, r; 264075d3a19aSMatthew G. Knepley 2641412e9a14SMatthew G. Knepley ierr = PetscFindInt(rankRem, numNeighbors, neighbors, &neighbor);CHKERRQ(ierr); 2642412e9a14SMatthew G. Knepley if (neighbor < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rankRem); 2643412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2644412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2645412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2646412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2647412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 2648412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(crRem[neighbor], ct, rct[n], pRem, r, &pNewRem);CHKERRQ(ierr); 2649412e9a14SMatthew G. Knepley localPointsNew[m] = pNew; 2650412e9a14SMatthew G. Knepley remotePointsNew[m].index = pNewRem; 2651412e9a14SMatthew G. Knepley remotePointsNew[m].rank = rankRem; 26520314a74cSLawrence Mitchell ++m; 26530314a74cSLawrence Mitchell } 26546ce3c06aSMatthew G. Knepley } 26556ce3c06aSMatthew G. Knepley } 2656412e9a14SMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) {ierr = DMPlexCellRefinerDestroy(&crRem[n]);CHKERRQ(ierr);} 2657412e9a14SMatthew G. Knepley ierr = PetscFree(crRem);CHKERRQ(ierr); 2658d7eabd03SStefano Zampini if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew); 265975d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 266075d3a19aSMatthew G. Knepley ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 2661ba3c3d50SMatthew G. Knepley { 2662ba3c3d50SMatthew G. Knepley PetscSFNode *rp, *rtmp; 2663ba3c3d50SMatthew G. Knepley PetscInt *lp, *idx, *ltmp, i; 2664ba3c3d50SMatthew G. Knepley 2665ba3c3d50SMatthew G. Knepley /* SF needs sorted leaves to correct calculate Gather */ 2666ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &idx);CHKERRQ(ierr); 2667ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 2668ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 2669c7c54c77SMatthew G. Knepley for (i = 0; i < numLeavesNew; ++i) { 2670d7eabd03SStefano Zampini if ((localPointsNew[i] < pStartNew) || (localPointsNew[i] >= pEndNew)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local SF point %D (%D) not in [%D, %D)", localPointsNew[i], i, pStartNew, pEndNew); 2671c7c54c77SMatthew G. Knepley idx[i] = i; 2672c7c54c77SMatthew G. Knepley } 2673ba3c3d50SMatthew G. Knepley ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 2674ba3c3d50SMatthew G. Knepley for (i = 0; i < numLeavesNew; ++i) { 2675ba3c3d50SMatthew G. Knepley lp[i] = localPointsNew[idx[i]]; 2676ba3c3d50SMatthew G. Knepley rp[i] = remotePointsNew[idx[i]]; 2677ba3c3d50SMatthew G. Knepley } 2678ba3c3d50SMatthew G. Knepley ltmp = localPointsNew; 2679ba3c3d50SMatthew G. Knepley localPointsNew = lp; 2680ba3c3d50SMatthew G. Knepley rtmp = remotePointsNew; 2681ba3c3d50SMatthew G. Knepley remotePointsNew = rp; 2682ba3c3d50SMatthew G. Knepley ierr = PetscFree(idx);CHKERRQ(ierr); 2683ba3c3d50SMatthew G. Knepley ierr = PetscFree(ltmp);CHKERRQ(ierr); 2684ba3c3d50SMatthew G. Knepley ierr = PetscFree(rtmp);CHKERRQ(ierr); 2685ba3c3d50SMatthew G. Knepley } 268675d3a19aSMatthew G. Knepley ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 268775d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 268875d3a19aSMatthew G. Knepley } 268975d3a19aSMatthew G. Knepley 2690e7887635SMatthew G. Knepley static PetscErrorCode RefineLabel_Internal(DMPlexCellRefiner cr, DMLabel label, DMLabel labelNew) 269175d3a19aSMatthew G. Knepley { 2692412e9a14SMatthew G. Knepley DM dm = cr->dm; 2693e7887635SMatthew G. Knepley IS valueIS; 2694e7887635SMatthew G. Knepley const PetscInt *values; 2695e7887635SMatthew G. Knepley PetscInt defVal, Nv, val; 269675d3a19aSMatthew G. Knepley PetscErrorCode ierr; 269775d3a19aSMatthew G. Knepley 269875d3a19aSMatthew G. Knepley PetscFunctionBegin; 26995aa44df4SToby Isaac ierr = DMLabelGetDefaultValue(label, &defVal);CHKERRQ(ierr); 27005aa44df4SToby Isaac ierr = DMLabelSetDefaultValue(labelNew, defVal);CHKERRQ(ierr); 270175d3a19aSMatthew G. Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 2702e7887635SMatthew G. Knepley ierr = ISGetLocalSize(valueIS, &Nv);CHKERRQ(ierr); 270375d3a19aSMatthew G. Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 2704e7887635SMatthew G. Knepley for (val = 0; val < Nv; ++val) { 270575d3a19aSMatthew G. Knepley IS pointIS; 270675d3a19aSMatthew G. Knepley const PetscInt *points; 2707412e9a14SMatthew G. Knepley PetscInt numPoints, p; 270875d3a19aSMatthew G. Knepley 27092bc5314cSMichael Lange /* Ensure refined label is created with same number of strata as 27102bc5314cSMichael Lange * original (even if no entries here). */ 2711ad8374ffSToby Isaac ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 2712412e9a14SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 2713412e9a14SMatthew G. Knepley ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 2714412e9a14SMatthew G. Knepley ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 2715412e9a14SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 2716412e9a14SMatthew G. Knepley const PetscInt point = points[p]; 2717412e9a14SMatthew G. Knepley DMPolytopeType ct; 2718412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2719412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2720e7887635SMatthew G. Knepley PetscInt Nct, n, r, pNew; 2721412e9a14SMatthew G. Knepley 2722412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, point, &ct);CHKERRQ(ierr); 2723412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2724412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2725412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2726412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], point, r, &pNew);CHKERRQ(ierr); 2727412e9a14SMatthew G. Knepley ierr = DMLabelSetValue(labelNew, pNew, values[val]);CHKERRQ(ierr); 272827fcede3SMatthew G. Knepley } 272975d3a19aSMatthew G. Knepley } 273075d3a19aSMatthew G. Knepley } 273175d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 273275d3a19aSMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 273375d3a19aSMatthew G. Knepley } 273475d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 273575d3a19aSMatthew G. Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 2736e7887635SMatthew G. Knepley PetscFunctionReturn(0); 2737e7887635SMatthew G. Knepley } 2738e7887635SMatthew G. Knepley 2739e7887635SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateLabels(DMPlexCellRefiner cr, DM rdm) 2740e7887635SMatthew G. Knepley { 2741e7887635SMatthew G. Knepley DM dm = cr->dm; 2742e7887635SMatthew G. Knepley PetscInt numLabels, l; 2743e7887635SMatthew G. Knepley PetscErrorCode ierr; 2744e7887635SMatthew G. Knepley 2745e7887635SMatthew G. Knepley PetscFunctionBegin; 2746e7887635SMatthew G. Knepley ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 2747e7887635SMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 2748e7887635SMatthew G. Knepley DMLabel label, labelNew; 2749e7887635SMatthew G. Knepley const char *lname; 2750e7887635SMatthew G. Knepley PetscBool isDepth, isCellType; 2751e7887635SMatthew G. Knepley 2752e7887635SMatthew G. Knepley ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 2753e7887635SMatthew G. Knepley ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 2754e7887635SMatthew G. Knepley if (isDepth) continue; 2755e7887635SMatthew G. Knepley ierr = PetscStrcmp(lname, "celltype", &isCellType);CHKERRQ(ierr); 2756e7887635SMatthew G. Knepley if (isCellType) continue; 2757e7887635SMatthew G. Knepley ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 2758e7887635SMatthew G. Knepley ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 2759e7887635SMatthew G. Knepley ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 2760e7887635SMatthew G. Knepley ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr); 276175d3a19aSMatthew G. Knepley } 276275d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 276375d3a19aSMatthew G. Knepley } 276475d3a19aSMatthew G. Knepley 276575d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */ 2766412e9a14SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform(DM dm, DMPlexCellRefiner cr, DM *dmRefined) 276775d3a19aSMatthew G. Knepley { 276875d3a19aSMatthew G. Knepley DM rdm; 2769412e9a14SMatthew G. Knepley PetscInt dim, embedDim, depth; 277075d3a19aSMatthew G. Knepley PetscErrorCode ierr; 277175d3a19aSMatthew G. Knepley 277275d3a19aSMatthew G. Knepley PetscFunctionBegin; 2773412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 277475d3a19aSMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 277575d3a19aSMatthew G. Knepley ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 2776c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 2777c73cfb54SMatthew G. Knepley ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 27786dcbd917SStefano Zampini ierr = DMGetCoordinateDim(dm, &embedDim);CHKERRQ(ierr); 27796dcbd917SStefano Zampini ierr = DMSetCoordinateDim(rdm, embedDim);CHKERRQ(ierr); 278075d3a19aSMatthew G. Knepley /* Calculate number of new points of each depth */ 278175d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 27821e573d11SMatthew G. Knepley if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 278375d3a19aSMatthew G. Knepley /* Step 1: Set chart */ 2784412e9a14SMatthew G. Knepley ierr = DMPlexSetChart(rdm, 0, cr->ctStartNew[cr->ctOrder[DM_NUM_POLYTOPES]]);CHKERRQ(ierr); 27856d7373e8SToby Isaac /* Step 2: Set cone/support sizes (automatically stratifies) */ 2786412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetConeSizes(cr, rdm);CHKERRQ(ierr); 278775d3a19aSMatthew G. Knepley /* Step 3: Setup refined DM */ 278875d3a19aSMatthew G. Knepley ierr = DMSetUp(rdm);CHKERRQ(ierr); 27896d7373e8SToby Isaac /* Step 4: Set cones and supports (automatically symmetrizes) */ 2790412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetCones(cr, rdm);CHKERRQ(ierr); 27916d7373e8SToby Isaac /* Step 5: Create pointSF */ 2792412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreateSF(cr, rdm);CHKERRQ(ierr); 27936d7373e8SToby Isaac /* Step 6: Create labels */ 2794412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreateLabels(cr, rdm);CHKERRQ(ierr); 27956d7373e8SToby Isaac /* Step 7: Set coordinates */ 2796412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetCoordinates(cr, rdm);CHKERRQ(ierr); 279775d3a19aSMatthew G. Knepley *dmRefined = rdm; 279875d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 279975d3a19aSMatthew G. Knepley } 280075d3a19aSMatthew G. Knepley 28012389894bSMatthew G. Knepley /*@ 28022389894bSMatthew G. Knepley DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 28032389894bSMatthew G. Knepley 28042389894bSMatthew G. Knepley Input Parameter: 28052389894bSMatthew G. Knepley . dm - The coarse DM 28062389894bSMatthew G. Knepley 28072389894bSMatthew G. Knepley Output Parameter: 28082389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh 28092389894bSMatthew G. Knepley 28102389894bSMatthew G. Knepley Level: developer 28112389894bSMatthew G. Knepley 281297d8846cSMatthew Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetSubpointIS() 28132389894bSMatthew G. Knepley @*/ 28142389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 28152389894bSMatthew G. Knepley { 2816412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 2817412e9a14SMatthew G. Knepley PetscInt *fpoints; 2818412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p, vStart, vEnd, v, vNew; 28192389894bSMatthew G. Knepley PetscErrorCode ierr; 28202389894bSMatthew G. Knepley 28212389894bSMatthew G. Knepley PetscFunctionBegin; 28222389894bSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 28232389894bSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 2824412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr); 2825412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 28262389894bSMatthew G. Knepley ierr = PetscMalloc1(pEnd-pStart, &fpoints);CHKERRQ(ierr); 28272389894bSMatthew G. Knepley for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 2828412e9a14SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 2829412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, DM_POLYTOPE_POINT, DM_POLYTOPE_POINT, p, 0, &vNew);CHKERRQ(ierr); 2830412e9a14SMatthew G. Knepley fpoints[v-pStart] = vNew; 28312389894bSMatthew G. Knepley } 2832412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 28332389894bSMatthew G. Knepley ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 28342389894bSMatthew G. Knepley PetscFunctionReturn(0); 28352389894bSMatthew G. Knepley } 28362389894bSMatthew G. Knepley 28370e2b6761SMatthew G. Knepley /*@ 28380e2b6761SMatthew G. Knepley DMPlexSetRefinementUniform - Set the flag for uniform refinement 28390e2b6761SMatthew G. Knepley 28400e2b6761SMatthew G. Knepley Input Parameters: 28410e2b6761SMatthew G. Knepley + dm - The DM 28420e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement 28430e2b6761SMatthew G. Knepley 28440e2b6761SMatthew G. Knepley Level: developer 28450e2b6761SMatthew G. Knepley 28460e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 28470e2b6761SMatthew G. Knepley @*/ 284875d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 284975d3a19aSMatthew G. Knepley { 285075d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 285175d3a19aSMatthew G. Knepley 285275d3a19aSMatthew G. Knepley PetscFunctionBegin; 285375d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 285475d3a19aSMatthew G. Knepley mesh->refinementUniform = refinementUniform; 285575d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 285675d3a19aSMatthew G. Knepley } 285775d3a19aSMatthew G. Knepley 28580e2b6761SMatthew G. Knepley /*@ 28590e2b6761SMatthew G. Knepley DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 28600e2b6761SMatthew G. Knepley 28610e2b6761SMatthew G. Knepley Input Parameter: 28620e2b6761SMatthew G. Knepley . dm - The DM 28630e2b6761SMatthew G. Knepley 28640e2b6761SMatthew G. Knepley Output Parameter: 28650e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement 28660e2b6761SMatthew G. Knepley 28670e2b6761SMatthew G. Knepley Level: developer 28680e2b6761SMatthew G. Knepley 28690e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 28700e2b6761SMatthew G. Knepley @*/ 287175d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 287275d3a19aSMatthew G. Knepley { 287375d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 287475d3a19aSMatthew G. Knepley 287575d3a19aSMatthew G. Knepley PetscFunctionBegin; 287675d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 287775d3a19aSMatthew G. Knepley PetscValidPointer(refinementUniform, 2); 287875d3a19aSMatthew G. Knepley *refinementUniform = mesh->refinementUniform; 287975d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 288075d3a19aSMatthew G. Knepley } 288175d3a19aSMatthew G. Knepley 28820e2b6761SMatthew G. Knepley /*@ 28830e2b6761SMatthew G. Knepley DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 28840e2b6761SMatthew G. Knepley 28850e2b6761SMatthew G. Knepley Input Parameters: 28860e2b6761SMatthew G. Knepley + dm - The DM 28870e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh 28880e2b6761SMatthew G. Knepley 28890e2b6761SMatthew G. Knepley Level: developer 28900e2b6761SMatthew G. Knepley 28910e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 28920e2b6761SMatthew G. Knepley @*/ 289375d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 289475d3a19aSMatthew G. Knepley { 289575d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 289675d3a19aSMatthew G. Knepley 289775d3a19aSMatthew G. Knepley PetscFunctionBegin; 289875d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 289975d3a19aSMatthew G. Knepley mesh->refinementLimit = refinementLimit; 290075d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 290175d3a19aSMatthew G. Knepley } 290275d3a19aSMatthew G. Knepley 29030e2b6761SMatthew G. Knepley /*@ 29040e2b6761SMatthew G. Knepley DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 29050e2b6761SMatthew G. Knepley 29060e2b6761SMatthew G. Knepley Input Parameter: 29070e2b6761SMatthew G. Knepley . dm - The DM 29080e2b6761SMatthew G. Knepley 29090e2b6761SMatthew G. Knepley Output Parameter: 29100e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh 29110e2b6761SMatthew G. Knepley 29120e2b6761SMatthew G. Knepley Level: developer 29130e2b6761SMatthew G. Knepley 29140e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 29150e2b6761SMatthew G. Knepley @*/ 291675d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 291775d3a19aSMatthew G. Knepley { 291875d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 291975d3a19aSMatthew G. Knepley 292075d3a19aSMatthew G. Knepley PetscFunctionBegin; 292175d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 292275d3a19aSMatthew G. Knepley PetscValidPointer(refinementLimit, 2); 292375d3a19aSMatthew G. Knepley /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 292475d3a19aSMatthew G. Knepley *refinementLimit = mesh->refinementLimit; 292575d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 292675d3a19aSMatthew G. Knepley } 292775d3a19aSMatthew G. Knepley 2928b28003e6SMatthew G. Knepley /*@ 2929b28003e6SMatthew G. Knepley DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 2930b28003e6SMatthew G. Knepley 2931b28003e6SMatthew G. Knepley Input Parameters: 2932b28003e6SMatthew G. Knepley + dm - The DM 2933b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh 2934b28003e6SMatthew G. Knepley 2935b28003e6SMatthew G. Knepley Note: The calling sequence is refinementFunc(coords, limit) 2936b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid 2937b28003e6SMatthew G. Knepley $ limit - The maximum cell volume for a cell containing this point 2938b28003e6SMatthew G. Knepley 2939b28003e6SMatthew G. Knepley Level: developer 2940b28003e6SMatthew G. Knepley 2941b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 2942b28003e6SMatthew G. Knepley @*/ 2943b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 2944b28003e6SMatthew G. Knepley { 2945b28003e6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2946b28003e6SMatthew G. Knepley 2947b28003e6SMatthew G. Knepley PetscFunctionBegin; 2948b28003e6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2949b28003e6SMatthew G. Knepley mesh->refinementFunc = refinementFunc; 2950b28003e6SMatthew G. Knepley PetscFunctionReturn(0); 2951b28003e6SMatthew G. Knepley } 2952b28003e6SMatthew G. Knepley 2953b28003e6SMatthew G. Knepley /*@ 2954b28003e6SMatthew G. Knepley DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 2955b28003e6SMatthew G. Knepley 2956b28003e6SMatthew G. Knepley Input Parameter: 2957b28003e6SMatthew G. Knepley . dm - The DM 2958b28003e6SMatthew G. Knepley 2959b28003e6SMatthew G. Knepley Output Parameter: 2960b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh 2961b28003e6SMatthew G. Knepley 2962b28003e6SMatthew G. Knepley Note: The calling sequence is refinementFunc(coords, limit) 2963b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid 2964b28003e6SMatthew G. Knepley $ limit - The maximum cell volume for a cell containing this point 2965b28003e6SMatthew G. Knepley 2966b28003e6SMatthew G. Knepley Level: developer 2967b28003e6SMatthew G. Knepley 2968b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 2969b28003e6SMatthew G. Knepley @*/ 2970b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 2971b28003e6SMatthew G. Knepley { 2972b28003e6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2973b28003e6SMatthew G. Knepley 2974b28003e6SMatthew G. Knepley PetscFunctionBegin; 2975b28003e6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2976b28003e6SMatthew G. Knepley PetscValidPointer(refinementFunc, 2); 2977b28003e6SMatthew G. Knepley *refinementFunc = mesh->refinementFunc; 2978b28003e6SMatthew G. Knepley PetscFunctionReturn(0); 2979b28003e6SMatthew G. Knepley } 2980b28003e6SMatthew G. Knepley 2981e7887635SMatthew G. Knepley static PetscErrorCode RefineDiscLabels_Internal(DMPlexCellRefiner cr, DM rdm) 2982e7887635SMatthew G. Knepley { 2983e7887635SMatthew G. Knepley DM dm = cr->dm; 2984e7887635SMatthew G. Knepley PetscInt Nf, f, Nds, s; 2985e7887635SMatthew G. Knepley PetscErrorCode ierr; 2986e7887635SMatthew G. Knepley 2987e7887635SMatthew G. Knepley PetscFunctionBegin; 2988e7887635SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 2989e7887635SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2990e7887635SMatthew G. Knepley DMLabel label, labelNew; 2991e7887635SMatthew G. Knepley PetscObject obj; 2992e7887635SMatthew G. Knepley const char *lname; 2993e7887635SMatthew G. Knepley 2994e7887635SMatthew G. Knepley ierr = DMGetField(rdm, f, &label, &obj);CHKERRQ(ierr); 2995e7887635SMatthew G. Knepley if (!label) continue; 2996e7887635SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 2997e7887635SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew);CHKERRQ(ierr); 2998e7887635SMatthew G. Knepley ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr); 2999e7887635SMatthew G. Knepley ierr = DMSetField_Internal(rdm, f, labelNew, obj);CHKERRQ(ierr); 3000e7887635SMatthew G. Knepley ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr); 3001e7887635SMatthew G. Knepley } 3002e7887635SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 3003e7887635SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 3004e7887635SMatthew G. Knepley DMLabel label, labelNew; 3005e7887635SMatthew G. Knepley const char *lname; 3006e7887635SMatthew G. Knepley 3007e7887635SMatthew G. Knepley ierr = DMGetRegionNumDS(rdm, s, &label, NULL, NULL);CHKERRQ(ierr); 3008e7887635SMatthew G. Knepley if (!label) continue; 3009e7887635SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 3010e7887635SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew);CHKERRQ(ierr); 3011e7887635SMatthew G. Knepley ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr); 3012e7887635SMatthew G. Knepley ierr = DMSetRegionNumDS(rdm, s, labelNew, NULL, NULL);CHKERRQ(ierr); 3013e7887635SMatthew G. Knepley ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr); 3014e7887635SMatthew G. Knepley } 3015e7887635SMatthew G. Knepley PetscFunctionReturn(0); 3016e7887635SMatthew G. Knepley } 3017e7887635SMatthew G. Knepley 30180d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 30190d1cd5e0SMatthew G. Knepley { 3020492b8470SStefano Zampini PetscBool isUniform; 3021412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 30220d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 30230d1cd5e0SMatthew G. Knepley 30240d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 30250d1cd5e0SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 3026412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-initref_dm_view");CHKERRQ(ierr); 30270d1cd5e0SMatthew G. Knepley if (isUniform) { 3028492b8470SStefano Zampini PetscBool localized; 30290d1cd5e0SMatthew G. Knepley 3030412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr); 3031412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 3032492b8470SStefano Zampini ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 3033412e9a14SMatthew G. Knepley ierr = DMPlexRefineUniform(dm, cr, dmRefined);CHKERRQ(ierr); 30349a7e3c0aSMatthew G. Knepley ierr = DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);CHKERRQ(ierr); 3035e7887635SMatthew G. Knepley ierr = DMCopyDisc(dm, *dmRefined);CHKERRQ(ierr); 3036e7887635SMatthew G. Knepley ierr = RefineDiscLabels_Internal(cr, *dmRefined);CHKERRQ(ierr); 30370d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 3038412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 30390d1cd5e0SMatthew G. Knepley } else { 30400d1cd5e0SMatthew G. Knepley ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 30410d1cd5e0SMatthew G. Knepley } 30420d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 30430d1cd5e0SMatthew G. Knepley } 30440d1cd5e0SMatthew G. Knepley 30450d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 30460d1cd5e0SMatthew G. Knepley { 30470d1cd5e0SMatthew G. Knepley DM cdm = dm; 30480d1cd5e0SMatthew G. Knepley PetscInt r; 30490d1cd5e0SMatthew G. Knepley PetscBool isUniform, localized; 30500d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 30510d1cd5e0SMatthew G. Knepley 30520d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 30530d1cd5e0SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 30540d1cd5e0SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 30550d1cd5e0SMatthew G. Knepley if (isUniform) { 30560d1cd5e0SMatthew G. Knepley for (r = 0; r < nlevels; ++r) { 3057412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 30580d1cd5e0SMatthew G. Knepley 3059412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(cdm, &cr);CHKERRQ(ierr); 3060412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 3061412e9a14SMatthew G. Knepley ierr = DMPlexRefineUniform(cdm, cr, &dmRefined[r]);CHKERRQ(ierr); 30629a7e3c0aSMatthew G. Knepley ierr = DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);CHKERRQ(ierr); 30639a7e3c0aSMatthew G. Knepley ierr = DMSetRefineLevel(dmRefined[r], cdm->levelup+1);CHKERRQ(ierr); 3064e7887635SMatthew G. Knepley ierr = DMCopyDisc(cdm, dmRefined[r]);CHKERRQ(ierr); 3065e7887635SMatthew G. Knepley ierr = RefineDiscLabels_Internal(cr, dmRefined[r]);CHKERRQ(ierr); 30660d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 30670d1cd5e0SMatthew G. Knepley ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 30680d1cd5e0SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 30690d1cd5e0SMatthew G. Knepley cdm = dmRefined[r]; 3070412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 30710d1cd5e0SMatthew G. Knepley } 30720d1cd5e0SMatthew G. Knepley } else { 30730d1cd5e0SMatthew G. Knepley for (r = 0; r < nlevels; ++r) { 30740d1cd5e0SMatthew G. Knepley ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 3075e7887635SMatthew G. Knepley ierr = DMCopyDisc(cdm, dmRefined[r]);CHKERRQ(ierr); 30760d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 30770d1cd5e0SMatthew G. Knepley if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 30780d1cd5e0SMatthew G. Knepley ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 30790d1cd5e0SMatthew G. Knepley cdm = dmRefined[r]; 30800d1cd5e0SMatthew G. Knepley } 30810d1cd5e0SMatthew G. Knepley } 30820d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 30830d1cd5e0SMatthew G. Knepley } 3084