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 53f2a96e3SMatthew G. Knepley PetscBool SBRcite = PETSC_FALSE; 63f2a96e3SMatthew G. Knepley const char SBRCitation[] = "@article{PlazaCarey2000,\n" 73f2a96e3SMatthew G. Knepley " title = {Local refinement of simplicial grids based on the skeleton},\n" 83f2a96e3SMatthew G. Knepley " journal = {Applied Numerical Mathematics},\n" 93f2a96e3SMatthew G. Knepley " author = {A. Plaza and Graham F. Carey},\n" 103f2a96e3SMatthew G. Knepley " volume = {32},\n" 113f2a96e3SMatthew G. Knepley " number = {3},\n" 123f2a96e3SMatthew G. Knepley " pages = {195--218},\n" 133f2a96e3SMatthew G. Knepley " doi = {10.1016/S0168-9274(99)00022-7},\n" 143f2a96e3SMatthew G. Knepley " year = {2000}\n}\n"; 153f2a96e3SMatthew G. Knepley 163f2a96e3SMatthew G. Knepley const char * const DMPlexCellRefinerTypes[] = {"Regular", "ToBox", "ToSimplex", "Alfeld2D", "Alfeld3D", "PowellSabin", "BoundaryLayer", "SBR", "DMPlexCellRefinerTypes", "DM_REFINER_", NULL}; 1775d3a19aSMatthew G. Knepley 1809789c4cSMatthew G. Knepley /* 1909789c4cSMatthew G. Knepley Note that j and invj are non-square: 2009789c4cSMatthew G. Knepley v0 + j x_face = x_cell 2109789c4cSMatthew G. Knepley invj (x_cell - v0) = x_face 2209789c4cSMatthew G. Knepley */ 23412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[]) 2409789c4cSMatthew G. Knepley { 2509789c4cSMatthew G. Knepley /* 2609789c4cSMatthew G. Knepley 2 2709789c4cSMatthew G. Knepley |\ 2809789c4cSMatthew G. Knepley | \ 2909789c4cSMatthew G. Knepley | \ 3009789c4cSMatthew G. Knepley | \ 3109789c4cSMatthew G. Knepley | \ 3209789c4cSMatthew G. Knepley | \ 3309789c4cSMatthew G. Knepley | \ 3409789c4cSMatthew G. Knepley 2 1 3509789c4cSMatthew G. Knepley | \ 3609789c4cSMatthew G. Knepley | \ 3709789c4cSMatthew G. Knepley | \ 3809789c4cSMatthew G. Knepley 0---0-------1 39412e9a14SMatthew G. Knepley v0[Nf][dc]: 3 x 2 40412e9a14SMatthew G. Knepley J[Nf][df][dc]: 3 x 1 x 2 41412e9a14SMatthew G. Knepley invJ[Nf][dc][df]: 3 x 2 x 1 42412e9a14SMatthew G. Knepley detJ[Nf]: 3 4309789c4cSMatthew G. Knepley */ 44412e9a14SMatthew G. Knepley static PetscReal tri_v0[] = {0.0, -1.0, 0.0, 0.0, -1.0, 0.0}; 45412e9a14SMatthew G. Knepley static PetscReal tri_J[] = {1.0, 0.0, -1.0, 1.0, 0.0, -1.0}; 46412e9a14SMatthew G. Knepley static PetscReal tri_invJ[] = {1.0, 0.0, -0.5, 0.5, 0.0, -1.0}; 47412e9a14SMatthew G. Knepley static PetscReal tri_detJ[] = {1.0, 1.414213562373095, 1.0}; 4809789c4cSMatthew G. Knepley /* 4909789c4cSMatthew G. Knepley 3---------2---------2 5009789c4cSMatthew G. Knepley | | 5109789c4cSMatthew G. Knepley | | 5209789c4cSMatthew G. Knepley | | 5309789c4cSMatthew G. Knepley 3 1 5409789c4cSMatthew G. Knepley | | 5509789c4cSMatthew G. Knepley | | 5609789c4cSMatthew G. Knepley | | 5709789c4cSMatthew G. Knepley 0---------0---------1 58412e9a14SMatthew G. Knepley 59412e9a14SMatthew G. Knepley v0[Nf][dc]: 4 x 2 60412e9a14SMatthew G. Knepley J[Nf][df][dc]: 4 x 1 x 2 61412e9a14SMatthew G. Knepley invJ[Nf][dc][df]: 4 x 2 x 1 62412e9a14SMatthew G. Knepley detJ[Nf]: 4 6309789c4cSMatthew G. Knepley */ 64412e9a14SMatthew G. Knepley static PetscReal quad_v0[] = {0.0, -1.0, 1.0, 0.0, 0.0, 1.0 -1.0, 0.0}; 65412e9a14SMatthew G. Knepley static PetscReal quad_J[] = {1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, -1.0}; 66412e9a14SMatthew G. Knepley static PetscReal quad_invJ[] = {1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, -1.0}; 67412e9a14SMatthew G. Knepley static PetscReal quad_detJ[] = {1.0, 1.0, 1.0, 1.0}; 68412e9a14SMatthew G. Knepley 69412e9a14SMatthew G. Knepley PetscFunctionBegin; 70412e9a14SMatthew G. Knepley switch (ct) { 71412e9a14SMatthew 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; 72412e9a14SMatthew 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; 7309789c4cSMatthew G. Knepley default: 74412e9a14SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 7509789c4cSMatthew G. Knepley } 7609789c4cSMatthew G. Knepley PetscFunctionReturn(0); 7709789c4cSMatthew G. Knepley } 7809789c4cSMatthew G. Knepley 79bed052eaSMatthew G. Knepley /* Gets the affine map from the original cell to each subcell */ 80412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetAffineTransforms_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[]) 81bed052eaSMatthew G. Knepley { 82260b6d3fSMatthew G. Knepley /* 83260b6d3fSMatthew G. Knepley 2 84260b6d3fSMatthew G. Knepley |\ 85260b6d3fSMatthew G. Knepley | \ 86260b6d3fSMatthew G. Knepley | \ 87260b6d3fSMatthew G. Knepley | \ 88260b6d3fSMatthew G. Knepley | C \ 89260b6d3fSMatthew G. Knepley | \ 90260b6d3fSMatthew G. Knepley | \ 91260b6d3fSMatthew G. Knepley 2---1---1 92260b6d3fSMatthew G. Knepley |\ D / \ 93260b6d3fSMatthew G. Knepley | 2 0 \ 94260b6d3fSMatthew G. Knepley |A \ / B \ 95260b6d3fSMatthew G. Knepley 0---0-------1 96260b6d3fSMatthew G. Knepley */ 97412e9a14SMatthew G. Knepley static PetscReal tri_v0[] = {-1.0, -1.0, 0.0, -1.0, -1.0, 0.0, 0.0, -1.0}; 98412e9a14SMatthew G. Knepley static PetscReal tri_J[] = {0.5, 0.0, 99412e9a14SMatthew G. Knepley 0.0, 0.5, 100412e9a14SMatthew G. Knepley 101412e9a14SMatthew G. Knepley 0.5, 0.0, 102412e9a14SMatthew G. Knepley 0.0, 0.5, 103412e9a14SMatthew G. Knepley 104412e9a14SMatthew G. Knepley 0.5, 0.0, 105412e9a14SMatthew G. Knepley 0.0, 0.5, 106412e9a14SMatthew G. Knepley 107412e9a14SMatthew G. Knepley 0.0, -0.5, 108412e9a14SMatthew G. Knepley 0.5, 0.5}; 109412e9a14SMatthew G. Knepley static PetscReal tri_invJ[] = {2.0, 0.0, 110412e9a14SMatthew G. Knepley 0.0, 2.0, 111412e9a14SMatthew G. Knepley 112412e9a14SMatthew G. Knepley 2.0, 0.0, 113412e9a14SMatthew G. Knepley 0.0, 2.0, 114412e9a14SMatthew G. Knepley 115412e9a14SMatthew G. Knepley 2.0, 0.0, 116412e9a14SMatthew G. Knepley 0.0, 2.0, 117412e9a14SMatthew G. Knepley 118412e9a14SMatthew G. Knepley 2.0, 2.0, 119412e9a14SMatthew G. Knepley -2.0, 0.0}; 120260b6d3fSMatthew G. Knepley /* 121260b6d3fSMatthew G. Knepley 3---------2---------2 122260b6d3fSMatthew G. Knepley | | | 123260b6d3fSMatthew G. Knepley | D 2 C | 124260b6d3fSMatthew G. Knepley | | | 125260b6d3fSMatthew G. Knepley 3----3----0----1----1 126260b6d3fSMatthew G. Knepley | | | 127260b6d3fSMatthew G. Knepley | A 0 B | 128260b6d3fSMatthew G. Knepley | | | 129260b6d3fSMatthew G. Knepley 0---------0---------1 130260b6d3fSMatthew G. Knepley */ 131412e9a14SMatthew G. Knepley static PetscReal quad_v0[] = {-1.0, -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0}; 132412e9a14SMatthew G. Knepley static PetscReal quad_J[] = {0.5, 0.0, 133412e9a14SMatthew G. Knepley 0.0, 0.5, 134412e9a14SMatthew G. Knepley 135412e9a14SMatthew G. Knepley 0.5, 0.0, 136412e9a14SMatthew G. Knepley 0.0, 0.5, 137412e9a14SMatthew G. Knepley 138412e9a14SMatthew G. Knepley 0.5, 0.0, 139412e9a14SMatthew G. Knepley 0.0, 0.5, 140412e9a14SMatthew G. Knepley 141412e9a14SMatthew G. Knepley 0.5, 0.0, 142412e9a14SMatthew G. Knepley 0.0, 0.5}; 143412e9a14SMatthew G. Knepley static PetscReal quad_invJ[] = {2.0, 0.0, 144412e9a14SMatthew G. Knepley 0.0, 2.0, 145412e9a14SMatthew G. Knepley 146412e9a14SMatthew G. Knepley 2.0, 0.0, 147412e9a14SMatthew G. Knepley 0.0, 2.0, 148412e9a14SMatthew G. Knepley 149412e9a14SMatthew G. Knepley 2.0, 0.0, 150412e9a14SMatthew G. Knepley 0.0, 2.0, 151412e9a14SMatthew G. Knepley 152412e9a14SMatthew G. Knepley 2.0, 0.0, 153412e9a14SMatthew G. Knepley 0.0, 2.0}; 154c1879b55SMatthew G. Knepley /* 155c1879b55SMatthew G. Knepley Bottom (viewed from top) Top 156c1879b55SMatthew G. Knepley 1---------2---------2 7---------2---------6 157c1879b55SMatthew G. Knepley | | | | | | 158c1879b55SMatthew G. Knepley | B 2 C | | H 2 G | 159c1879b55SMatthew G. Knepley | | | | | | 160c1879b55SMatthew G. Knepley 3----3----0----1----1 3----3----0----1----1 161c1879b55SMatthew G. Knepley | | | | | | 162c1879b55SMatthew G. Knepley | A 0 D | | E 0 F | 163c1879b55SMatthew G. Knepley | | | | | | 164c1879b55SMatthew G. Knepley 0---------0---------3 4---------0---------5 165c1879b55SMatthew G. Knepley */ 166412e9a14SMatthew 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, 167412e9a14SMatthew 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}; 168412e9a14SMatthew G. Knepley static PetscReal hex_J[] = {0.5, 0.0, 0.0, 169412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 170412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 171bed052eaSMatthew G. Knepley 172412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 173412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 174412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 175412e9a14SMatthew G. Knepley 176412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 177412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 178412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 179412e9a14SMatthew G. Knepley 180412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 181412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 182412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 183412e9a14SMatthew G. Knepley 184412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 185412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 186412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 187412e9a14SMatthew G. Knepley 188412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 189412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 190412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 191412e9a14SMatthew G. Knepley 192412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 193412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 194412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 195412e9a14SMatthew G. Knepley 196412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 197412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 198412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5}; 199412e9a14SMatthew G. Knepley static PetscReal hex_invJ[] = {2.0, 0.0, 0.0, 200412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 201412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 202412e9a14SMatthew G. Knepley 203412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 204412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 205412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 206412e9a14SMatthew G. Knepley 207412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 208412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 209412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 210412e9a14SMatthew G. Knepley 211412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 212412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 213412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 214412e9a14SMatthew G. Knepley 215412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 216412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 217412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 218412e9a14SMatthew G. Knepley 219412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 220412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 221412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 222412e9a14SMatthew G. Knepley 223412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 224412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 225412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 226412e9a14SMatthew G. Knepley 227412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 228412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 229412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0}; 230bed052eaSMatthew G. Knepley 231bed052eaSMatthew G. Knepley PetscFunctionBegin; 232412e9a14SMatthew G. Knepley switch (ct) { 233412e9a14SMatthew 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; 234412e9a14SMatthew 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; 235412e9a14SMatthew 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; 236412e9a14SMatthew G. Knepley default: 237412e9a14SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 238412e9a14SMatthew G. Knepley } 239bed052eaSMatthew G. Knepley PetscFunctionReturn(0); 240bed052eaSMatthew G. Knepley } 241bed052eaSMatthew G. Knepley 24280389061SMatthew G. Knepley /* Should this be here or in the DualSpace somehow? */ 243412e9a14SMatthew G. Knepley PetscErrorCode CellRefinerInCellTest_Internal(DMPolytopeType ct, const PetscReal point[], PetscBool *inside) 24480389061SMatthew G. Knepley { 24580389061SMatthew G. Knepley PetscReal sum = 0.0; 24680389061SMatthew G. Knepley PetscInt d; 24780389061SMatthew G. Knepley 24880389061SMatthew G. Knepley PetscFunctionBegin; 24980389061SMatthew G. Knepley *inside = PETSC_TRUE; 250412e9a14SMatthew G. Knepley switch (ct) { 251412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 252412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 253412e9a14SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) { 25480389061SMatthew G. Knepley if (point[d] < -1.0) {*inside = PETSC_FALSE; break;} 25580389061SMatthew G. Knepley sum += point[d]; 25680389061SMatthew G. Knepley } 257412e9a14SMatthew G. Knepley if (sum > PETSC_SMALL) {*inside = PETSC_FALSE; break;} 25880389061SMatthew G. Knepley break; 259412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 260412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 261412e9a14SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) 262412e9a14SMatthew G. Knepley if (PetscAbsReal(point[d]) > 1.+PETSC_SMALL) {*inside = PETSC_FALSE; break;} 26394339e62SJed Brown break; 26480389061SMatthew G. Knepley default: 265412e9a14SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 26680389061SMatthew G. Knepley } 26780389061SMatthew G. Knepley PetscFunctionReturn(0); 26880389061SMatthew G. Knepley } 26980389061SMatthew G. Knepley 270412e9a14SMatthew G. Knepley /* Regular Refinment of Hybrid Meshes 27175d3a19aSMatthew G. Knepley 272412e9a14SMatthew 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 273412e9a14SMatthew G. Knepley to automatically generate a refined Plex. In fact, we would like these rules to be general enough to encompass other 274412e9a14SMatthew G. Knepley transformations, such as changing from one type of cell to another, as simplex to hex. 27575d3a19aSMatthew G. Knepley 276412e9a14SMatthew G. Knepley To start, we can create a function that takes an original cell type and returns the number of new cells replacing it 277412e9a14SMatthew G. Knepley and the types of the new cells. 278518a8359SMatthew G. Knepley 279412e9a14SMatthew G. Knepley We need the group multiplication table for group actions from the dihedral group for each cell type. 28042525629SMatthew G. Knepley 281412e9a14SMatthew 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 282412e9a14SMatthew G. Knepley we can just write this operator for faces with identity, and then compose the face orientation actions to get the actual 283412e9a14SMatthew G. Knepley (face, orient) pairs for each subcell. 284412e9a14SMatthew G. Knepley */ 2850314a74cSLawrence Mitchell 28675d3a19aSMatthew G. Knepley /* 287412e9a14SMatthew G. Knepley Input Parameters: 288412e9a14SMatthew G. Knepley + ct - The type of the input cell 289a5801f52SStefano Zampini . co - The orientation of this cell in its parent 290412e9a14SMatthew G. Knepley - cp - The requested cone point of this cell assuming orientation 0 291412e9a14SMatthew G. Knepley 292412e9a14SMatthew G. Knepley Output Parameters: 293a5801f52SStefano Zampini . cpnew - The new cone point, taking into account the orientation co 294412e9a14SMatthew G. Knepley */ 295412e9a14SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPolytopeMapCell(DMPolytopeType ct, PetscInt co, PetscInt cp, PetscInt *cpnew) 296412e9a14SMatthew G. Knepley { 297412e9a14SMatthew G. Knepley const PetscInt csize = DMPolytopeTypeGetConeSize(ct); 298412e9a14SMatthew G. Knepley 299412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 300412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_POINT) {*cpnew = cp;} 301412e9a14SMatthew G. Knepley else {*cpnew = (co < 0 ? -(co+1)-cp+csize : co+cp)%csize;} 302412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 303412e9a14SMatthew G. Knepley } 304412e9a14SMatthew G. Knepley 305412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCellVertices_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 306412e9a14SMatthew G. Knepley { 307412e9a14SMatthew G. Knepley static PetscReal seg_v[] = {-1.0, 0.0, 1.0}; 308412e9a14SMatthew 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}; 309412e9a14SMatthew 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}; 310412e9a14SMatthew G. Knepley static PetscReal tet_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 311412e9a14SMatthew G. Knepley -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, -1.0, 1.0, -1.0, 312412e9a14SMatthew 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}; 313412e9a14SMatthew G. Knepley static PetscReal hex_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 314412e9a14SMatthew G. Knepley -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0, -1.0, 315412e9a14SMatthew G. Knepley -1.0, 1.0, -1.0, 0.0, 1.0, -1.0, 1.0, 1.0, -1.0, 316412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0, -1.0, 0.0, 317412e9a14SMatthew G. Knepley -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 318412e9a14SMatthew G. Knepley -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 319412e9a14SMatthew G. Knepley -1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 1.0, -1.0, 1.0, 320412e9a14SMatthew G. Knepley -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 321412e9a14SMatthew G. Knepley -1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0}; 322412e9a14SMatthew G. Knepley 323412e9a14SMatthew G. Knepley PetscFunctionBegin; 324412e9a14SMatthew G. Knepley switch (ct) { 325412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nv = 3; *subcellV = seg_v; break; 326412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 6; *subcellV = tri_v; break; 327412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nv = 9; *subcellV = quad_v; break; 328412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 10; *subcellV = tet_v; break; 329412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nv = 27; *subcellV = hex_v; break; 330412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 331412e9a14SMatthew G. Knepley } 332412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 333412e9a14SMatthew G. Knepley } 334412e9a14SMatthew G. Knepley 33596ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerGetCellVertices_ToBox(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 336412e9a14SMatthew G. Knepley { 337412e9a14SMatthew 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}; 338412e9a14SMatthew G. Knepley static PetscReal tet_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 339412e9a14SMatthew 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, 340412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, -1.0/3.0, -1.0, -1.0/3.0, 0.0, -1.0, 0.0, 341412e9a14SMatthew 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, 342412e9a14SMatthew G. Knepley -1.0, -1.0, 1.0, -0.5, -0.5, -0.5}; 343412e9a14SMatthew G. Knepley PetscErrorCode ierr; 344412e9a14SMatthew G. Knepley 345412e9a14SMatthew G. Knepley PetscFunctionBegin; 346412e9a14SMatthew G. Knepley switch (ct) { 347412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 348412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 349412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 350412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCellVertices_Regular(cr, ct, Nv, subcellV);CHKERRQ(ierr);break; 351412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 7; *subcellV = tri_v; break; 352412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 15; *subcellV = tet_v; break; 353412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 354412e9a14SMatthew G. Knepley } 355412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 356412e9a14SMatthew G. Knepley } 357412e9a14SMatthew G. Knepley 358412e9a14SMatthew G. Knepley /* 359412e9a14SMatthew G. Knepley DMPlexCellRefinerGetCellVertices - Get the set of refined vertices lying in the closure of a reference cell of given type 360412e9a14SMatthew G. Knepley 361412e9a14SMatthew G. Knepley Input Parameters: 362412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 363412e9a14SMatthew G. Knepley - ct - The cell type 364412e9a14SMatthew G. Knepley 365412e9a14SMatthew G. Knepley Output Parameters: 366412e9a14SMatthew G. Knepley + Nv - The number of refined vertices in the closure of the reference cell of given type 367412e9a14SMatthew G. Knepley - subcellV - The coordinates of these vertices in the reference cell 368412e9a14SMatthew G. Knepley 369412e9a14SMatthew G. Knepley Level: developer 370412e9a14SMatthew G. Knepley 371412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetSubcellVertices() 372412e9a14SMatthew G. Knepley */ 373412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCellVertices(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 374412e9a14SMatthew G. Knepley { 375412e9a14SMatthew G. Knepley PetscErrorCode ierr; 376412e9a14SMatthew G. Knepley 377412e9a14SMatthew G. Knepley PetscFunctionBegin; 378a5801f52SStefano Zampini if (!cr->ops->getcellvertices) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]); 379412e9a14SMatthew G. Knepley ierr = (*cr->ops->getcellvertices)(cr, ct, Nv, subcellV);CHKERRQ(ierr); 380412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 381412e9a14SMatthew G. Knepley } 382412e9a14SMatthew G. Knepley 383412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 384412e9a14SMatthew G. Knepley { 385412e9a14SMatthew G. Knepley static PetscInt seg_v[] = {0, 1, 1, 2}; 386412e9a14SMatthew G. Knepley static PetscInt tri_v[] = {0, 3, 5, 3, 1, 4, 5, 4, 2, 3, 4, 5}; 387412e9a14SMatthew G. Knepley static PetscInt quad_v[] = {0, 4, 8, 7, 4, 1, 5, 8, 8, 5, 2, 6, 7, 8, 6, 3}; 388412e9a14SMatthew G. Knepley static PetscInt tet_v[] = {0, 3, 1, 6, 3, 2, 4, 8, 1, 4, 5, 7, 6, 8, 7, 9, 389412e9a14SMatthew G. Knepley 1, 6, 3, 7, 8, 4, 3, 7, 7, 3, 1, 4, 7, 3, 8, 6}; 390412e9a14SMatthew 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, 391412e9a14SMatthew 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}; 392412e9a14SMatthew G. Knepley 393412e9a14SMatthew G. Knepley PetscFunctionBegin; 394412e9a14SMatthew G. Knepley if (ct != rct) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Cell type %s does not produce %s", DMPolytopeTypes[ct], DMPolytopeTypes[rct]); 395412e9a14SMatthew G. Knepley switch (ct) { 396412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nv = 2; *subcellV = &seg_v[r*(*Nv)]; break; 397412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 3; *subcellV = &tri_v[r*(*Nv)]; break; 398412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nv = 4; *subcellV = &quad_v[r*(*Nv)]; break; 399412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 4; *subcellV = &tet_v[r*(*Nv)]; break; 400412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nv = 8; *subcellV = &hex_v[r*(*Nv)]; break; 401412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 402412e9a14SMatthew G. Knepley } 403412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 404412e9a14SMatthew G. Knepley } 405412e9a14SMatthew G. Knepley 40696ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerGetSubcellVertices_ToBox(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 407412e9a14SMatthew G. Knepley { 408412e9a14SMatthew G. Knepley static PetscInt tri_v[] = {0, 3, 6, 5, 3, 1, 4, 6, 5, 6, 4, 2}; 409412e9a14SMatthew 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}; 410412e9a14SMatthew G. Knepley PetscErrorCode ierr; 411412e9a14SMatthew G. Knepley 412412e9a14SMatthew G. Knepley PetscFunctionBegin; 413412e9a14SMatthew G. Knepley switch (ct) { 414412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 415412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 416412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 417412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetSubcellVertices_Regular(cr, ct, rct, r, Nv, subcellV);CHKERRQ(ierr);break; 418412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 419412e9a14SMatthew 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]); 420412e9a14SMatthew G. Knepley *Nv = 4; *subcellV = &tri_v[r*(*Nv)]; break; 421412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 422412e9a14SMatthew 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]); 423412e9a14SMatthew G. Knepley *Nv = 8; *subcellV = &tet_v[r*(*Nv)]; break; 424412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 425412e9a14SMatthew G. Knepley } 426412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 427412e9a14SMatthew G. Knepley } 428412e9a14SMatthew G. Knepley 429412e9a14SMatthew G. Knepley /* 430412e9a14SMatthew G. Knepley DMPlexCellRefinerGetSubcellVertices - Get the set of refined vertices defining a subcell in the reference cell of given type 431412e9a14SMatthew G. Knepley 432412e9a14SMatthew G. Knepley Input Parameters: 433412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 434412e9a14SMatthew G. Knepley . ct - The cell type 435412e9a14SMatthew G. Knepley . rct - The type of subcell 436412e9a14SMatthew G. Knepley - r - The subcell index 437412e9a14SMatthew G. Knepley 438412e9a14SMatthew G. Knepley Output Parameters: 439412e9a14SMatthew G. Knepley + Nv - The number of refined vertices in the subcell 440412e9a14SMatthew G. Knepley - subcellV - The indices of these vertices in the set of vertices returned by DMPlexCellRefinerGetCellVertices() 441412e9a14SMatthew G. Knepley 442412e9a14SMatthew G. Knepley Level: developer 443412e9a14SMatthew G. Knepley 444412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetCellVertices() 445412e9a14SMatthew G. Knepley */ 446412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 447412e9a14SMatthew G. Knepley { 448412e9a14SMatthew G. Knepley PetscErrorCode ierr; 449412e9a14SMatthew G. Knepley 450412e9a14SMatthew G. Knepley PetscFunctionBegin; 451a5801f52SStefano Zampini if (!cr->ops->getsubcellvertices) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]); 452412e9a14SMatthew G. Knepley ierr = (*cr->ops->getsubcellvertices)(cr, ct, rct, r, Nv, subcellV);CHKERRQ(ierr); 453412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 454412e9a14SMatthew G. Knepley } 455412e9a14SMatthew G. Knepley 456412e9a14SMatthew G. Knepley /* 457412e9a14SMatthew G. Knepley Input Parameters: 458412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner 459412e9a14SMatthew G. Knepley . pct - The cell type of the parent, from whom the new cell is being produced 460a5801f52SStefano Zampini . ct - The type being produced 461a5801f52SStefano Zampini . r - The replica number requested for the produced cell type 462a5801f52SStefano Zampini . Nv - Number of vertices in the closure of the parent cell 463a5801f52SStefano Zampini . dE - Spatial dimension 464a5801f52SStefano Zampini - in - array of size Nv*dE, holding coordinates of the vertices in the closure of the parent cell 465a5801f52SStefano Zampini 466a5801f52SStefano Zampini Output Parameters: 467a5801f52SStefano Zampini . out - The coordinates of the new vertices 468a5801f52SStefano Zampini */ 469a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapCoordinates(DMPlexCellRefiner cr, DMPolytopeType pct, DMPolytopeType ct, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[]) 470a5801f52SStefano Zampini { 471a5801f52SStefano Zampini PetscErrorCode ierr; 472a5801f52SStefano Zampini 473a5801f52SStefano Zampini PetscFunctionBeginHot; 474a5801f52SStefano Zampini if (!cr->ops->mapcoords) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]); 475a5801f52SStefano Zampini ierr = (*cr->ops->mapcoords)(cr, pct, ct, r, Nv, dE, in, out);CHKERRQ(ierr); 476a5801f52SStefano Zampini PetscFunctionReturn(0); 477a5801f52SStefano Zampini } 478a5801f52SStefano Zampini 479a5801f52SStefano Zampini /* Computes new vertex as the barycenter */ 480a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapCoordinates_Barycenter(DMPlexCellRefiner cr, DMPolytopeType pct, DMPolytopeType ct, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[]) 481a5801f52SStefano Zampini { 482a5801f52SStefano Zampini PetscInt v,d; 483a5801f52SStefano Zampini 484a5801f52SStefano Zampini PetscFunctionBeginHot; 485a5801f52SStefano Zampini if (ct != DM_POLYTOPE_POINT) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for refined point type %s",DMPolytopeTypes[ct]); 486a5801f52SStefano Zampini for (d = 0; d < dE; ++d) out[d] = 0.0; 487a5801f52SStefano Zampini for (v = 0; v < Nv; ++v) for (d = 0; d < dE; ++d) out[d] += in[v*dE+d]; 488a5801f52SStefano Zampini for (d = 0; d < dE; ++d) out[d] /= Nv; 489a5801f52SStefano Zampini PetscFunctionReturn(0); 490a5801f52SStefano Zampini } 491a5801f52SStefano Zampini 492a5801f52SStefano Zampini /* 493a5801f52SStefano Zampini Input Parameters: 494a5801f52SStefano Zampini + cr - The DMPlexCellRefiner 495a5801f52SStefano Zampini . pct - The cell type of the parent, from whom the new cell is being produced 4963f2a96e3SMatthew G. Knepley . pp - The parent cell 497412e9a14SMatthew G. Knepley . po - The orientation of the parent cell in its enclosing parent 498412e9a14SMatthew G. Knepley . ct - The type being produced 499412e9a14SMatthew G. Knepley . r - The replica number requested for the produced cell type 500412e9a14SMatthew G. Knepley - o - The relative orientation of the replica 501412e9a14SMatthew G. Knepley 502412e9a14SMatthew G. Knepley Output Parameters: 503a5801f52SStefano Zampini + rnew - The replica number, given the orientation of the parent 504412e9a14SMatthew G. Knepley - onew - The replica orientation, given the orientation of the parent 505412e9a14SMatthew G. Knepley */ 5063f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt pp, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 507412e9a14SMatthew G. Knepley { 508412e9a14SMatthew G. Knepley PetscErrorCode ierr; 509412e9a14SMatthew G. Knepley 510412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 511a5801f52SStefano Zampini if (!cr->ops->mapsubcells) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]); 5123f2a96e3SMatthew G. Knepley ierr = (*cr->ops->mapsubcells)(cr, pct, pp, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 513412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 514412e9a14SMatthew G. Knepley } 515412e9a14SMatthew G. Knepley 516cf4091a3SMatthew G. Knepley /* 517cf4091a3SMatthew G. Knepley This is the group multiplication table for the dihedral group of the cell. 518cf4091a3SMatthew G. Knepley */ 519cf4091a3SMatthew G. Knepley static PetscErrorCode ComposeOrientation_Private(PetscInt n, PetscInt o1, PetscInt o2, PetscInt *o) 520cf4091a3SMatthew G. Knepley { 521cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 522cf4091a3SMatthew G. Knepley if (!n) {*o = 0;} 523cf4091a3SMatthew G. Knepley else if (o1 >= 0 && o2 >= 0) {*o = ( o1 + o2) % n;} 524cf4091a3SMatthew G. Knepley else if (o1 < 0 && o2 < 0) {*o = (-o1 - o2) % n;} 525cf4091a3SMatthew G. Knepley else if (o1 < 0) {*o = -((-(o1+1) + o2) % n + 1);} 526cf4091a3SMatthew G. Knepley else if (o2 < 0) {*o = -((-(o2+1) + o1) % n + 1);} 527cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 528cf4091a3SMatthew G. Knepley } 529cf4091a3SMatthew G. Knepley 5303f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_None(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt pp, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 531cf4091a3SMatthew G. Knepley { 532cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 533cf4091a3SMatthew G. Knepley 534cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 535cf4091a3SMatthew G. Knepley *rnew = r; 536cf4091a3SMatthew G. Knepley ierr = ComposeOrientation_Private(DMPolytopeTypeGetConeSize(ct), po, o, onew);CHKERRQ(ierr); 537cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 538cf4091a3SMatthew G. Knepley } 539cf4091a3SMatthew G. Knepley 5403f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_Regular(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt pp, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 541412e9a14SMatthew G. Knepley { 542412e9a14SMatthew G. Knepley /* We shift any input orientation in order to make it non-negative 543412e9a14SMatthew 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) 544412e9a14SMatthew G. Knepley The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 545412e9a14SMatthew G. Knepley Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 546412e9a14SMatthew G. Knepley */ 547412e9a14SMatthew G. Knepley PetscInt tri_seg_o[] = {-2, 0, 548412e9a14SMatthew G. Knepley -2, 0, 549412e9a14SMatthew G. Knepley -2, 0, 550412e9a14SMatthew G. Knepley 0, -2, 551412e9a14SMatthew G. Knepley 0, -2, 552412e9a14SMatthew G. Knepley 0, -2}; 553412e9a14SMatthew G. Knepley PetscInt tri_seg_r[] = {1, 0, 2, 554412e9a14SMatthew G. Knepley 0, 2, 1, 555412e9a14SMatthew G. Knepley 2, 1, 0, 556412e9a14SMatthew G. Knepley 0, 1, 2, 557412e9a14SMatthew G. Knepley 1, 2, 0, 558412e9a14SMatthew G. Knepley 2, 0, 1}; 559412e9a14SMatthew G. Knepley PetscInt tri_tri_o[] = {0, 1, 2, -3, -2, -1, 560412e9a14SMatthew G. Knepley 2, 0, 1, -2, -1, -3, 561412e9a14SMatthew G. Knepley 1, 2, 0, -1, -3, -2, 562412e9a14SMatthew G. Knepley -3, -2, -1, 0, 1, 2, 563412e9a14SMatthew G. Knepley -1, -3, -2, 1, 2, 0, 564412e9a14SMatthew G. Knepley -2, -1, -3, 2, 0, 1}; 565412e9a14SMatthew G. Knepley /* orientation if the replica is the center triangle */ 566412e9a14SMatthew G. Knepley PetscInt tri_tri_o_c[] = {2, 0, 1, -2, -1, -3, 567412e9a14SMatthew G. Knepley 1, 2, 0, -1, -3, -2, 568412e9a14SMatthew G. Knepley 0, 1, 2, -3, -2, -1, 569412e9a14SMatthew G. Knepley -3, -2, -1, 0, 1, 2, 570412e9a14SMatthew G. Knepley -1, -3, -2, 1, 2, 0, 571412e9a14SMatthew G. Knepley -2, -1, -3, 2, 0, 1}; 572412e9a14SMatthew G. Knepley PetscInt tri_tri_r[] = {0, 2, 1, 3, 573412e9a14SMatthew G. Knepley 2, 1, 0, 3, 574412e9a14SMatthew G. Knepley 1, 0, 2, 3, 575412e9a14SMatthew G. Knepley 0, 1, 2, 3, 576412e9a14SMatthew G. Knepley 1, 2, 0, 3, 577412e9a14SMatthew G. Knepley 2, 0, 1, 3}; 578412e9a14SMatthew G. Knepley PetscInt quad_seg_r[] = {3, 2, 1, 0, 579412e9a14SMatthew G. Knepley 2, 1, 0, 3, 580412e9a14SMatthew G. Knepley 1, 0, 3, 2, 581412e9a14SMatthew G. Knepley 0, 3, 2, 1, 582412e9a14SMatthew G. Knepley 0, 1, 2, 3, 583412e9a14SMatthew G. Knepley 1, 2, 3, 0, 584412e9a14SMatthew G. Knepley 2, 3, 0, 1, 585412e9a14SMatthew G. Knepley 3, 0, 1, 2}; 586412e9a14SMatthew G. Knepley PetscInt quad_quad_o[] = { 0, 1, 2, 3, -4, -3, -2, -1, 587412e9a14SMatthew G. Knepley 4, 0, 1, 2, -3, -2, -1, -4, 588412e9a14SMatthew G. Knepley 3, 4, 0, 1, -2, -1, -4, -3, 589412e9a14SMatthew G. Knepley 2, 3, 4, 0, -1, -4, -3, -2, 590412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 591412e9a14SMatthew G. Knepley -1, -4, -3, -2, 1, 2, 3, 0, 592412e9a14SMatthew G. Knepley -2, -1, -4, -3, 2, 3, 0, 1, 593412e9a14SMatthew G. Knepley -3, -2, -1, -4, 3, 0, 1, 2}; 594412e9a14SMatthew G. Knepley PetscInt quad_quad_r[] = {0, 3, 2, 1, 595412e9a14SMatthew G. Knepley 3, 2, 1, 0, 596412e9a14SMatthew G. Knepley 2, 1, 0, 3, 597412e9a14SMatthew G. Knepley 1, 0, 3, 2, 598412e9a14SMatthew G. Knepley 0, 1, 2, 3, 599412e9a14SMatthew G. Knepley 1, 2, 3, 0, 600412e9a14SMatthew G. Knepley 2, 3, 0, 1, 601412e9a14SMatthew G. Knepley 3, 0, 1, 2}; 602412e9a14SMatthew G. Knepley PetscInt tquad_tquad_o[] = { 0, 1, -2, -1, 603412e9a14SMatthew G. Knepley 1, 0, -1, -2, 604412e9a14SMatthew G. Knepley -2, -1, 0, 1, 605412e9a14SMatthew G. Knepley -1, -2, 1, 0}; 606412e9a14SMatthew G. Knepley PetscInt tquad_tquad_r[] = {1, 0, 607412e9a14SMatthew G. Knepley 1, 0, 608412e9a14SMatthew G. Knepley 0, 1, 609412e9a14SMatthew G. Knepley 0, 1}; 610412e9a14SMatthew G. Knepley 611412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 612412e9a14SMatthew G. Knepley /* The default is no transformation */ 613412e9a14SMatthew G. Knepley *rnew = r; 614412e9a14SMatthew G. Knepley *onew = o; 615412e9a14SMatthew G. Knepley switch (pct) { 616412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 617412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_SEGMENT) { 618412e9a14SMatthew G. Knepley if (po == 0 || po == -1) {*rnew = r; *onew = o;} 619412e9a14SMatthew G. Knepley else if (po == 1 || po == -2) {*rnew = (r+1)%2; *onew = (o == 0 || o == -1) ? -2 : 0;} 620412e9a14SMatthew G. Knepley else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid orientation %D for segment", po); 621412e9a14SMatthew G. Knepley } 622412e9a14SMatthew G. Knepley break; 623412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 624412e9a14SMatthew G. Knepley switch (ct) { 625412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 626412e9a14SMatthew G. Knepley if (o == -1) o = 0; 627412e9a14SMatthew G. Knepley if (o == -2) o = 1; 628412e9a14SMatthew G. Knepley *onew = tri_seg_o[(po+3)*2+o]; 629412e9a14SMatthew G. Knepley *rnew = tri_seg_r[(po+3)*3+r]; 630412e9a14SMatthew G. Knepley break; 631412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 632412e9a14SMatthew 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]; 633412e9a14SMatthew G. Knepley *rnew = tri_tri_r[(po+3)*4+r]; 634412e9a14SMatthew G. Knepley break; 635412e9a14SMatthew G. Knepley default: break; 636412e9a14SMatthew G. Knepley } 637412e9a14SMatthew G. Knepley break; 638412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 639412e9a14SMatthew G. Knepley switch (ct) { 640412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 641412e9a14SMatthew G. Knepley *onew = o; 642412e9a14SMatthew G. Knepley *rnew = quad_seg_r[(po+4)*4+r]; 643412e9a14SMatthew G. Knepley break; 644412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 645412e9a14SMatthew G. Knepley *onew = quad_quad_o[(po+4)*8+o+4]; 646412e9a14SMatthew G. Knepley *rnew = quad_quad_r[(po+4)*4+r]; 647412e9a14SMatthew G. Knepley break; 648412e9a14SMatthew G. Knepley default: break; 649412e9a14SMatthew G. Knepley } 650412e9a14SMatthew G. Knepley break; 651412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 652412e9a14SMatthew G. Knepley switch (ct) { 653412e9a14SMatthew G. Knepley /* DM_POLYTOPE_POINT_PRISM_TENSOR does not change */ 654412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 655412e9a14SMatthew G. Knepley *onew = tquad_tquad_o[(po+2)*4+o+2]; 656412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 657412e9a14SMatthew G. Knepley break; 658412e9a14SMatthew G. Knepley default: break; 659412e9a14SMatthew G. Knepley } 660412e9a14SMatthew G. Knepley break; 661412e9a14SMatthew G. Knepley default: break; 662412e9a14SMatthew G. Knepley } 663412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 664412e9a14SMatthew G. Knepley } 665412e9a14SMatthew G. Knepley 6663f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_ToBox(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt pp, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 667412e9a14SMatthew G. Knepley { 668412e9a14SMatthew G. Knepley PetscErrorCode ierr; 669412e9a14SMatthew G. Knepley /* We shift any input orientation in order to make it non-negative 670412e9a14SMatthew 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) 671412e9a14SMatthew G. Knepley The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 672412e9a14SMatthew G. Knepley Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 673412e9a14SMatthew G. Knepley */ 674412e9a14SMatthew G. Knepley PetscInt tri_seg_o[] = {0, -2, 675412e9a14SMatthew G. Knepley 0, -2, 676412e9a14SMatthew G. Knepley 0, -2, 677412e9a14SMatthew G. Knepley 0, -2, 678412e9a14SMatthew G. Knepley 0, -2, 679412e9a14SMatthew G. Knepley 0, -2}; 680412e9a14SMatthew G. Knepley PetscInt tri_seg_r[] = {2, 1, 0, 681412e9a14SMatthew G. Knepley 1, 0, 2, 682412e9a14SMatthew G. Knepley 0, 2, 1, 683412e9a14SMatthew G. Knepley 0, 1, 2, 684412e9a14SMatthew G. Knepley 1, 2, 0, 685412e9a14SMatthew G. Knepley 2, 0, 1}; 686412e9a14SMatthew G. Knepley PetscInt tri_tri_o[] = {0, 1, 2, 3, -4, -3, -2, -1, 687412e9a14SMatthew G. Knepley 3, 0, 1, 2, -3, -2, -1, -4, 688412e9a14SMatthew G. Knepley 1, 2, 3, 0, -1, -4, -3, -2, 689412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 690412e9a14SMatthew G. Knepley -1, -4, -3, -2, 1, 2, 3, 0, 691412e9a14SMatthew G. Knepley -3, -2, -1, -4, 3, 0, 1, 2}; 692412e9a14SMatthew G. Knepley PetscInt tri_tri_r[] = {0, 2, 1, 693412e9a14SMatthew G. Knepley 2, 1, 0, 694412e9a14SMatthew G. Knepley 1, 0, 2, 695412e9a14SMatthew G. Knepley 0, 1, 2, 696412e9a14SMatthew G. Knepley 1, 2, 0, 697412e9a14SMatthew G. Knepley 2, 0, 1}; 698412e9a14SMatthew G. Knepley PetscInt tquad_tquad_o[] = { 0, 1, -2, -1, 699412e9a14SMatthew G. Knepley 1, 0, -1, -2, 700412e9a14SMatthew G. Knepley -2, -1, 0, 1, 701412e9a14SMatthew G. Knepley -1, -2, 1, 0}; 702412e9a14SMatthew G. Knepley PetscInt tquad_tquad_r[] = {1, 0, 703412e9a14SMatthew G. Knepley 1, 0, 704412e9a14SMatthew G. Knepley 0, 1, 705412e9a14SMatthew G. Knepley 0, 1}; 706412e9a14SMatthew G. Knepley PetscInt tquad_quad_o[] = {-2, -1, -4, -3, 2, 3, 0, 1, 707412e9a14SMatthew G. Knepley 1, 2, 3, 0, -1, -4, -3, -2, 708412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 709412e9a14SMatthew G. Knepley 1, 0, 3, 2, -3, -4, -1, -2}; 710412e9a14SMatthew G. Knepley 711412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 712412e9a14SMatthew G. Knepley *rnew = r; 713412e9a14SMatthew G. Knepley *onew = o; 714412e9a14SMatthew G. Knepley switch (pct) { 715412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 716412e9a14SMatthew G. Knepley switch (ct) { 717412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 718412e9a14SMatthew G. Knepley if (o == -1) o = 0; 719412e9a14SMatthew G. Knepley if (o == -2) o = 1; 720412e9a14SMatthew G. Knepley *onew = tri_seg_o[(po+3)*2+o]; 721412e9a14SMatthew G. Knepley *rnew = tri_seg_r[(po+3)*3+r]; 722412e9a14SMatthew G. Knepley break; 723412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 724412e9a14SMatthew G. Knepley *onew = tri_tri_o[(po+3)*8+o+4]; 725412e9a14SMatthew G. Knepley /* TODO See sheet, for fixing po == 1 and 2 */ 726412e9a14SMatthew G. Knepley if (po == 2 && r == 2 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+3)%4)+4]; 727412e9a14SMatthew G. Knepley if (po == 2 && r == 2 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+5)%4)]; 728412e9a14SMatthew G. Knepley if (po == 1 && r == 1 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+1)%4)+4]; 729412e9a14SMatthew G. Knepley if (po == 1 && r == 1 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+7)%4)]; 730412e9a14SMatthew G. Knepley if (po == -1 && r == 2 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+3)%4)+4]; 731412e9a14SMatthew G. Knepley if (po == -1 && r == 2 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+5)%4)]; 732412e9a14SMatthew G. Knepley if (po == -2 && r == 1 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+1)%4)+4]; 733412e9a14SMatthew G. Knepley if (po == -2 && r == 1 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+7)%4)]; 734412e9a14SMatthew G. Knepley *rnew = tri_tri_r[(po+3)*3+r]; 735412e9a14SMatthew G. Knepley break; 736412e9a14SMatthew G. Knepley default: break; 737412e9a14SMatthew G. Knepley } 738412e9a14SMatthew G. Knepley break; 739412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 740412e9a14SMatthew G. Knepley switch (ct) { 741412e9a14SMatthew G. Knepley /* DM_POLYTOPE_POINT_PRISM_TENSOR does not change */ 742412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 743412e9a14SMatthew G. Knepley *onew = tquad_tquad_o[(po+2)*4+o+2]; 744412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 745412e9a14SMatthew G. Knepley break; 746412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 747412e9a14SMatthew G. Knepley *onew = tquad_quad_o[(po+2)*8+o+4]; 748412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 749412e9a14SMatthew G. Knepley break; 750412e9a14SMatthew G. Knepley default: break; 751412e9a14SMatthew G. Knepley } 752412e9a14SMatthew G. Knepley break; 753412e9a14SMatthew G. Knepley default: 7543f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerMapSubcells_Regular(cr, pct, pp, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 755412e9a14SMatthew G. Knepley } 756412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 757412e9a14SMatthew G. Knepley } 758412e9a14SMatthew G. Knepley 7593f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt pp, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 760412e9a14SMatthew G. Knepley { 7613f2a96e3SMatthew G. Knepley return DMPlexCellRefinerMapSubcells_Regular(cr, pct, pp, po, ct, r, o, rnew, onew); 762412e9a14SMatthew G. Knepley } 763412e9a14SMatthew G. Knepley 764412e9a14SMatthew G. Knepley /*@ 765412e9a14SMatthew G. Knepley DMPlexCellRefinerRefine - Return a description of the refinement for a given cell type 766412e9a14SMatthew G. Knepley 7673f2a96e3SMatthew G. Knepley Input Parameters: 7683f2a96e3SMatthew G. Knepley + source - The cell type for a source point 7693f2a96e3SMatthew G. Knepley - p - The source point, or PETSC_DETERMINE if the refine is homogeneous 770412e9a14SMatthew G. Knepley 7713f2a96e3SMatthew G. Knepley Output Parameters: 7723f2a96e3SMatthew G. Knepley + rt - The refine type for this cell 7733f2a96e3SMatthew G. Knepley . Nt - The number of cell types generated by refinement 774412e9a14SMatthew G. Knepley . target - The cell types generated 775412e9a14SMatthew G. Knepley . size - The number of subcells of each type, ordered by dimension 776412e9a14SMatthew G. Knepley . cone - A list of the faces for each subcell of the same type as source 777412e9a14SMatthew G. Knepley - ornt - A list of the face orientations for each subcell of the same type as source 778412e9a14SMatthew G. Knepley 779a5801f52SStefano Zampini Note: The cone array gives the cone of each subcell listed by the first three outputs. For each cone point, we 780412e9a14SMatthew G. Knepley need the cell type, point identifier, and orientation within the subcell. The orientation is with respect to the canonical 781412e9a14SMatthew G. Knepley division (described in these outputs) of the cell in the original mesh. The point identifier is given by 782412e9a14SMatthew G. Knepley $ the number of cones to be taken, or 0 for the current cell 783412e9a14SMatthew G. Knepley $ the cell cone point number at each level from which it is subdivided 784412e9a14SMatthew G. Knepley $ the replica number r of the subdivision. 785412e9a14SMatthew G. Knepley The orientation is with respect to the canonical cone orientation. For example, the prescription for edge division is 786412e9a14SMatthew G. Knepley $ Nt = 2 787412e9a14SMatthew G. Knepley $ target = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT} 788412e9a14SMatthew G. Knepley $ size = {1, 2} 789412e9a14SMatthew 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} 790412e9a14SMatthew G. Knepley $ ornt = { 0, 0, 0, 0} 791412e9a14SMatthew G. Knepley 792412e9a14SMatthew G. Knepley Level: developer 793412e9a14SMatthew G. Knepley 79496ca5757SLisandro Dalcin .seealso: DMPlexCellRefinerCreate(), DMPlexRefineUniform() 795412e9a14SMatthew G. Knepley @*/ 7963f2a96e3SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerRefine(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt p, PetscInt *rt, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 797412e9a14SMatthew G. Knepley { 798412e9a14SMatthew G. Knepley PetscErrorCode ierr; 799412e9a14SMatthew G. Knepley 800412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 801a5801f52SStefano Zampini if (!cr->ops->refine) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]); 8023f2a96e3SMatthew G. Knepley ierr = (*cr->ops->refine)(cr, source, p, rt, Nt, target, size, cone, ornt);CHKERRQ(ierr); 803412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 804412e9a14SMatthew G. Knepley } 805412e9a14SMatthew G. Knepley 8063f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_None(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt p, PetscInt *rt, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 807cf4091a3SMatthew G. Knepley { 808cf4091a3SMatthew G. Knepley static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT}; 809cf4091a3SMatthew G. Knepley static PetscInt vertexS[] = {1}; 810cf4091a3SMatthew G. Knepley static PetscInt vertexC[] = {0}; 811cf4091a3SMatthew G. Knepley static PetscInt vertexO[] = {0}; 812cf4091a3SMatthew G. Knepley static DMPolytopeType edgeT[] = {DM_POLYTOPE_SEGMENT}; 813cf4091a3SMatthew G. Knepley static PetscInt edgeS[] = {1}; 814cf4091a3SMatthew G. Knepley static PetscInt edgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 815cf4091a3SMatthew G. Knepley static PetscInt edgeO[] = {0, 0}; 816cf4091a3SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR}; 817cf4091a3SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 818cf4091a3SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 819cf4091a3SMatthew G. Knepley static PetscInt tedgeO[] = {0, 0}; 820cf4091a3SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_TRIANGLE}; 821cf4091a3SMatthew G. Knepley static PetscInt triS[] = {1}; 822cf4091a3SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0}; 823cf4091a3SMatthew G. Knepley static PetscInt triO[] = {0, 0, 0}; 824cf4091a3SMatthew G. Knepley static DMPolytopeType quadT[] = {DM_POLYTOPE_QUADRILATERAL}; 825cf4091a3SMatthew G. Knepley static PetscInt quadS[] = {1}; 826cf4091a3SMatthew 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}; 827cf4091a3SMatthew G. Knepley static PetscInt quadO[] = {0, 0, 0, 0}; 828cf4091a3SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_SEG_PRISM_TENSOR}; 829cf4091a3SMatthew G. Knepley static PetscInt tquadS[] = {1}; 830cf4091a3SMatthew 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}; 831cf4091a3SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 0, 0}; 832cf4091a3SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_TETRAHEDRON}; 833cf4091a3SMatthew G. Knepley static PetscInt tetS[] = {1}; 834cf4091a3SMatthew 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}; 835cf4091a3SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 0, 0}; 836cf4091a3SMatthew G. Knepley static DMPolytopeType hexT[] = {DM_POLYTOPE_HEXAHEDRON}; 837cf4091a3SMatthew G. Knepley static PetscInt hexS[] = {1}; 838cf4091a3SMatthew G. Knepley static PetscInt hexC[] = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, 839cf4091a3SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0, DM_POLYTOPE_QUADRILATERAL, 1, 5, 0}; 840cf4091a3SMatthew G. Knepley static PetscInt hexO[] = {0, 0, 0, 0, 0, 0}; 841cf4091a3SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_TRI_PRISM}; 842cf4091a3SMatthew G. Knepley static PetscInt tripS[] = {1}; 843cf4091a3SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, 844cf4091a3SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0}; 845cf4091a3SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 0, 0, 0}; 846cf4091a3SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_TRI_PRISM_TENSOR}; 847cf4091a3SMatthew G. Knepley static PetscInt ttripS[] = {1}; 848cf4091a3SMatthew G. Knepley static PetscInt ttripC[] = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, 849cf4091a3SMatthew 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}; 850cf4091a3SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 0, 0, 0}; 851cf4091a3SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_QUAD_PRISM_TENSOR}; 852cf4091a3SMatthew G. Knepley static PetscInt tquadpS[] = {1}; 853cf4091a3SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, 854cf4091a3SMatthew 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}; 855cf4091a3SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 0, 0, 0, 0}; 856da9060c4SMatthew G. Knepley static DMPolytopeType pyrT[] = {DM_POLYTOPE_PYRAMID}; 857da9060c4SMatthew G. Knepley static PetscInt pyrS[] = {1}; 858da9060c4SMatthew G. Knepley static PetscInt pyrC[] = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, 859da9060c4SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 1, 3, 0, DM_POLYTOPE_TRIANGLE, 1, 4, 0}; 860da9060c4SMatthew G. Knepley static PetscInt pyrO[] = {0, 0, 0, 0, 0}; 861cf4091a3SMatthew G. Knepley 862cf4091a3SMatthew G. Knepley PetscFunctionBegin; 8633f2a96e3SMatthew G. Knepley if (rt) *rt = 0; 864cf4091a3SMatthew G. Knepley switch (source) { 865cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT: *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break; 866cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nt = 1; *target = edgeT; *size = edgeS; *cone = edgeC; *ornt = edgeO; break; 867cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 868cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 1; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 869cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nt = 1; *target = quadT; *size = quadS; *cone = quadC; *ornt = quadO; break; 870cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 1; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 871cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 1; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 872cf4091a3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nt = 1; *target = hexT; *size = hexS; *cone = hexC; *ornt = hexO; break; 873cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 1; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 874cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 1; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 875cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 1; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 876da9060c4SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: *Nt = 1; *target = pyrT; *size = pyrS; *cone = pyrC; *ornt = pyrO; break; 877cf4091a3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 878cf4091a3SMatthew G. Knepley } 879cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 880cf4091a3SMatthew G. Knepley } 881cf4091a3SMatthew G. Knepley 8823f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Regular(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt p, PetscInt *rt, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 883412e9a14SMatthew G. Knepley { 884412e9a14SMatthew G. Knepley /* All vertices remain in the refined mesh */ 885412e9a14SMatthew G. Knepley static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT}; 886412e9a14SMatthew G. Knepley static PetscInt vertexS[] = {1}; 887412e9a14SMatthew G. Knepley static PetscInt vertexC[] = {0}; 888412e9a14SMatthew G. Knepley static PetscInt vertexO[] = {0}; 889412e9a14SMatthew G. Knepley /* Split all edges with a new vertex, making two new 2 edges 890412e9a14SMatthew G. Knepley 0--0--0--1--1 891412e9a14SMatthew G. Knepley */ 892412e9a14SMatthew G. Knepley static DMPolytopeType edgeT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT}; 893412e9a14SMatthew G. Knepley static PetscInt edgeS[] = {1, 2}; 894412e9a14SMatthew 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}; 895412e9a14SMatthew G. Knepley static PetscInt edgeO[] = { 0, 0, 0, 0}; 896412e9a14SMatthew G. Knepley /* Do not split tensor edges */ 897412e9a14SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR}; 898412e9a14SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 899412e9a14SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 900412e9a14SMatthew G. Knepley static PetscInt tedgeO[] = { 0, 0}; 901412e9a14SMatthew G. Knepley /* Add 3 edges inside every triangle, making 4 new triangles. 90275d3a19aSMatthew G. Knepley 2 90375d3a19aSMatthew G. Knepley |\ 90475d3a19aSMatthew G. Knepley | \ 90575d3a19aSMatthew G. Knepley | \ 906412e9a14SMatthew G. Knepley 0 1 90775d3a19aSMatthew G. Knepley | C \ 90875d3a19aSMatthew G. Knepley | \ 90975d3a19aSMatthew G. Knepley | \ 91075d3a19aSMatthew G. Knepley 2---1---1 91175d3a19aSMatthew G. Knepley |\ D / \ 912412e9a14SMatthew G. Knepley 1 2 0 0 91375d3a19aSMatthew G. Knepley |A \ / B \ 914412e9a14SMatthew G. Knepley 0-0-0---1---1 91575d3a19aSMatthew G. Knepley */ 916412e9a14SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE}; 917412e9a14SMatthew G. Knepley static PetscInt triS[] = {3, 4}; 918412e9a14SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 919412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 1, 2, 0, 920412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 0, 0, 921412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 922412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 0, 923412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, 924412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2}; 925412e9a14SMatthew G. Knepley static PetscInt triO[] = {0, 0, 926412e9a14SMatthew G. Knepley 0, 0, 927412e9a14SMatthew G. Knepley 0, 0, 928412e9a14SMatthew G. Knepley 0, -2, 0, 929412e9a14SMatthew G. Knepley 0, 0, -2, 930412e9a14SMatthew G. Knepley -2, 0, 0, 931412e9a14SMatthew G. Knepley 0, 0, 0}; 932412e9a14SMatthew G. Knepley /* Add a vertex in the center of each quadrilateral, and 4 edges inside, making 4 new quads. 933412e9a14SMatthew G. Knepley 3----1----2----0----2 934412e9a14SMatthew G. Knepley | | | 935412e9a14SMatthew G. Knepley 0 D 2 C 1 936412e9a14SMatthew G. Knepley | | | 937412e9a14SMatthew G. Knepley 3----3----0----1----1 938412e9a14SMatthew G. Knepley | | | 939412e9a14SMatthew G. Knepley 1 A 0 B 0 940412e9a14SMatthew G. Knepley | | | 941412e9a14SMatthew G. Knepley 0----0----0----1----1 942412e9a14SMatthew G. Knepley */ 943412e9a14SMatthew G. Knepley static DMPolytopeType quadT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 944412e9a14SMatthew G. Knepley static PetscInt quadS[] = {1, 4, 4}; 945412e9a14SMatthew G. Knepley static PetscInt quadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 946412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 947412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 948412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 949412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, 950412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 951412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, 952412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0}; 953412e9a14SMatthew G. Knepley static PetscInt quadO[] = {0, 0, 954412e9a14SMatthew G. Knepley 0, 0, 955412e9a14SMatthew G. Knepley 0, 0, 956412e9a14SMatthew G. Knepley 0, 0, 957412e9a14SMatthew G. Knepley 0, 0, -2, 0, 958412e9a14SMatthew G. Knepley 0, 0, 0, -2, 959412e9a14SMatthew G. Knepley -2, 0, 0, 0, 960412e9a14SMatthew G. Knepley 0, -2, 0, 0}; 961412e9a14SMatthew G. Knepley /* Add 1 edge inside every tensor quad, making 2 new tensor quads 962412e9a14SMatthew G. Knepley 2----2----1----3----3 963412e9a14SMatthew G. Knepley | | | 964412e9a14SMatthew G. Knepley | | | 965412e9a14SMatthew G. Knepley | | | 966412e9a14SMatthew G. Knepley 4 A 6 B 5 967412e9a14SMatthew G. Knepley | | | 968412e9a14SMatthew G. Knepley | | | 969412e9a14SMatthew G. Knepley | | | 970412e9a14SMatthew G. Knepley 0----0----0----1----1 971412e9a14SMatthew G. Knepley */ 972412e9a14SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR}; 973412e9a14SMatthew G. Knepley static PetscInt tquadS[] = {1, 2}; 974412e9a14SMatthew G. Knepley static PetscInt tquadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 975412e9a14SMatthew 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, 976412e9a14SMatthew 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}; 977412e9a14SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 978412e9a14SMatthew G. Knepley 0, 0, 0, 0, 979412e9a14SMatthew G. Knepley 0, 0, 0, 0}; 980412e9a14SMatthew G. Knepley /* Add 1 edge and 8 triangles inside every cell, making 8 new tets 981412e9a14SMatthew 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 982412e9a14SMatthew 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] 983412e9a14SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 984412e9a14SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 985412e9a14SMatthew G. Knepley The first four tets just cut off the corners, using the replica notation for new vertices, 986412e9a14SMatthew G. Knepley [v0, (e0, 0), (e2, 0), (e3, 0)] 987412e9a14SMatthew G. Knepley [(e0, 0), v1, (e1, 0), (e4, 0)] 988412e9a14SMatthew G. Knepley [(e2, 0), (e1, 0), v2, (e5, 0)] 989412e9a14SMatthew G. Knepley [(e3, 0), (e4, 0), (e5, 0), v3 ] 990412e9a14SMatthew G. Knepley The next four tets match a vertex to the newly created faces from cutting off those first tets. 991412e9a14SMatthew G. Knepley [(e2, 0), (e3, 0), (e0, 0), (e5, 0)] 992412e9a14SMatthew G. Knepley [(e4, 0), (e1, 0), (e0, 0), (e5, 0)] 993412e9a14SMatthew G. Knepley [(e5, 0), (e0, 0), (e2, 0), (e1, 0)] 994412e9a14SMatthew G. Knepley [(e5, 0), (e0, 0), (e4, 0), (e3, 0)] 995412e9a14SMatthew 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 996412e9a14SMatthew G. Knepley [(e2, 0), (e0, 0), (e3, 0)] 997412e9a14SMatthew G. Knepley [(e0, 0), (e1, 0), (e4, 0)] 998412e9a14SMatthew G. Knepley [(e2, 0), (e5, 0), (e1, 0)] 999412e9a14SMatthew G. Knepley [(e3, 0), (e4, 0), (e5, 0)] 1000412e9a14SMatthew G. Knepley The next four, from the second group of tets, are 1001412e9a14SMatthew G. Knepley [(e2, 0), (e0, 0), (e5, 0)] 1002412e9a14SMatthew G. Knepley [(e4, 0), (e0, 0), (e5, 0)] 1003412e9a14SMatthew G. Knepley [(e0, 0), (e1, 0), (e5, 0)] 1004412e9a14SMatthew G. Knepley [(e5, 0), (e3, 0), (e0, 0)] 1005412e9a14SMatthew G. Knepley I could write a program to generate these orientations by comparing the faces from GetRawFaces() with my existing table. 1006412e9a14SMatthew G. Knepley */ 1007412e9a14SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON}; 1008412e9a14SMatthew G. Knepley static PetscInt tetS[] = {1, 8, 8}; 1009412e9a14SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 2, 2, 1, 0, 1010412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 2, 2, 1011412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 1, 1, 1012412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 1, 0, 1, 1013412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 2, 1, 1014412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1015412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, 1016412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 0, 1017412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0, 0, 1018412e9a14SMatthew 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, 1019412e9a14SMatthew 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, 1020412e9a14SMatthew 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, 1021412e9a14SMatthew 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, 1022412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 2, 3, DM_POLYTOPE_TRIANGLE, 0, 4, DM_POLYTOPE_TRIANGLE, 0, 7, 1023412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 1, 3, 3, DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 6, 1024412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 4, DM_POLYTOPE_TRIANGLE, 0, 6, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 1, 0, 3, 1025412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 7, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 1, 1, 3}; 1026412e9a14SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 1027412e9a14SMatthew G. Knepley 0, 0, 0, 1028412e9a14SMatthew G. Knepley 0, 0, 0, 1029412e9a14SMatthew G. Knepley 0, 0, 0, 1030412e9a14SMatthew G. Knepley 0, 0, 0, 1031412e9a14SMatthew G. Knepley 0, 0, -2, 1032412e9a14SMatthew G. Knepley 0, 0, -2, 1033412e9a14SMatthew G. Knepley 0, -2, -2, 1034412e9a14SMatthew G. Knepley 0, -2, 0, 1035412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1036412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1037412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1038412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1039412e9a14SMatthew G. Knepley -3, 0, 0, -2, 1040412e9a14SMatthew G. Knepley -2, 1, 0, 0, 1041412e9a14SMatthew G. Knepley -2, -2, -1, 2, 1042412e9a14SMatthew G. Knepley -2, 0, -2, 1}; 1043412e9a14SMatthew G. Knepley /* Add a vertex in the center of each cell, add 6 edges and 12 quads inside every cell, making 8 new hexes 1044412e9a14SMatthew 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 1045412e9a14SMatthew G. Knepley [v0, v1, v2, v3] f0 bottom 1046412e9a14SMatthew G. Knepley [v4, v5, v6, v7] f1 top 1047412e9a14SMatthew G. Knepley [v0, v3, v5, v4] f2 front 1048412e9a14SMatthew G. Knepley [v2, v1, v7, v6] f3 back 1049412e9a14SMatthew G. Knepley [v3, v2, v6, v5] f4 right 1050412e9a14SMatthew G. Knepley [v0, v4, v7, v1] f5 left 1051412e9a14SMatthew G. Knepley The eight hexes are divided into four on the bottom, and four on the top, 1052412e9a14SMatthew G. Knepley [v0, (e0, 0), (f0, 0), (e3, 0), (e9, 0), (f2, 0), (c0, 0), (f5, 0)] 1053412e9a14SMatthew G. Knepley [(e0, 0), v1, (e1, 0), (f0, 0), (f5, 0), (c0, 0), (f3, 0), (e10, 0)] 1054412e9a14SMatthew G. Knepley [(f0, 0), (e1, 0), v2, (e2, 0), (c0, 0), (f4, 0), (e11, 0), (f3, 0)] 1055412e9a14SMatthew G. Knepley [(e3, 0), (f0, 0), (e2, 0), v3, (f2, 0), (e8, 0), (f4, 0), (c0, 0)] 1056412e9a14SMatthew G. Knepley [(e9, 0), (f5, 0), (c0, 0), (f2, 0), v4, (e4, 0), (f1, 0), (e7, 0)] 1057412e9a14SMatthew G. Knepley [(f2, 0), (c0, 0), (f4, 0), (e8, 0), (e4, 0), v5, (e5, 0), (f1, 0)] 1058412e9a14SMatthew G. Knepley [(c0, 0), (f3, 0), (e11, 0), (f4, 0), (f1, 0), (e5, 0), v6, (e6, 0)] 1059412e9a14SMatthew G. Knepley [(f5, 0), (e10, 0), (f3, 0), (c0, 0), (e7, 0), (f1, 0), (e6, 0), v7] 1060412e9a14SMatthew 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, 1061412e9a14SMatthew G. Knepley [(e9, 0), (f2, 0), (c0, 0), (f5, 0)] 1062412e9a14SMatthew G. Knepley [(f5, 0), (c0, 0), (f3, 0), (e10, 0)] 1063412e9a14SMatthew G. Knepley [(c0, 0), (f4, 0), (e11, 0), (f3, 0)] 1064412e9a14SMatthew G. Knepley [(f2, 0), (e8, 0), (f4, 0), (c0, 0)] 1065412e9a14SMatthew G. Knepley and on the x-z plane, 1066412e9a14SMatthew G. Knepley [(f0, 0), (e0, 0), (f5, 0), (c0, 0)] 1067412e9a14SMatthew G. Knepley [(c0, 0), (f5, 0), (e7, 0), (f1, 0)] 1068412e9a14SMatthew G. Knepley [(f4, 0), (c0, 0), (f1, 0), (e5, 0)] 1069412e9a14SMatthew G. Knepley [(e2, 0), (f0, 0), (c0, 0), (f4, 0)] 1070412e9a14SMatthew G. Knepley and on the y-z plane, 1071412e9a14SMatthew G. Knepley [(e3, 0), (f2, 0), (c0, 0), (f0, 0)] 1072412e9a14SMatthew G. Knepley [(f2, 0), (e4, 0), (f1, 0), (c0, 0)] 1073412e9a14SMatthew G. Knepley [(c0, 0), (f1, 0), (e6, 0), (f3, 0)] 1074412e9a14SMatthew G. Knepley [(f0, 0), (c0, 0), (f3, 0), (e1, 0)] 1075412e9a14SMatthew G. Knepley */ 1076412e9a14SMatthew G. Knepley static DMPolytopeType hexT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1077412e9a14SMatthew G. Knepley static PetscInt hexS[] = {1, 6, 12, 8}; 1078412e9a14SMatthew G. Knepley static PetscInt hexC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1079412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1080412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1081412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1082412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0, 1083412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 5, 0, DM_POLYTOPE_POINT, 0, 0, 1084412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 1, 5, 0, 1085412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 5, 2, 1086412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 3, 1087412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 2, 1088412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 5, 3, DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 0, 0, 1089412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 1, 5, 1, DM_POLYTOPE_SEGMENT, 1, 1, 3, DM_POLYTOPE_SEGMENT, 0, 1, 1090412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 4, 2, 1091412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 0, 1092412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 0, 3, 1093412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 1094412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 3, 1095412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1, 1096412e9a14SMatthew 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, 1097412e9a14SMatthew 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, 1098412e9a14SMatthew 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, 1099412e9a14SMatthew 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, 1100412e9a14SMatthew 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, 1101412e9a14SMatthew 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, 1102412e9a14SMatthew 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, 1103412e9a14SMatthew 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}; 1104412e9a14SMatthew G. Knepley static PetscInt hexO[] = {0, 0, 1105412e9a14SMatthew G. Knepley 0, 0, 1106412e9a14SMatthew G. Knepley 0, 0, 1107412e9a14SMatthew G. Knepley 0, 0, 1108412e9a14SMatthew G. Knepley 0, 0, 1109412e9a14SMatthew G. Knepley 0, 0, 1110412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1111412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1112412e9a14SMatthew G. Knepley -2, -2, 0, 0, 1113412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1114412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1115412e9a14SMatthew G. Knepley -2, -2, 0, 0, 1116412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1117412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1118412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1119412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1120412e9a14SMatthew G. Knepley -2, -2, 0, 0, 1121412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1122412e9a14SMatthew G. Knepley 0, 0, 0, 0, -4, 0, 1123412e9a14SMatthew G. Knepley 0, 0, -1, 0, -4, 0, 1124412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1125412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 1126412e9a14SMatthew G. Knepley -4, 0, 0, 0, -4, 0, 1127412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, 0, 1128412e9a14SMatthew G. Knepley -4, 0, -1, 0, 0, 0, 1129412e9a14SMatthew G. Knepley -4, 0, -1, 0, -4, 0}; 1130412e9a14SMatthew G. Knepley /* Add 3 quads inside every triangular prism, making 4 new prisms. */ 1131412e9a14SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_TRI_PRISM}; 1132412e9a14SMatthew G. Knepley static PetscInt tripS[] = {3, 4, 6, 8}; 1133412e9a14SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 3, 0, 1134412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 1, 4, 0, 1135412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 1, 2, 0, 1136412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 4, 1, 1137412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 0, 1138412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, 1139412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 1140412e9a14SMatthew 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, 1141412e9a14SMatthew 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, 1142412e9a14SMatthew 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, 1143412e9a14SMatthew 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, 1144412e9a14SMatthew 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, 1145412e9a14SMatthew 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, 1146412e9a14SMatthew 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, 1147412e9a14SMatthew 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, 1148412e9a14SMatthew 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, 1149412e9a14SMatthew 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, 1150412e9a14SMatthew 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, 1151412e9a14SMatthew 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, 1152412e9a14SMatthew 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, 1153412e9a14SMatthew 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}; 1154412e9a14SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 1155412e9a14SMatthew G. Knepley 0, 0, 1156412e9a14SMatthew G. Knepley 0, 0, 1157412e9a14SMatthew G. Knepley 0, -2, -2, 1158412e9a14SMatthew G. Knepley -2, 0, -2, 1159412e9a14SMatthew G. Knepley -2, -2, 0, 1160412e9a14SMatthew G. Knepley 0, 0, 0, 1161412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1162412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1163412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1164412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1165412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1166412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1167412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1168412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1169412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 1170412e9a14SMatthew G. Knepley 2, 0, 0, 0, 0, 1171412e9a14SMatthew G. Knepley -3, 0, 0, -1, 0, 1172412e9a14SMatthew G. Knepley -3, 0, 0, 0, -1, 1173412e9a14SMatthew G. Knepley -3, 0, -1, 0, 0, 1174412e9a14SMatthew G. Knepley -3, 0, 0, 0, 0}; 1175412e9a14SMatthew G. Knepley /* Add 3 tensor quads inside every tensor triangular prism, making 4 new prisms. 1176412e9a14SMatthew G. Knepley 2 1177412e9a14SMatthew G. Knepley |\ 1178412e9a14SMatthew G. Knepley | \ 1179412e9a14SMatthew G. Knepley | \ 1180412e9a14SMatthew G. Knepley 0---1 118175d3a19aSMatthew G. Knepley 1182412e9a14SMatthew G. Knepley 2 118375d3a19aSMatthew G. Knepley 1184412e9a14SMatthew G. Knepley 0 1 118575d3a19aSMatthew G. Knepley 1186412e9a14SMatthew G. Knepley 2 1187412e9a14SMatthew G. Knepley |\ 1188412e9a14SMatthew G. Knepley | \ 1189412e9a14SMatthew G. Knepley | \ 1190412e9a14SMatthew G. Knepley 0---1 1191412e9a14SMatthew G. Knepley */ 1192412e9a14SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_TRI_PRISM_TENSOR}; 1193412e9a14SMatthew G. Knepley static PetscInt ttripS[] = {3, 4}; 1194412e9a14SMatthew 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, 1195412e9a14SMatthew 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, 1196412e9a14SMatthew 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, 1197412e9a14SMatthew 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, 1198412e9a14SMatthew 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, 1199412e9a14SMatthew 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, 1200412e9a14SMatthew 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}; 1201412e9a14SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 0, 0, 1202412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1203412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1204412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1205412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1206412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 1207412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0}; 1208412e9a14SMatthew G. Knepley /* Add 1 edge and 4 tensor quads inside every tensor quad prism, making 4 new prisms. */ 1209412e9a14SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1210412e9a14SMatthew G. Knepley static PetscInt tquadpS[] = {1, 4, 4}; 1211412e9a14SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1212412e9a14SMatthew 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, 1213412e9a14SMatthew 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, 1214412e9a14SMatthew 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, 1215412e9a14SMatthew 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, 1216412e9a14SMatthew 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, 1217412e9a14SMatthew 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, 1218412e9a14SMatthew 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, 1219412e9a14SMatthew 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}; 1220412e9a14SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 1221412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1222412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1223412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1224412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1225412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1226412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1227412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1228412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 1229da9060c4SMatthew G. Knepley PetscErrorCode ierr; 123075d3a19aSMatthew G. Knepley 1231412e9a14SMatthew G. Knepley PetscFunctionBegin; 12323f2a96e3SMatthew G. Knepley if (rt) *rt = 0; 1233412e9a14SMatthew G. Knepley switch (source) { 1234412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break; 1235412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nt = 2; *target = edgeT; *size = edgeS; *cone = edgeC; *ornt = edgeO; break; 1236412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 1237412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 2; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1238412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nt = 3; *target = quadT; *size = quadS; *cone = quadC; *ornt = quadO; break; 1239412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 2; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 1240412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 3; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1241412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nt = 4; *target = hexT; *size = hexS; *cone = hexC; *ornt = hexO; break; 1242412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1243412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 2; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 1244412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 1245da9060c4SMatthew G. Knepley /* TODO Fix pyramids: For now, we just ignore them */ 1246da9060c4SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 12473f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, p, rt, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1248da9060c4SMatthew G. Knepley break; 1249412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1250412e9a14SMatthew G. Knepley } 1251412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1252412e9a14SMatthew G. Knepley } 125375d3a19aSMatthew G. Knepley 12543f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_ToBox(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt p, PetscInt *rt, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1255412e9a14SMatthew G. Knepley { 1256412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1257412e9a14SMatthew G. Knepley /* Change tensor edges to segments */ 1258412e9a14SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_SEGMENT}; 1259412e9a14SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 1260412e9a14SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 1261412e9a14SMatthew G. Knepley static PetscInt tedgeO[] = { 0, 0}; 1262412e9a14SMatthew G. Knepley /* Add 1 vertex, 3 edges inside every triangle, making 3 new quadrilaterals. 1263e5337592SStefano Zampini 2 1264e5337592SStefano Zampini |\ 1265e5337592SStefano Zampini | \ 1266e5337592SStefano Zampini | \ 1267e5337592SStefano Zampini | \ 1268412e9a14SMatthew G. Knepley 0 1 1269412e9a14SMatthew G. Knepley | \ 1270e5337592SStefano Zampini | \ 1271e5337592SStefano Zampini 2 1 1272e5337592SStefano Zampini |\ / \ 1273e5337592SStefano Zampini | 2 1 \ 1274e5337592SStefano Zampini | \ / \ 1275412e9a14SMatthew G. Knepley 1 | 0 1276e5337592SStefano Zampini | 0 \ 1277e5337592SStefano Zampini | | \ 1278412e9a14SMatthew G. Knepley | | \ 1279412e9a14SMatthew G. Knepley 0-0-0-----1-----1 1280e5337592SStefano Zampini */ 1281412e9a14SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 1282412e9a14SMatthew G. Knepley static PetscInt triS[] = {1, 3, 3}; 1283412e9a14SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1284412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1285412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1286412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 1287412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1288412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0}; 1289412e9a14SMatthew G. Knepley static PetscInt triO[] = {0, 0, 1290412e9a14SMatthew G. Knepley 0, 0, 1291412e9a14SMatthew G. Knepley 0, 0, 1292412e9a14SMatthew G. Knepley 0, 0, -2, 0, 1293412e9a14SMatthew G. Knepley 0, 0, 0, -2, 1294412e9a14SMatthew G. Knepley 0, -2, 0, 0}; 1295412e9a14SMatthew G. Knepley /* Add 1 edge inside every tensor quad, making 2 new quadrilaterals 1296412e9a14SMatthew G. Knepley 2----2----1----3----3 12974330a3fcSStefano Zampini | | | 12984330a3fcSStefano Zampini | | | 12994330a3fcSStefano Zampini | | | 1300412e9a14SMatthew G. Knepley 4 A 6 B 5 13014330a3fcSStefano Zampini | | | 1302412e9a14SMatthew G. Knepley | | | 1303412e9a14SMatthew G. Knepley | | | 1304412e9a14SMatthew G. Knepley 0----0----0----1----1 13054330a3fcSStefano Zampini */ 1306412e9a14SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 1307412e9a14SMatthew G. Knepley static PetscInt tquadS[] = {1, 2}; 1308412e9a14SMatthew G. Knepley static PetscInt tquadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1309412e9a14SMatthew G. Knepley /* TODO Fix these */ 1310412e9a14SMatthew 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, 1311412e9a14SMatthew 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}; 1312412e9a14SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 1313412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1314412e9a14SMatthew G. Knepley 0, 0, -2, -2}; 1315412e9a14SMatthew G. Knepley /* Add 6 triangles inside every cell, making 4 new hexs 1316412e9a14SMatthew G. Knepley TODO: Need different SubcellMap(). Need to make a struct with the function pointers in it 1317412e9a14SMatthew 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 1318412e9a14SMatthew 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] 1319412e9a14SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 1320412e9a14SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 1321412e9a14SMatthew G. Knepley We make a new hex in each corner 1322412e9a14SMatthew G. Knepley [v0, (e0, 0), (f0, 0), (e2, 0), (e3, 0), (f2, 0), (c0, 0), (f1, 0)] 1323412e9a14SMatthew G. Knepley [v1, (e4, 0), (f3, 0), (e1, 0), (e0, 0), (f0, 0), (c0, 0), (f1, 0)] 1324412e9a14SMatthew G. Knepley [v2, (e1, 0), (f3, 0), (e5, 0), (e2, 0), (f2, 0), (c0, 0), (f0, 0)] 1325412e9a14SMatthew G. Knepley [v3, (e4, 0), (f1, 0), (e3, 0), (e5, 0), (f2, 0), (c0, 0), (f3, 0)] 1326412e9a14SMatthew G. Knepley We create a new face for each edge 1327412e9a14SMatthew G. Knepley [(e3, 0), (f2, 0), (c0, 0), (f1, 0)] 1328412e9a14SMatthew G. Knepley [(f0, 0), (e0, 0), (f1, 0), (c0, 0)] 1329412e9a14SMatthew G. Knepley [(e2, 0), (f0, 0), (c0, 0), (f2, 0)] 1330412e9a14SMatthew G. Knepley [(f3, 0), (e4, 0), (f1, 0), (c0, 0)] 1331412e9a14SMatthew G. Knepley [(e1, 0), (f3, 0), (c0, 0), (f0, 0)] 1332412e9a14SMatthew G. Knepley [(e5, 0), (f3, 0), (c0, 0), (f2, 0)] 1333412e9a14SMatthew 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. 133475d3a19aSMatthew G. Knepley */ 1335412e9a14SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1336412e9a14SMatthew G. Knepley static PetscInt tetS[] = {1, 4, 6, 4}; 1337412e9a14SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1338412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1339412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1340412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1341412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, 1342412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1343412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1344412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 3, 1345412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1, 1346412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 1347412e9a14SMatthew 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, 1348412e9a14SMatthew 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, 1349412e9a14SMatthew 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, 1350412e9a14SMatthew 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}; 1351412e9a14SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 1352412e9a14SMatthew G. Knepley 0, 0, 1353412e9a14SMatthew G. Knepley 0, 0, 1354412e9a14SMatthew G. Knepley 0, 0, 1355412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1356412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1357412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1358412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1359412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1360412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1361412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 1362412e9a14SMatthew G. Knepley 1, -1, 1, 0, 0, 3, 1363412e9a14SMatthew G. Knepley 0, -4, 1, -1, 0, 3, 1364412e9a14SMatthew G. Knepley 1, -4, 3, -2, -4, 3}; 1365412e9a14SMatthew G. Knepley /* Add 3 quads inside every triangular prism, making 4 new prisms. */ 1366412e9a14SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1367412e9a14SMatthew G. Knepley static PetscInt tripS[] = {1, 5, 9, 6}; 1368412e9a14SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1369412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1370412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1371412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1372412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0, 1373412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 1, 1374412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, 1375412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, 1376412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1377412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 0, 1378412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 0, 1379412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 2, 1380412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 3, 2, 1381412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 4, 2, 1382412e9a14SMatthew 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, 1383412e9a14SMatthew 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, 1384412e9a14SMatthew 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, 1385412e9a14SMatthew 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, 1386412e9a14SMatthew 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, 1387412e9a14SMatthew 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}; 1388412e9a14SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 1389412e9a14SMatthew G. Knepley 0, 0, 1390412e9a14SMatthew G. Knepley 0, 0, 1391412e9a14SMatthew G. Knepley 0, 0, 1392412e9a14SMatthew G. Knepley 0, 0, 1393412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1394412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1395412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1396412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1397412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1398412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1399412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1400412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1401412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1402412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1, 1403412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -4, 1404412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1, 1405412e9a14SMatthew G. Knepley -4, 0, 0, -1, 0, 1, 1406412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, -4, 1407412e9a14SMatthew G. Knepley -4, 0, 0, 0, -1, 1}; 1408412e9a14SMatthew G. Knepley /* Add 3 tensor quads inside every tensor triangular prism, making 4 new tensor triangular prisms. 1409412e9a14SMatthew G. Knepley 2 1410412e9a14SMatthew G. Knepley |\ 1411412e9a14SMatthew G. Knepley | \ 1412412e9a14SMatthew G. Knepley | \ 1413412e9a14SMatthew G. Knepley 0---1 141475d3a19aSMatthew G. Knepley 1415412e9a14SMatthew G. Knepley 2 141675d3a19aSMatthew G. Knepley 1417412e9a14SMatthew G. Knepley 0 1 141875d3a19aSMatthew G. Knepley 1419412e9a14SMatthew G. Knepley 2 1420412e9a14SMatthew G. Knepley |\ 1421412e9a14SMatthew G. Knepley | \ 1422412e9a14SMatthew G. Knepley | \ 1423412e9a14SMatthew G. Knepley 0---1 142475d3a19aSMatthew G. Knepley */ 1425412e9a14SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1426412e9a14SMatthew G. Knepley static PetscInt ttripS[] = {1, 3, 3}; 1427412e9a14SMatthew G. Knepley static PetscInt ttripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1428412e9a14SMatthew 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, 1429412e9a14SMatthew 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, 1430412e9a14SMatthew 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, 1431412e9a14SMatthew 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, 1432412e9a14SMatthew 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, 1433412e9a14SMatthew 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}; 1434412e9a14SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 1435412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1436412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1437412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1438412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1439412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1440412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 1441412e9a14SMatthew G. Knepley /* TODO Add 3 quads inside every tensor triangular prism, making 4 new triangular prisms. 1442412e9a14SMatthew G. Knepley 2 1443412e9a14SMatthew G. Knepley |\ 1444412e9a14SMatthew G. Knepley | \ 1445412e9a14SMatthew G. Knepley | \ 1446412e9a14SMatthew G. Knepley 0---1 144775d3a19aSMatthew G. Knepley 1448412e9a14SMatthew G. Knepley 2 144975d3a19aSMatthew G. Knepley 1450412e9a14SMatthew G. Knepley 0 1 145175d3a19aSMatthew G. Knepley 1452412e9a14SMatthew G. Knepley 2 1453412e9a14SMatthew G. Knepley |\ 1454412e9a14SMatthew G. Knepley | \ 1455412e9a14SMatthew G. Knepley | \ 1456412e9a14SMatthew G. Knepley 0---1 1457a97b51b8SMatthew G. Knepley */ 1458412e9a14SMatthew G. Knepley static DMPolytopeType ctripT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1459412e9a14SMatthew G. Knepley static PetscInt ctripS[] = {1, 3, 3}; 1460412e9a14SMatthew G. Knepley static PetscInt ctripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1461412e9a14SMatthew 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, 1462412e9a14SMatthew 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, 1463412e9a14SMatthew 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, 1464412e9a14SMatthew 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, 1465412e9a14SMatthew 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, 1466412e9a14SMatthew 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}; 1467412e9a14SMatthew G. Knepley static PetscInt ctripO[] = {0, 0, 1468412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1469412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1470412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1471412e9a14SMatthew G. Knepley -4, 0, 0, -1, 0, 1, 1472412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, -4, 1473412e9a14SMatthew G. Knepley -4, 0, 0, 0, -1, 1}; 1474412e9a14SMatthew G. Knepley /* Add 1 edge and 4 quads inside every tensor quad prism, making 4 new hexahedra. */ 1475412e9a14SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1476412e9a14SMatthew G. Knepley static PetscInt tquadpS[] = {1, 4, 4}; 1477412e9a14SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1478412e9a14SMatthew 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, 1479412e9a14SMatthew 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, 1480412e9a14SMatthew 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, 1481412e9a14SMatthew 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, 1482412e9a14SMatthew 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, 1483412e9a14SMatthew 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, 1484412e9a14SMatthew 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, 1485412e9a14SMatthew 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}; 1486412e9a14SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 1487412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1488412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1489412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1490412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1491412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1492412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1493412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1494412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 1495412e9a14SMatthew G. Knepley PetscBool convertTensor = PETSC_TRUE; 1496a97b51b8SMatthew G. Knepley 1497412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 14983f2a96e3SMatthew G. Knepley if (rt) *rt = 0; 1499412e9a14SMatthew G. Knepley if (convertTensor) { 1500412e9a14SMatthew G. Knepley switch (source) { 1501412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1502412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1503412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1504412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 15053f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, p, rt, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1506a97b51b8SMatthew G. Knepley break; 1507412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 1508412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 2; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 1509412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 3; *target = ctripT; *size = ctripS; *cone = ctripC; *ornt = ctripO; break; 1510412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 1511412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1512412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1513412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1514da9060c4SMatthew G. Knepley /* TODO Fix pyramids: For now, we just ignore them */ 1515da9060c4SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 15163f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, p, rt, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1517da9060c4SMatthew G. Knepley break; 1518412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1519b5da9499SMatthew G. Knepley } 1520b5da9499SMatthew G. Knepley } else { 1521412e9a14SMatthew G. Knepley switch (source) { 1522412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1523412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1524412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1525412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1526412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1527412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1528412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 15293f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, p, rt, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1530b5da9499SMatthew G. Knepley break; 1531412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1532412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1533412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1534412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 3; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 1535da9060c4SMatthew G. Knepley /* TODO Fix pyramids: For now, we just ignore them */ 1536da9060c4SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 15373f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, p, rt, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1538da9060c4SMatthew G. Knepley break; 1539412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 154027fcede3SMatthew G. Knepley } 154175d3a19aSMatthew G. Knepley } 154275d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 154375d3a19aSMatthew G. Knepley } 154475d3a19aSMatthew G. Knepley 15453f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt p, PetscInt *rt, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 154675d3a19aSMatthew G. Knepley { 1547412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1548412e9a14SMatthew G. Knepley 1549412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 15503f2a96e3SMatthew G. Knepley if (rt) *rt = 0; 1551412e9a14SMatthew G. Knepley switch (source) { 1552412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1553412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1554412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1555412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1556412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 1557412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1558412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 1559412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1560412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1561412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1562412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 15633f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, p, rt, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1564412e9a14SMatthew G. Knepley break; 1565da9060c4SMatthew G. Knepley /* TODO Fix pyramids: For now, we just ignore them */ 1566da9060c4SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 15673f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, p, rt, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1568da9060c4SMatthew G. Knepley break; 1569412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1570412e9a14SMatthew G. Knepley } 1571412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1572412e9a14SMatthew G. Knepley } 1573412e9a14SMatthew G. Knepley 15743f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Alfeld2D(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt p, PetscInt *rt, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1575cf4091a3SMatthew G. Knepley { 1576cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 1577cf4091a3SMatthew G. Knepley /* Add 1 vertex, 3 edges inside every triangle, making 3 new triangles. 1578cf4091a3SMatthew G. Knepley 2 1579cf4091a3SMatthew G. Knepley |\ 1580cf4091a3SMatthew G. Knepley |\\ 1581cf4091a3SMatthew G. Knepley | |\ 1582cf4091a3SMatthew G. Knepley | \ \ 1583cf4091a3SMatthew G. Knepley | | \ 1584cf4091a3SMatthew G. Knepley | \ \ 1585cf4091a3SMatthew G. Knepley | | \ 1586cf4091a3SMatthew G. Knepley 2 \ \ 1587cf4091a3SMatthew G. Knepley | | 1 1588cf4091a3SMatthew G. Knepley | 2 \ 1589cf4091a3SMatthew G. Knepley | | \ 1590cf4091a3SMatthew G. Knepley | /\ \ 1591cf4091a3SMatthew G. Knepley | 0 1 | 1592cf4091a3SMatthew G. Knepley | / \ | 1593cf4091a3SMatthew G. Knepley |/ \| 1594cf4091a3SMatthew G. Knepley 0---0----1 1595cf4091a3SMatthew G. Knepley */ 1596cf4091a3SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE}; 1597cf4091a3SMatthew G. Knepley static PetscInt triS[] = {1, 3, 3}; 1598cf4091a3SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1599cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 2, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1600cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 2, 2, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1601cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1602cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, 1603cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2}; 1604cf4091a3SMatthew G. Knepley static PetscInt triO[] = {0, 0, 1605cf4091a3SMatthew G. Knepley 0, 0, 1606cf4091a3SMatthew G. Knepley 0, 0, 1607cf4091a3SMatthew G. Knepley 0, 0, -2, 1608cf4091a3SMatthew G. Knepley 0, 0, -2, 1609cf4091a3SMatthew G. Knepley 0, 0, -2}; 1610cf4091a3SMatthew G. Knepley 1611cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 16123f2a96e3SMatthew G. Knepley if (rt) *rt = 0; 1613cf4091a3SMatthew G. Knepley switch (source) { 1614cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT: 1615cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1616cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1617cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1618cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1619cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 1620cf4091a3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1621cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1622cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 1623cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1624da9060c4SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 16253f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, p, rt, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1626cf4091a3SMatthew G. Knepley break; 1627cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1628cf4091a3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1629cf4091a3SMatthew G. Knepley } 1630cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 1631cf4091a3SMatthew G. Knepley } 1632cf4091a3SMatthew G. Knepley 16333f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Alfeld3D(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt p, PetscInt *rt, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1634cf4091a3SMatthew G. Knepley { 1635cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 1636cf4091a3SMatthew G. Knepley /* Add 6 triangles inside every cell, making 4 new tets 1637cf4091a3SMatthew 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 1638cf4091a3SMatthew 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] 1639cf4091a3SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 1640cf4091a3SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 1641cf4091a3SMatthew G. Knepley We make a new tet on each face 1642cf4091a3SMatthew G. Knepley [v0, v1, v2, (c0, 0)] 1643cf4091a3SMatthew G. Knepley [v0, v3, v1, (c0, 0)] 1644cf4091a3SMatthew G. Knepley [v0, v2, v3, (c0, 0)] 1645cf4091a3SMatthew G. Knepley [v2, v1, v3, (c0, 0)] 1646cf4091a3SMatthew G. Knepley We create a new face for each edge 1647cf4091a3SMatthew G. Knepley [v0, (c0, 0), v1 ] 1648cf4091a3SMatthew G. Knepley [v0, v2, (c0, 0)] 1649cf4091a3SMatthew G. Knepley [v2, v1, (c0, 0)] 1650cf4091a3SMatthew G. Knepley [v0, (c0, 0), v3 ] 1651cf4091a3SMatthew G. Knepley [v1, v3, (c0, 0)] 1652cf4091a3SMatthew G. Knepley [v3, v2, (c0, 0)] 1653cf4091a3SMatthew G. Knepley */ 1654cf4091a3SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON}; 1655cf4091a3SMatthew G. Knepley static PetscInt tetS[] = {1, 4, 6, 4}; 1656cf4091a3SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 3, 0, 0, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1657cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 3, 0, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1658cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 3, 0, 2, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1659cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 3, 1, 0, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1660cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 2, 0, 0, 0, 1661cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 0, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, 1662cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 0, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 1663cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 2, 1, 0, 0, 1664cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 1, 1665cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 2, 1, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 3, 1666cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 2, 1667cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 4, 1668cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 5, 1669cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 3, 0, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 4}; 1670cf4091a3SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 1671cf4091a3SMatthew G. Knepley 0, 0, 1672cf4091a3SMatthew G. Knepley 0, 0, 1673cf4091a3SMatthew G. Knepley 0, 0, 1674cf4091a3SMatthew G. Knepley 0, -2, -2, 1675cf4091a3SMatthew G. Knepley -2, 0, -2, 1676cf4091a3SMatthew G. Knepley -2, 0, -2, 1677cf4091a3SMatthew G. Knepley 0, -2, -2, 1678cf4091a3SMatthew G. Knepley -2, 0, -2, 1679cf4091a3SMatthew G. Knepley -2, 0, -2, 1680cf4091a3SMatthew G. Knepley 0, 0, 0, 0, 1681cf4091a3SMatthew G. Knepley 0, 0, -3, 0, 1682cf4091a3SMatthew G. Knepley 0, -3, -3, 0, 1683cf4091a3SMatthew G. Knepley 0, -3, -1, -1}; 1684cf4091a3SMatthew G. Knepley 1685cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 16863f2a96e3SMatthew G. Knepley if (rt) *rt = 0; 1687cf4091a3SMatthew G. Knepley switch (source) { 1688cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT: 1689cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1690cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1691cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1692cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1693cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1694cf4091a3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1695cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1696cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 1697cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1698da9060c4SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 16993f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, p, rt, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1700cf4091a3SMatthew G. Knepley break; 1701cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1702cf4091a3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1703cf4091a3SMatthew G. Knepley } 1704cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 1705cf4091a3SMatthew G. Knepley } 1706cf4091a3SMatthew G. Knepley 1707a5801f52SStefano Zampini typedef struct { 1708a5801f52SStefano Zampini PetscInt n; 1709a5801f52SStefano Zampini PetscReal r; 1710a5801f52SStefano Zampini PetscScalar *h; 1711a5801f52SStefano Zampini PetscInt *Nt; 1712a5801f52SStefano Zampini DMPolytopeType **target; 1713a5801f52SStefano Zampini PetscInt **size; 1714a5801f52SStefano Zampini PetscInt **cone; 1715a5801f52SStefano Zampini PetscInt **ornt; 1716a5801f52SStefano Zampini } PlexRefiner_BL; 1717a5801f52SStefano Zampini 1718a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerSetUp_BL(DMPlexCellRefiner cr) 1719a5801f52SStefano Zampini { 1720a5801f52SStefano Zampini PlexRefiner_BL *crbl; 1721a5801f52SStefano Zampini PetscErrorCode ierr; 1722a5801f52SStefano Zampini PetscInt i,n; 1723a5801f52SStefano Zampini PetscReal r; 1724a5801f52SStefano Zampini PetscInt c1,c2,o1,o2; 1725a5801f52SStefano Zampini 1726a5801f52SStefano Zampini PetscFunctionBegin; 1727a5801f52SStefano Zampini ierr = PetscNew(&crbl);CHKERRQ(ierr); 1728a5801f52SStefano Zampini cr->data = crbl; 1729a5801f52SStefano Zampini crbl->n = 1; /* 1 split -> 2 new cells */ 1730a5801f52SStefano Zampini crbl->r = 1; /* linear progression */ 1731a5801f52SStefano Zampini 1732a5801f52SStefano Zampini /* TODO: add setfromoptions to the refiners? */ 1733a5801f52SStefano Zampini ierr = PetscOptionsGetInt(((PetscObject) cr->dm)->options,((PetscObject) cr->dm)->prefix, "-dm_plex_refine_boundarylayer_splits", &crbl->n, NULL);CHKERRQ(ierr); 1734a5801f52SStefano Zampini if (crbl->n < 1) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Number of splits %D must be positive",crbl->n); 1735a5801f52SStefano Zampini ierr = PetscOptionsGetReal(((PetscObject) cr->dm)->options,((PetscObject) cr->dm)->prefix, "-dm_plex_refine_boundarylayer_progression", &crbl->r, NULL);CHKERRQ(ierr); 1736a5801f52SStefano Zampini n = crbl->n; 1737a5801f52SStefano Zampini r = crbl->r; 1738a5801f52SStefano Zampini 1739a5801f52SStefano Zampini /* we only split DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_TRI_PRISM_TENSOR and DM_POLYTOPE_QUAD_PRISM_TENSOR */ 1740a5801f52SStefano Zampini ierr = PetscMalloc5(4,&crbl->Nt,4,&crbl->target,4,&crbl->size,4,&crbl->cone,4,&crbl->ornt);CHKERRQ(ierr); 1741a5801f52SStefano Zampini 1742a5801f52SStefano Zampini /* progression */ 1743a5801f52SStefano Zampini ierr = PetscMalloc1(n,&crbl->h);CHKERRQ(ierr); 1744a5801f52SStefano Zampini if (r > 1) { 1745a5801f52SStefano Zampini PetscReal d = (r-1.)/(PetscPowRealInt(r,n+1)-1.); 1746a5801f52SStefano Zampini 1747a5801f52SStefano Zampini crbl->h[0] = d; 1748a5801f52SStefano Zampini for (i = 1; i < n; i++) { 1749a5801f52SStefano Zampini d *= r; 1750a5801f52SStefano Zampini crbl->h[i] = crbl->h[i-1] + d; 1751a5801f52SStefano Zampini } 1752a5801f52SStefano Zampini } else { /* linear */ 1753a5801f52SStefano Zampini for (i = 0; i < n; i++) crbl->h[i] = (i + 1.)/(n+1); /* linear */ 1754a5801f52SStefano Zampini } 1755a5801f52SStefano Zampini 1756a5801f52SStefano Zampini /* DM_POLYTOPE_POINT_PRISM_TENSOR produces n points and n+1 tensor segments */ 1757a5801f52SStefano Zampini c1 = 14+6*(n-1); 1758a5801f52SStefano Zampini o1 = 2*(n+1); 1759a5801f52SStefano Zampini crbl->Nt[0] = 2; 1760a5801f52SStefano Zampini 1761a5801f52SStefano Zampini ierr = PetscMalloc4(crbl->Nt[0],&crbl->target[0],crbl->Nt[0],&crbl->size[0],c1,&crbl->cone[0],o1,&crbl->ornt[0]);CHKERRQ(ierr); 1762a5801f52SStefano Zampini 1763a5801f52SStefano Zampini crbl->target[0][0] = DM_POLYTOPE_POINT; 1764a5801f52SStefano Zampini crbl->target[0][1] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1765a5801f52SStefano Zampini 1766a5801f52SStefano Zampini crbl->size[0][0] = n; 1767a5801f52SStefano Zampini crbl->size[0][1] = n+1; 1768a5801f52SStefano Zampini 1769a5801f52SStefano Zampini /* the tensor segments */ 1770a5801f52SStefano Zampini crbl->cone[0][0] = DM_POLYTOPE_POINT; 1771a5801f52SStefano Zampini crbl->cone[0][1] = 1; 1772a5801f52SStefano Zampini crbl->cone[0][2] = 0; 1773a5801f52SStefano Zampini crbl->cone[0][3] = 0; 1774a5801f52SStefano Zampini crbl->cone[0][4] = DM_POLYTOPE_POINT; 1775a5801f52SStefano Zampini crbl->cone[0][5] = 0; 1776a5801f52SStefano Zampini crbl->cone[0][6] = 0; 1777a5801f52SStefano Zampini for (i = 0; i < n-1; i++) { 1778a5801f52SStefano Zampini crbl->cone[0][7+6*i+0] = DM_POLYTOPE_POINT; 1779a5801f52SStefano Zampini crbl->cone[0][7+6*i+1] = 0; 1780a5801f52SStefano Zampini crbl->cone[0][7+6*i+2] = i; 1781a5801f52SStefano Zampini crbl->cone[0][7+6*i+3] = DM_POLYTOPE_POINT; 1782a5801f52SStefano Zampini crbl->cone[0][7+6*i+4] = 0; 1783a5801f52SStefano Zampini crbl->cone[0][7+6*i+5] = i+1; 1784a5801f52SStefano Zampini } 1785a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+0] = DM_POLYTOPE_POINT; 1786a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+1] = 0; 1787a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+2] = n-1; 1788a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+3] = DM_POLYTOPE_POINT; 1789a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+4] = 1; 1790a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+5] = 1; 1791a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+6] = 0; 1792a5801f52SStefano Zampini for (i = 0; i < o1; i++) crbl->ornt[0][i] = 0; 1793a5801f52SStefano Zampini 1794a5801f52SStefano Zampini /* DM_POLYTOPE_SEG_PRISM_TENSOR produces n segments and n+1 tensor quads */ 1795a5801f52SStefano Zampini c1 = 8*n; 1796a5801f52SStefano Zampini c2 = 30+14*(n-1); 1797a5801f52SStefano Zampini o1 = 2*n; 1798a5801f52SStefano Zampini o2 = 4*(n+1); 1799a5801f52SStefano Zampini crbl->Nt[1] = 2; 1800a5801f52SStefano Zampini 1801a5801f52SStefano Zampini ierr = PetscMalloc4(crbl->Nt[1],&crbl->target[1],crbl->Nt[1],&crbl->size[1],c1+c2,&crbl->cone[1],o1+o2,&crbl->ornt[1]);CHKERRQ(ierr); 1802a5801f52SStefano Zampini 1803a5801f52SStefano Zampini crbl->target[1][0] = DM_POLYTOPE_SEGMENT; 1804a5801f52SStefano Zampini crbl->target[1][1] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1805a5801f52SStefano Zampini 1806a5801f52SStefano Zampini crbl->size[1][0] = n; 1807a5801f52SStefano Zampini crbl->size[1][1] = n+1; 1808a5801f52SStefano Zampini 1809a5801f52SStefano Zampini /* the segments */ 1810a5801f52SStefano Zampini for (i = 0; i < n; i++) { 1811a5801f52SStefano Zampini crbl->cone[1][8*i+0] = DM_POLYTOPE_POINT; 1812a5801f52SStefano Zampini crbl->cone[1][8*i+1] = 1; 1813a5801f52SStefano Zampini crbl->cone[1][8*i+2] = 2; 1814a5801f52SStefano Zampini crbl->cone[1][8*i+3] = i; 1815a5801f52SStefano Zampini crbl->cone[1][8*i+4] = DM_POLYTOPE_POINT; 1816a5801f52SStefano Zampini crbl->cone[1][8*i+5] = 1; 1817a5801f52SStefano Zampini crbl->cone[1][8*i+6] = 3; 1818a5801f52SStefano Zampini crbl->cone[1][8*i+7] = i; 1819a5801f52SStefano Zampini } 1820a5801f52SStefano Zampini 1821a5801f52SStefano Zampini /* the tensor quads */ 1822a5801f52SStefano Zampini crbl->cone[1][c1+ 0] = DM_POLYTOPE_SEGMENT; 1823a5801f52SStefano Zampini crbl->cone[1][c1+ 1] = 1; 1824a5801f52SStefano Zampini crbl->cone[1][c1+ 2] = 0; 1825a5801f52SStefano Zampini crbl->cone[1][c1+ 3] = 0; 1826a5801f52SStefano Zampini crbl->cone[1][c1+ 4] = DM_POLYTOPE_SEGMENT; 1827a5801f52SStefano Zampini crbl->cone[1][c1+ 5] = 0; 1828a5801f52SStefano Zampini crbl->cone[1][c1+ 6] = 0; 1829a5801f52SStefano Zampini crbl->cone[1][c1+ 7] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1830a5801f52SStefano Zampini crbl->cone[1][c1+ 8] = 1; 1831a5801f52SStefano Zampini crbl->cone[1][c1+ 9] = 2; 1832a5801f52SStefano Zampini crbl->cone[1][c1+10] = 0; 1833a5801f52SStefano Zampini crbl->cone[1][c1+11] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1834a5801f52SStefano Zampini crbl->cone[1][c1+12] = 1; 1835a5801f52SStefano Zampini crbl->cone[1][c1+13] = 3; 1836a5801f52SStefano Zampini crbl->cone[1][c1+14] = 0; 1837a5801f52SStefano Zampini for (i = 0; i < n-1; i++) { 1838a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 0] = DM_POLYTOPE_SEGMENT; 1839a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 1] = 0; 1840a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 2] = i; 1841a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 3] = DM_POLYTOPE_SEGMENT; 1842a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 4] = 0; 1843a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 5] = i+1; 1844a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 6] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1845a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 7] = 1; 1846a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 8] = 2; 1847a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 9] = i+1; 1848a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+10] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1849a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+11] = 1; 1850a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+12] = 3; 1851a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+13] = i+1; 1852a5801f52SStefano Zampini } 1853a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 0] = DM_POLYTOPE_SEGMENT; 1854a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 1] = 0; 1855a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 2] = n-1; 1856a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 3] = DM_POLYTOPE_SEGMENT; 1857a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 4] = 1; 1858a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 5] = 1; 1859a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 6] = 0; 1860a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 7] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1861a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 8] = 1; 1862a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 9] = 2; 1863a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+10] = n; 1864a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+11] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1865a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+12] = 1; 1866a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+13] = 3; 1867a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+14] = n; 1868a5801f52SStefano Zampini for (i = 0; i < o1+o2; i++) crbl->ornt[1][i] = 0; 1869a5801f52SStefano Zampini 1870a5801f52SStefano Zampini /* DM_POLYTOPE_TRI_PRISM_TENSOR produces n triangles and n+1 tensor triangular prisms */ 1871a5801f52SStefano Zampini c1 = 12*n; 1872a5801f52SStefano Zampini c2 = 38+18*(n-1); 1873a5801f52SStefano Zampini o1 = 3*n; 1874a5801f52SStefano Zampini o2 = 5*(n+1); 1875a5801f52SStefano Zampini crbl->Nt[2] = 2; 1876a5801f52SStefano Zampini 1877a5801f52SStefano Zampini ierr = PetscMalloc4(crbl->Nt[2],&crbl->target[2],crbl->Nt[2],&crbl->size[2],c1+c2,&crbl->cone[2],o1+o2,&crbl->ornt[2]);CHKERRQ(ierr); 1878a5801f52SStefano Zampini 1879a5801f52SStefano Zampini crbl->target[2][0] = DM_POLYTOPE_TRIANGLE; 1880a5801f52SStefano Zampini crbl->target[2][1] = DM_POLYTOPE_TRI_PRISM_TENSOR; 1881a5801f52SStefano Zampini 1882a5801f52SStefano Zampini crbl->size[2][0] = n; 1883a5801f52SStefano Zampini crbl->size[2][1] = n+1; 1884a5801f52SStefano Zampini 1885a5801f52SStefano Zampini /* the triangles */ 1886a5801f52SStefano Zampini for (i = 0; i < n; i++) { 1887a5801f52SStefano Zampini crbl->cone[2][12*i+ 0] = DM_POLYTOPE_SEGMENT; 1888a5801f52SStefano Zampini crbl->cone[2][12*i+ 1] = 1; 1889a5801f52SStefano Zampini crbl->cone[2][12*i+ 2] = 2; 1890a5801f52SStefano Zampini crbl->cone[2][12*i+ 3] = i; 1891a5801f52SStefano Zampini crbl->cone[2][12*i+ 4] = DM_POLYTOPE_SEGMENT; 1892a5801f52SStefano Zampini crbl->cone[2][12*i+ 5] = 1; 1893a5801f52SStefano Zampini crbl->cone[2][12*i+ 6] = 3; 1894a5801f52SStefano Zampini crbl->cone[2][12*i+ 7] = i; 1895a5801f52SStefano Zampini crbl->cone[2][12*i+ 8] = DM_POLYTOPE_SEGMENT; 1896a5801f52SStefano Zampini crbl->cone[2][12*i+ 9] = 1; 1897a5801f52SStefano Zampini crbl->cone[2][12*i+10] = 4; 1898a5801f52SStefano Zampini crbl->cone[2][12*i+11] = i; 1899a5801f52SStefano Zampini } 1900a5801f52SStefano Zampini 1901a5801f52SStefano Zampini /* the triangular prisms */ 1902a5801f52SStefano Zampini crbl->cone[2][c1+ 0] = DM_POLYTOPE_TRIANGLE; 1903a5801f52SStefano Zampini crbl->cone[2][c1+ 1] = 1; 1904a5801f52SStefano Zampini crbl->cone[2][c1+ 2] = 0; 1905a5801f52SStefano Zampini crbl->cone[2][c1+ 3] = 0; 1906a5801f52SStefano Zampini crbl->cone[2][c1+ 4] = DM_POLYTOPE_TRIANGLE; 1907a5801f52SStefano Zampini crbl->cone[2][c1+ 5] = 0; 1908a5801f52SStefano Zampini crbl->cone[2][c1+ 6] = 0; 1909a5801f52SStefano Zampini crbl->cone[2][c1+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1910a5801f52SStefano Zampini crbl->cone[2][c1+ 8] = 1; 1911a5801f52SStefano Zampini crbl->cone[2][c1+ 9] = 2; 1912a5801f52SStefano Zampini crbl->cone[2][c1+10] = 0; 1913a5801f52SStefano Zampini crbl->cone[2][c1+11] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1914a5801f52SStefano Zampini crbl->cone[2][c1+12] = 1; 1915a5801f52SStefano Zampini crbl->cone[2][c1+13] = 3; 1916a5801f52SStefano Zampini crbl->cone[2][c1+14] = 0; 1917a5801f52SStefano Zampini crbl->cone[2][c1+15] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1918a5801f52SStefano Zampini crbl->cone[2][c1+16] = 1; 1919a5801f52SStefano Zampini crbl->cone[2][c1+17] = 4; 1920a5801f52SStefano Zampini crbl->cone[2][c1+18] = 0; 1921a5801f52SStefano Zampini for (i = 0; i < n-1; i++) { 1922a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 0] = DM_POLYTOPE_TRIANGLE; 1923a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 1] = 0; 1924a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 2] = i; 1925a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 3] = DM_POLYTOPE_TRIANGLE; 1926a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 4] = 0; 1927a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 5] = i+1; 1928a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 6] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1929a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 7] = 1; 1930a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 8] = 2; 1931a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 9] = i+1; 1932a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+10] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1933a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+11] = 1; 1934a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+12] = 3; 1935a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+13] = i+1; 1936a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+14] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1937a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+15] = 1; 1938a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+16] = 4; 1939a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+17] = i+1; 1940a5801f52SStefano Zampini } 1941a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 0] = DM_POLYTOPE_TRIANGLE; 1942a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 1] = 0; 1943a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 2] = n-1; 1944a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 3] = DM_POLYTOPE_TRIANGLE; 1945a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 4] = 1; 1946a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 5] = 1; 1947a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 6] = 0; 1948a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1949a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 8] = 1; 1950a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 9] = 2; 1951a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+10] = n; 1952a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+11] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1953a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+12] = 1; 1954a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+13] = 3; 1955a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+14] = n; 1956a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+15] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1957a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+16] = 1; 1958a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+17] = 4; 1959a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+18] = n; 1960a5801f52SStefano Zampini for (i = 0; i < o1+o2; i++) crbl->ornt[2][i] = 0; 1961a5801f52SStefano Zampini 1962a5801f52SStefano Zampini /* DM_POLYTOPE_QUAD_PRISM_TENSOR produces n quads and n+1 tensor quad prisms */ 1963a5801f52SStefano Zampini c1 = 16*n; 1964a5801f52SStefano Zampini c2 = 46+22*(n-1); 1965a5801f52SStefano Zampini o1 = 4*n; 1966a5801f52SStefano Zampini o2 = 6*(n+1); 1967a5801f52SStefano Zampini crbl->Nt[3] = 2; 1968a5801f52SStefano Zampini 1969a5801f52SStefano Zampini ierr = PetscMalloc4(crbl->Nt[3],&crbl->target[3],crbl->Nt[3],&crbl->size[3],c1+c2,&crbl->cone[3],o1+o2,&crbl->ornt[3]);CHKERRQ(ierr); 1970a5801f52SStefano Zampini 1971a5801f52SStefano Zampini crbl->target[3][0] = DM_POLYTOPE_QUADRILATERAL; 1972a5801f52SStefano Zampini crbl->target[3][1] = DM_POLYTOPE_QUAD_PRISM_TENSOR; 1973a5801f52SStefano Zampini 1974a5801f52SStefano Zampini crbl->size[3][0] = n; 1975a5801f52SStefano Zampini crbl->size[3][1] = n+1; 1976a5801f52SStefano Zampini 1977a5801f52SStefano Zampini /* the quads */ 1978a5801f52SStefano Zampini for (i = 0; i < n; i++) { 1979a5801f52SStefano Zampini crbl->cone[3][16*i+ 0] = DM_POLYTOPE_SEGMENT; 1980a5801f52SStefano Zampini crbl->cone[3][16*i+ 1] = 1; 1981a5801f52SStefano Zampini crbl->cone[3][16*i+ 2] = 2; 1982a5801f52SStefano Zampini crbl->cone[3][16*i+ 3] = i; 1983a5801f52SStefano Zampini crbl->cone[3][16*i+ 4] = DM_POLYTOPE_SEGMENT; 1984a5801f52SStefano Zampini crbl->cone[3][16*i+ 5] = 1; 1985a5801f52SStefano Zampini crbl->cone[3][16*i+ 6] = 3; 1986a5801f52SStefano Zampini crbl->cone[3][16*i+ 7] = i; 1987a5801f52SStefano Zampini crbl->cone[3][16*i+ 8] = DM_POLYTOPE_SEGMENT; 1988a5801f52SStefano Zampini crbl->cone[3][16*i+ 9] = 1; 1989a5801f52SStefano Zampini crbl->cone[3][16*i+10] = 4; 1990a5801f52SStefano Zampini crbl->cone[3][16*i+11] = i; 1991a5801f52SStefano Zampini crbl->cone[3][16*i+12] = DM_POLYTOPE_SEGMENT; 1992a5801f52SStefano Zampini crbl->cone[3][16*i+13] = 1; 1993a5801f52SStefano Zampini crbl->cone[3][16*i+14] = 5; 1994a5801f52SStefano Zampini crbl->cone[3][16*i+15] = i; 1995a5801f52SStefano Zampini } 1996a5801f52SStefano Zampini 1997a5801f52SStefano Zampini /* the quad prisms */ 1998a5801f52SStefano Zampini crbl->cone[3][c1+ 0] = DM_POLYTOPE_QUADRILATERAL; 1999a5801f52SStefano Zampini crbl->cone[3][c1+ 1] = 1; 2000a5801f52SStefano Zampini crbl->cone[3][c1+ 2] = 0; 2001a5801f52SStefano Zampini crbl->cone[3][c1+ 3] = 0; 2002a5801f52SStefano Zampini crbl->cone[3][c1+ 4] = DM_POLYTOPE_QUADRILATERAL; 2003a5801f52SStefano Zampini crbl->cone[3][c1+ 5] = 0; 2004a5801f52SStefano Zampini crbl->cone[3][c1+ 6] = 0; 2005a5801f52SStefano Zampini crbl->cone[3][c1+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2006a5801f52SStefano Zampini crbl->cone[3][c1+ 8] = 1; 2007a5801f52SStefano Zampini crbl->cone[3][c1+ 9] = 2; 2008a5801f52SStefano Zampini crbl->cone[3][c1+10] = 0; 2009a5801f52SStefano Zampini crbl->cone[3][c1+11] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2010a5801f52SStefano Zampini crbl->cone[3][c1+12] = 1; 2011a5801f52SStefano Zampini crbl->cone[3][c1+13] = 3; 2012a5801f52SStefano Zampini crbl->cone[3][c1+14] = 0; 2013a5801f52SStefano Zampini crbl->cone[3][c1+15] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2014a5801f52SStefano Zampini crbl->cone[3][c1+16] = 1; 2015a5801f52SStefano Zampini crbl->cone[3][c1+17] = 4; 2016a5801f52SStefano Zampini crbl->cone[3][c1+18] = 0; 2017a5801f52SStefano Zampini crbl->cone[3][c1+19] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2018a5801f52SStefano Zampini crbl->cone[3][c1+20] = 1; 2019a5801f52SStefano Zampini crbl->cone[3][c1+21] = 5; 2020a5801f52SStefano Zampini crbl->cone[3][c1+22] = 0; 2021a5801f52SStefano Zampini for (i = 0; i < n-1; i++) { 2022a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 0] = DM_POLYTOPE_QUADRILATERAL; 2023a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 1] = 0; 2024a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 2] = i; 2025a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 3] = DM_POLYTOPE_QUADRILATERAL; 2026a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 4] = 0; 2027a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 5] = i+1; 2028a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 6] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2029a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 7] = 1; 2030a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 8] = 2; 2031a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 9] = i+1; 2032a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+10] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2033a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+11] = 1; 2034a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+12] = 3; 2035a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+13] = i+1; 2036a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+14] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2037a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+15] = 1; 2038a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+16] = 4; 2039a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+17] = i+1; 2040a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+18] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2041a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+19] = 1; 2042a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+20] = 5; 2043a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+21] = i+1; 2044a5801f52SStefano Zampini } 2045a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 0] = DM_POLYTOPE_QUADRILATERAL; 2046a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 1] = 0; 2047a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 2] = n-1; 2048a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 3] = DM_POLYTOPE_QUADRILATERAL; 2049a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 4] = 1; 2050a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 5] = 1; 2051a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 6] = 0; 2052a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2053a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 8] = 1; 2054a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 9] = 2; 2055a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+10] = n; 2056a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+11] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2057a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+12] = 1; 2058a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+13] = 3; 2059a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+14] = n; 2060a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+15] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2061a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+16] = 1; 2062a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+17] = 4; 2063a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+18] = n; 2064a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+19] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2065a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+20] = 1; 2066a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+21] = 5; 2067a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+22] = n; 2068a5801f52SStefano Zampini for (i = 0; i < o1+o2; i++) crbl->ornt[3][i] = 0; 2069a5801f52SStefano Zampini PetscFunctionReturn(0); 2070a5801f52SStefano Zampini } 2071a5801f52SStefano Zampini 2072a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerDestroy_BL(DMPlexCellRefiner cr) 2073a5801f52SStefano Zampini { 2074a5801f52SStefano Zampini PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data; 2075a5801f52SStefano Zampini PetscErrorCode ierr; 2076a5801f52SStefano Zampini 2077a5801f52SStefano Zampini PetscFunctionBegin; 2078a5801f52SStefano Zampini ierr = PetscFree4(crbl->target[0],crbl->size[0],crbl->cone[0],crbl->ornt[0]);CHKERRQ(ierr); 2079a5801f52SStefano Zampini ierr = PetscFree4(crbl->target[1],crbl->size[1],crbl->cone[1],crbl->ornt[1]);CHKERRQ(ierr); 2080a5801f52SStefano Zampini ierr = PetscFree4(crbl->target[2],crbl->size[2],crbl->cone[2],crbl->ornt[2]);CHKERRQ(ierr); 2081a5801f52SStefano Zampini ierr = PetscFree4(crbl->target[3],crbl->size[3],crbl->cone[3],crbl->ornt[3]);CHKERRQ(ierr); 2082a5801f52SStefano Zampini ierr = PetscFree5(crbl->Nt,crbl->target,crbl->size,crbl->cone,crbl->ornt);CHKERRQ(ierr); 2083a5801f52SStefano Zampini ierr = PetscFree(crbl->h);CHKERRQ(ierr); 2084a5801f52SStefano Zampini ierr = PetscFree(cr->data);CHKERRQ(ierr); 2085a5801f52SStefano Zampini PetscFunctionReturn(0); 2086a5801f52SStefano Zampini } 2087a5801f52SStefano Zampini 20883f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_BL(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt p, PetscInt *rt, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 2089cf4091a3SMatthew G. Knepley { 2090a5801f52SStefano Zampini PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data; 2091cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 2092cf4091a3SMatthew G. Knepley 2093cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 20943f2a96e3SMatthew G. Knepley if (rt) *rt = 0; 2095cf4091a3SMatthew G. Knepley switch (source) { 2096a5801f52SStefano Zampini case DM_POLYTOPE_POINT_PRISM_TENSOR: 2097a5801f52SStefano Zampini *Nt = crbl->Nt[0]; 2098a5801f52SStefano Zampini *target = crbl->target[0]; 2099a5801f52SStefano Zampini *size = crbl->size[0]; 2100a5801f52SStefano Zampini *cone = crbl->cone[0]; 2101a5801f52SStefano Zampini *ornt = crbl->ornt[0]; 2102cf4091a3SMatthew G. Knepley break; 2103a5801f52SStefano Zampini case DM_POLYTOPE_SEG_PRISM_TENSOR: 2104a5801f52SStefano Zampini *Nt = crbl->Nt[1]; 2105a5801f52SStefano Zampini *target = crbl->target[1]; 2106a5801f52SStefano Zampini *size = crbl->size[1]; 2107a5801f52SStefano Zampini *cone = crbl->cone[1]; 2108a5801f52SStefano Zampini *ornt = crbl->ornt[1]; 2109a5801f52SStefano Zampini break; 2110a5801f52SStefano Zampini case DM_POLYTOPE_TRI_PRISM_TENSOR: 2111a5801f52SStefano Zampini *Nt = crbl->Nt[2]; 2112a5801f52SStefano Zampini *target = crbl->target[2]; 2113a5801f52SStefano Zampini *size = crbl->size[2]; 2114a5801f52SStefano Zampini *cone = crbl->cone[2]; 2115a5801f52SStefano Zampini *ornt = crbl->ornt[2]; 2116a5801f52SStefano Zampini break; 2117a5801f52SStefano Zampini case DM_POLYTOPE_QUAD_PRISM_TENSOR: 2118a5801f52SStefano Zampini *Nt = crbl->Nt[3]; 2119a5801f52SStefano Zampini *target = crbl->target[3]; 2120a5801f52SStefano Zampini *size = crbl->size[3]; 2121a5801f52SStefano Zampini *cone = crbl->cone[3]; 2122a5801f52SStefano Zampini *ornt = crbl->ornt[3]; 2123a5801f52SStefano Zampini break; 2124a5801f52SStefano Zampini default: 21253f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr,source,p,rt,Nt,target,size,cone,ornt);CHKERRQ(ierr); 2126a5801f52SStefano Zampini } 2127a5801f52SStefano Zampini PetscFunctionReturn(0); 2128a5801f52SStefano Zampini } 2129a5801f52SStefano Zampini 21303f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_BL(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt pp, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 2131a5801f52SStefano Zampini { 2132a5801f52SStefano Zampini /* We shift any input orientation in order to make it non-negative 2133a5801f52SStefano Zampini 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) 2134a5801f52SStefano Zampini The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 2135a5801f52SStefano Zampini Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 2136a5801f52SStefano Zampini */ 2137a5801f52SStefano Zampini PetscInt tquad_seg_o[] = { 0, 1, -2, -1, 2138a5801f52SStefano Zampini 0, 1, -2, -1, 2139a5801f52SStefano Zampini -2, -1, 0, 1, 2140a5801f52SStefano Zampini -2, -1, 0, 1}; 2141a5801f52SStefano Zampini PetscInt tquad_tquad_o[] = { 0, 1, -2, -1, 2142a5801f52SStefano Zampini 1, 0, -1, -2, 2143a5801f52SStefano Zampini -2, -1, 0, 1, 2144a5801f52SStefano Zampini -1, -2, 1, 0}; 2145a5801f52SStefano Zampini PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data; 2146a5801f52SStefano Zampini const PetscInt n = crbl->n; 2147a5801f52SStefano Zampini PetscErrorCode ierr; 2148a5801f52SStefano Zampini 2149a5801f52SStefano Zampini PetscFunctionBeginHot; 2150a5801f52SStefano Zampini *rnew = r; 2151a5801f52SStefano Zampini *onew = o; 2152a5801f52SStefano Zampini switch (pct) { 2153a5801f52SStefano Zampini case DM_POLYTOPE_POINT_PRISM_TENSOR: 2154a5801f52SStefano Zampini if (ct == DM_POLYTOPE_POINT_PRISM_TENSOR) { 2155a5801f52SStefano Zampini if (po == 0 || po == -1) {*rnew = r; *onew = o;} 2156a5801f52SStefano Zampini else if (po == 1 || po == -2) {*rnew = n - r; *onew = (o == 0 || o == -1) ? -2 : 0;} 2157a5801f52SStefano Zampini else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid orientation %D for tensor segment", po); 2158a5801f52SStefano Zampini } 2159a5801f52SStefano Zampini break; 2160a5801f52SStefano Zampini case DM_POLYTOPE_SEG_PRISM_TENSOR: 2161a5801f52SStefano Zampini switch (ct) { 2162a5801f52SStefano Zampini case DM_POLYTOPE_SEGMENT: 2163a5801f52SStefano Zampini *onew = tquad_seg_o[(po+2)*4+o+2]; 2164a5801f52SStefano Zampini *rnew = r; 2165a5801f52SStefano Zampini break; 2166a5801f52SStefano Zampini case DM_POLYTOPE_SEG_PRISM_TENSOR: 2167a5801f52SStefano Zampini *onew = tquad_tquad_o[(po+2)*4+o+2]; 2168a5801f52SStefano Zampini *rnew = r; 2169a5801f52SStefano Zampini break; 2170a5801f52SStefano Zampini default: break; 2171a5801f52SStefano Zampini } 2172a5801f52SStefano Zampini break; 2173a5801f52SStefano Zampini default: 21743f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerMapSubcells_None(cr, pct, pp, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 2175a5801f52SStefano Zampini } 2176a5801f52SStefano Zampini PetscFunctionReturn(0); 2177a5801f52SStefano Zampini } 2178a5801f52SStefano Zampini 2179a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapCoordinates_BL(DMPlexCellRefiner cr, DMPolytopeType pct, DMPolytopeType ct, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[]) 2180a5801f52SStefano Zampini { 2181a5801f52SStefano Zampini PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data; 2182a5801f52SStefano Zampini PetscInt d; 2183a5801f52SStefano Zampini PetscErrorCode ierr; 2184a5801f52SStefano Zampini 2185a5801f52SStefano Zampini PetscFunctionBeginHot; 2186a5801f52SStefano Zampini switch (pct) { 2187a5801f52SStefano Zampini case DM_POLYTOPE_POINT_PRISM_TENSOR: 2188a5801f52SStefano Zampini if (ct != DM_POLYTOPE_POINT) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for refined point type %s",DMPolytopeTypes[ct]); 2189a5801f52SStefano Zampini if (Nv != 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for parent vertices %D",Nv); 2190a5801f52SStefano Zampini if (r >= crbl->n || r < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Invalid replica %D, must be in [0,%D)",r,crbl->n); 2191a5801f52SStefano Zampini for (d = 0; d < dE; d++) out[d] = in[d] + crbl->h[r] * (in[d + dE] - in[d]); 2192a5801f52SStefano Zampini break; 2193a5801f52SStefano Zampini default: 2194a5801f52SStefano Zampini ierr = DMPlexCellRefinerMapCoordinates_Barycenter(cr,pct,ct,r,Nv,dE,in,out);CHKERRQ(ierr); 2195cf4091a3SMatthew G. Knepley } 2196cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 2197cf4091a3SMatthew G. Knepley } 2198cf4091a3SMatthew G. Knepley 21993f2a96e3SMatthew G. Knepley typedef struct { 22003f2a96e3SMatthew G. Knepley DMLabel splitPoints; /* List of edges to be bisected (1) and cells to be divided (2) */ 22013f2a96e3SMatthew G. Knepley PetscSection secEdgeLen; /* Section for edge length field */ 22023f2a96e3SMatthew G. Knepley PetscReal *edgeLen; /* Storage for edge length field */ 22033f2a96e3SMatthew G. Knepley PetscInt *splitArray; /* Array for communication of split points label */ 22043f2a96e3SMatthew G. Knepley } PlexRefiner_SBR; 22053f2a96e3SMatthew G. Knepley 22063f2a96e3SMatthew G. Knepley typedef struct _p_PointQueue *PointQueue; 22073f2a96e3SMatthew G. Knepley struct _p_PointQueue { 22083f2a96e3SMatthew G. Knepley PetscInt size; /* Size of the storage array */ 22093f2a96e3SMatthew G. Knepley PetscInt *points; /* Array of mesh points */ 22103f2a96e3SMatthew G. Knepley PetscInt front; /* Index of the front of the queue */ 22113f2a96e3SMatthew G. Knepley PetscInt back; /* Index of the back of the queue */ 22123f2a96e3SMatthew G. Knepley PetscInt num; /* Number of enqueued points */ 22133f2a96e3SMatthew G. Knepley }; 22143f2a96e3SMatthew G. Knepley 22153f2a96e3SMatthew G. Knepley static PetscErrorCode PointQueueCreate(PetscInt size, PointQueue *queue) 22163f2a96e3SMatthew G. Knepley { 22173f2a96e3SMatthew G. Knepley PointQueue q; 22183f2a96e3SMatthew G. Knepley PetscErrorCode ierr; 22193f2a96e3SMatthew G. Knepley 22203f2a96e3SMatthew G. Knepley PetscFunctionBegin; 22213f2a96e3SMatthew G. Knepley if (size < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Queue size %D must be non-negative", size); 22223f2a96e3SMatthew G. Knepley ierr = PetscCalloc1(1, &q);CHKERRQ(ierr); 22233f2a96e3SMatthew G. Knepley q->size = size; 22243f2a96e3SMatthew G. Knepley ierr = PetscMalloc1(q->size, &q->points);CHKERRQ(ierr); 22253f2a96e3SMatthew G. Knepley q->num = 0; 22263f2a96e3SMatthew G. Knepley q->front = 0; 22273f2a96e3SMatthew G. Knepley q->back = q->size-1; 22283f2a96e3SMatthew G. Knepley *queue = q; 22293f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 22303f2a96e3SMatthew G. Knepley } 22313f2a96e3SMatthew G. Knepley 22323f2a96e3SMatthew G. Knepley static PetscErrorCode PointQueueDestroy(PointQueue *queue) 22333f2a96e3SMatthew G. Knepley { 22343f2a96e3SMatthew G. Knepley PointQueue q = *queue; 22353f2a96e3SMatthew G. Knepley PetscErrorCode ierr; 22363f2a96e3SMatthew G. Knepley 22373f2a96e3SMatthew G. Knepley PetscFunctionBegin; 22383f2a96e3SMatthew G. Knepley ierr = PetscFree(q->points);CHKERRQ(ierr); 22393f2a96e3SMatthew G. Knepley ierr = PetscFree(q);CHKERRQ(ierr); 22403f2a96e3SMatthew G. Knepley *queue = NULL; 22413f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 22423f2a96e3SMatthew G. Knepley } 22433f2a96e3SMatthew G. Knepley 22443f2a96e3SMatthew G. Knepley static PetscErrorCode PointQueueEnsureSize(PointQueue queue) 22453f2a96e3SMatthew G. Knepley { 22463f2a96e3SMatthew G. Knepley PetscErrorCode ierr; 22473f2a96e3SMatthew G. Knepley 22483f2a96e3SMatthew G. Knepley PetscFunctionBegin; 22493f2a96e3SMatthew G. Knepley if (queue->num < queue->size) PetscFunctionReturn(0); 22503f2a96e3SMatthew G. Knepley queue->size *= 2; 22513f2a96e3SMatthew G. Knepley ierr = PetscRealloc(queue->size * sizeof(PetscInt), &queue->points);CHKERRQ(ierr); 22523f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 22533f2a96e3SMatthew G. Knepley } 22543f2a96e3SMatthew G. Knepley 22553f2a96e3SMatthew G. Knepley static PetscErrorCode PointQueueEnqueue(PointQueue queue, PetscInt p) 22563f2a96e3SMatthew G. Knepley { 22573f2a96e3SMatthew G. Knepley PetscErrorCode ierr; 22583f2a96e3SMatthew G. Knepley 22593f2a96e3SMatthew G. Knepley PetscFunctionBegin; 22603f2a96e3SMatthew G. Knepley ierr = PointQueueEnsureSize(queue);CHKERRQ(ierr); 22613f2a96e3SMatthew G. Knepley queue->back = (queue->back + 1) % queue->size; 22623f2a96e3SMatthew G. Knepley queue->points[queue->back] = p; 22633f2a96e3SMatthew G. Knepley ++queue->num; 22643f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 22653f2a96e3SMatthew G. Knepley } 22663f2a96e3SMatthew G. Knepley 22673f2a96e3SMatthew G. Knepley static PetscErrorCode PointQueueDequeue(PointQueue queue, PetscInt *p) 22683f2a96e3SMatthew G. Knepley { 22693f2a96e3SMatthew G. Knepley PetscFunctionBegin; 22703f2a96e3SMatthew G. Knepley if (!queue->num) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot dequeue from an empty queue"); 22713f2a96e3SMatthew G. Knepley *p = queue->points[queue->front]; 22723f2a96e3SMatthew G. Knepley queue->front = (queue->front + 1) % queue->size; 22733f2a96e3SMatthew G. Knepley --queue->num; 22743f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 22753f2a96e3SMatthew G. Knepley } 22763f2a96e3SMatthew G. Knepley 22773f2a96e3SMatthew G. Knepley #if 0 22783f2a96e3SMatthew G. Knepley static PetscErrorCode PointQueueFront(PointQueue queue, PetscInt *p) 22793f2a96e3SMatthew G. Knepley { 22803f2a96e3SMatthew G. Knepley PetscFunctionBegin; 22813f2a96e3SMatthew G. Knepley if (!queue->num) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot get the front of an empty queue"); 22823f2a96e3SMatthew G. Knepley *p = queue->points[queue->front]; 22833f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 22843f2a96e3SMatthew G. Knepley } 22853f2a96e3SMatthew G. Knepley 22863f2a96e3SMatthew G. Knepley static PetscErrorCode PointQueueBack(PointQueue queue, PetscInt *p) 22873f2a96e3SMatthew G. Knepley { 22883f2a96e3SMatthew G. Knepley PetscFunctionBegin; 22893f2a96e3SMatthew G. Knepley if (!queue->num) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot get the back of an empty queue"); 22903f2a96e3SMatthew G. Knepley *p = queue->points[queue->back]; 22913f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 22923f2a96e3SMatthew G. Knepley } 22933f2a96e3SMatthew G. Knepley #endif 22943f2a96e3SMatthew G. Knepley 22953f2a96e3SMatthew G. Knepley PETSC_STATIC_INLINE PetscBool PointQueueEmpty(PointQueue queue) 22963f2a96e3SMatthew G. Knepley { 22973f2a96e3SMatthew G. Knepley if (!queue->num) return PETSC_TRUE; 22983f2a96e3SMatthew G. Knepley return PETSC_FALSE; 22993f2a96e3SMatthew G. Knepley } 23003f2a96e3SMatthew G. Knepley 23013f2a96e3SMatthew G. Knepley static PetscErrorCode SBRGetEdgeLen_Private(DMPlexCellRefiner cr, PetscInt edge, PetscReal *len) 23023f2a96e3SMatthew G. Knepley { 23033f2a96e3SMatthew G. Knepley PlexRefiner_SBR *sbr = (PlexRefiner_SBR *) cr->data; 23043f2a96e3SMatthew G. Knepley DM dm = cr->dm; 23053f2a96e3SMatthew G. Knepley PetscInt off; 23063f2a96e3SMatthew G. Knepley PetscErrorCode ierr; 23073f2a96e3SMatthew G. Knepley 23083f2a96e3SMatthew G. Knepley PetscFunctionBeginHot; 23093f2a96e3SMatthew G. Knepley ierr = PetscSectionGetOffset(sbr->secEdgeLen, edge, &off);CHKERRQ(ierr); 23103f2a96e3SMatthew G. Knepley if (sbr->edgeLen[off] <= 0.0) { 23113f2a96e3SMatthew G. Knepley DM cdm; 23123f2a96e3SMatthew G. Knepley Vec coordsLocal; 23133f2a96e3SMatthew G. Knepley const PetscScalar *coords; 23143f2a96e3SMatthew G. Knepley const PetscInt *cone; 23153f2a96e3SMatthew G. Knepley PetscScalar *cA, *cB; 23163f2a96e3SMatthew G. Knepley PetscInt coneSize, cdim; 23173f2a96e3SMatthew G. Knepley 23183f2a96e3SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 23193f2a96e3SMatthew G. Knepley ierr = DMPlexGetCone(dm, edge, &cone);CHKERRQ(ierr); 23203f2a96e3SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, edge, &coneSize);CHKERRQ(ierr); 23213f2a96e3SMatthew G. Knepley if (coneSize != 2) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Edge %D cone size must be 2, not %D", edge, coneSize); 23223f2a96e3SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 23233f2a96e3SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); 23243f2a96e3SMatthew G. Knepley ierr = VecGetArrayRead(coordsLocal, &coords);CHKERRQ(ierr); 23253f2a96e3SMatthew G. Knepley ierr = DMPlexPointLocalRead(cdm, cone[0], coords, &cA);CHKERRQ(ierr); 23263f2a96e3SMatthew G. Knepley ierr = DMPlexPointLocalRead(cdm, cone[1], coords, &cB);CHKERRQ(ierr); 23273f2a96e3SMatthew G. Knepley sbr->edgeLen[off] = DMPlex_DistD_Internal(cdim, cA, cB); 23283f2a96e3SMatthew G. Knepley ierr = VecRestoreArrayRead(coordsLocal, &coords);CHKERRQ(ierr); 23293f2a96e3SMatthew G. Knepley } 23303f2a96e3SMatthew G. Knepley *len = sbr->edgeLen[off]; 23313f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 23323f2a96e3SMatthew G. Knepley } 23333f2a96e3SMatthew G. Knepley 23343f2a96e3SMatthew G. Knepley /* Mark local edges that should be split */ 23353f2a96e3SMatthew G. Knepley /* TODO This will not work in 3D */ 23363f2a96e3SMatthew G. Knepley static PetscErrorCode SBRSplitLocalEdges_Private(DMPlexCellRefiner cr, PointQueue queue) 23373f2a96e3SMatthew G. Knepley { 23383f2a96e3SMatthew G. Knepley PlexRefiner_SBR *sbr = (PlexRefiner_SBR *) cr->data; 23393f2a96e3SMatthew G. Knepley DM dm = cr->dm; 23403f2a96e3SMatthew G. Knepley PetscErrorCode ierr; 23413f2a96e3SMatthew G. Knepley 23423f2a96e3SMatthew G. Knepley PetscFunctionBegin; 23433f2a96e3SMatthew G. Knepley while (!PointQueueEmpty(queue)) { 23443f2a96e3SMatthew G. Knepley PetscInt p = -1; 23453f2a96e3SMatthew G. Knepley const PetscInt *support; 23463f2a96e3SMatthew G. Knepley PetscInt supportSize, s; 23473f2a96e3SMatthew G. Knepley 23483f2a96e3SMatthew G. Knepley ierr = PointQueueDequeue(queue, &p);CHKERRQ(ierr); 23493f2a96e3SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &support);CHKERRQ(ierr); 23503f2a96e3SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 23513f2a96e3SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 23523f2a96e3SMatthew G. Knepley const PetscInt cell = support[s]; 23533f2a96e3SMatthew G. Knepley const PetscInt *cone; 23543f2a96e3SMatthew G. Knepley PetscInt coneSize, c; 23553f2a96e3SMatthew G. Knepley PetscInt cval, eval, maxedge; 23563f2a96e3SMatthew G. Knepley PetscReal len, maxlen; 23573f2a96e3SMatthew G. Knepley 23583f2a96e3SMatthew G. Knepley ierr = DMLabelGetValue(sbr->splitPoints, cell, &cval);CHKERRQ(ierr); 23593f2a96e3SMatthew G. Knepley if (cval == 2) continue; 23603f2a96e3SMatthew G. Knepley ierr = DMPlexGetCone(dm, cell, &cone);CHKERRQ(ierr); 23613f2a96e3SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cell, &coneSize);CHKERRQ(ierr); 23623f2a96e3SMatthew G. Knepley ierr = SBRGetEdgeLen_Private(cr, cone[0], &maxlen);CHKERRQ(ierr); 23633f2a96e3SMatthew G. Knepley maxedge = cone[0]; 23643f2a96e3SMatthew G. Knepley for (c = 1; c < coneSize; ++c) { 23653f2a96e3SMatthew G. Knepley ierr = SBRGetEdgeLen_Private(cr, cone[c], &len);CHKERRQ(ierr); 23663f2a96e3SMatthew G. Knepley if (len > maxlen) {maxlen = len; maxedge = cone[c];} 23673f2a96e3SMatthew G. Knepley } 23683f2a96e3SMatthew G. Knepley ierr = DMLabelGetValue(sbr->splitPoints, maxedge, &eval);CHKERRQ(ierr); 23693f2a96e3SMatthew G. Knepley if (eval != 1) { 23703f2a96e3SMatthew G. Knepley ierr = DMLabelSetValue(sbr->splitPoints, maxedge, 1);CHKERRQ(ierr); 23713f2a96e3SMatthew G. Knepley ierr = PointQueueEnqueue(queue, maxedge);CHKERRQ(ierr); 23723f2a96e3SMatthew G. Knepley } 23733f2a96e3SMatthew G. Knepley ierr = DMLabelSetValue(sbr->splitPoints, cell, 2);CHKERRQ(ierr); 23743f2a96e3SMatthew G. Knepley } 23753f2a96e3SMatthew G. Knepley } 23763f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 23773f2a96e3SMatthew G. Knepley } 23783f2a96e3SMatthew G. Knepley 23793f2a96e3SMatthew G. Knepley static PetscErrorCode SBRInitializeComm(DMPlexCellRefiner cr, PetscSF pointSF) 23803f2a96e3SMatthew G. Knepley { 23813f2a96e3SMatthew G. Knepley PlexRefiner_SBR *sbr = (PlexRefiner_SBR *) cr->data; 23823f2a96e3SMatthew G. Knepley DMLabel splitPoints = sbr->splitPoints; 23833f2a96e3SMatthew G. Knepley PetscInt *splitArray = sbr->splitArray; 23843f2a96e3SMatthew G. Knepley const PetscInt *degree; 23853f2a96e3SMatthew G. Knepley const PetscInt *points; 23863f2a96e3SMatthew G. Knepley PetscInt Nl, l, pStart, pEnd, p, val; 23873f2a96e3SMatthew G. Knepley PetscErrorCode ierr; 23883f2a96e3SMatthew G. Knepley 23893f2a96e3SMatthew G. Knepley PetscFunctionBegin; 23903f2a96e3SMatthew G. Knepley /* Add in leaves */ 23913f2a96e3SMatthew G. Knepley ierr = PetscSFGetGraph(pointSF, NULL, &Nl, &points, NULL);CHKERRQ(ierr); 23923f2a96e3SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 23933f2a96e3SMatthew G. Knepley ierr = DMLabelGetValue(splitPoints, points[l], &val);CHKERRQ(ierr); 23943f2a96e3SMatthew G. Knepley if (val > 0) splitArray[points[l]] = val; 23953f2a96e3SMatthew G. Knepley } 23963f2a96e3SMatthew G. Knepley /* Add in shared roots */ 23973f2a96e3SMatthew G. Knepley ierr = PetscSFComputeDegreeBegin(pointSF, °ree);CHKERRQ(ierr); 23983f2a96e3SMatthew G. Knepley ierr = PetscSFComputeDegreeEnd(pointSF, °ree);CHKERRQ(ierr); 23993f2a96e3SMatthew G. Knepley ierr = DMPlexGetChart(cr->dm, &pStart, &pEnd);CHKERRQ(ierr); 24003f2a96e3SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 24013f2a96e3SMatthew G. Knepley if (degree[p]) { 24023f2a96e3SMatthew G. Knepley ierr = DMLabelGetValue(splitPoints, p, &val);CHKERRQ(ierr); 24033f2a96e3SMatthew G. Knepley if (val > 0) splitArray[p] = val; 24043f2a96e3SMatthew G. Knepley } 24053f2a96e3SMatthew G. Knepley } 24063f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 24073f2a96e3SMatthew G. Knepley } 24083f2a96e3SMatthew G. Knepley 24093f2a96e3SMatthew G. Knepley static PetscErrorCode SBRFinalizeComm(DMPlexCellRefiner cr, PetscSF pointSF, PointQueue queue) 24103f2a96e3SMatthew G. Knepley { 24113f2a96e3SMatthew G. Knepley PlexRefiner_SBR *sbr = (PlexRefiner_SBR *) cr->data; 24123f2a96e3SMatthew G. Knepley DMLabel splitPoints = sbr->splitPoints; 24133f2a96e3SMatthew G. Knepley PetscInt *splitArray = sbr->splitArray; 24143f2a96e3SMatthew G. Knepley const PetscInt *degree; 24153f2a96e3SMatthew G. Knepley const PetscInt *points; 24163f2a96e3SMatthew G. Knepley PetscInt Nl, l, pStart, pEnd, p, val; 24173f2a96e3SMatthew G. Knepley PetscErrorCode ierr; 24183f2a96e3SMatthew G. Knepley 24193f2a96e3SMatthew G. Knepley PetscFunctionBegin; 24203f2a96e3SMatthew G. Knepley /* Read out leaves */ 24213f2a96e3SMatthew G. Knepley ierr = PetscSFGetGraph(pointSF, NULL, &Nl, &points, NULL);CHKERRQ(ierr); 24223f2a96e3SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 24233f2a96e3SMatthew G. Knepley const PetscInt p = points[l]; 24243f2a96e3SMatthew G. Knepley const PetscInt cval = splitArray[p]; 24253f2a96e3SMatthew G. Knepley 24263f2a96e3SMatthew G. Knepley if (cval) { 24273f2a96e3SMatthew G. Knepley ierr = DMLabelGetValue(splitPoints, p, &val);CHKERRQ(ierr); 24283f2a96e3SMatthew G. Knepley if (val <= 0) { 24293f2a96e3SMatthew G. Knepley ierr = DMLabelSetValue(splitPoints, p, cval);CHKERRQ(ierr); 24303f2a96e3SMatthew G. Knepley ierr = PointQueueEnqueue(queue, p);CHKERRQ(ierr); 24313f2a96e3SMatthew G. Knepley } 24323f2a96e3SMatthew G. Knepley } 24333f2a96e3SMatthew G. Knepley } 24343f2a96e3SMatthew G. Knepley /* Read out shared roots */ 24353f2a96e3SMatthew G. Knepley ierr = PetscSFComputeDegreeBegin(pointSF, °ree);CHKERRQ(ierr); 24363f2a96e3SMatthew G. Knepley ierr = PetscSFComputeDegreeEnd(pointSF, °ree);CHKERRQ(ierr); 24373f2a96e3SMatthew G. Knepley ierr = DMPlexGetChart(cr->dm, &pStart, &pEnd);CHKERRQ(ierr); 24383f2a96e3SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 24393f2a96e3SMatthew G. Knepley if (degree[p]) { 24403f2a96e3SMatthew G. Knepley const PetscInt cval = splitArray[p]; 24413f2a96e3SMatthew G. Knepley 24423f2a96e3SMatthew G. Knepley if (cval) { 24433f2a96e3SMatthew G. Knepley ierr = DMLabelGetValue(splitPoints, p, &val);CHKERRQ(ierr); 24443f2a96e3SMatthew G. Knepley if (val <= 0) { 24453f2a96e3SMatthew G. Knepley ierr = DMLabelSetValue(splitPoints, p, cval);CHKERRQ(ierr); 24463f2a96e3SMatthew G. Knepley ierr = PointQueueEnqueue(queue, p);CHKERRQ(ierr); 24473f2a96e3SMatthew G. Knepley } 24483f2a96e3SMatthew G. Knepley } 24493f2a96e3SMatthew G. Knepley } 24503f2a96e3SMatthew G. Knepley } 24513f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 24523f2a96e3SMatthew G. Knepley } 24533f2a96e3SMatthew G. Knepley 24543f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetUp_SBR(DMPlexCellRefiner cr) 24553f2a96e3SMatthew G. Knepley { 24563f2a96e3SMatthew G. Knepley PlexRefiner_SBR *sbr; 24573f2a96e3SMatthew G. Knepley PetscSF pointSF; 24583f2a96e3SMatthew G. Knepley PointQueue queue = NULL; 24593f2a96e3SMatthew G. Knepley IS refineIS; 24603f2a96e3SMatthew G. Knepley const PetscInt *refineCells; 24613f2a96e3SMatthew G. Knepley PetscMPIInt size; 24623f2a96e3SMatthew G. Knepley PetscInt pStart, pEnd, p, eStart, eEnd, e, edgeLenSize, Nc, c; 24633f2a96e3SMatthew G. Knepley PetscBool empty; 24643f2a96e3SMatthew G. Knepley PetscErrorCode ierr; 24653f2a96e3SMatthew G. Knepley 24663f2a96e3SMatthew G. Knepley PetscFunctionBegin; 24673f2a96e3SMatthew G. Knepley ierr = PetscCitationsRegister(SBRCitation, &SBRcite);CHKERRQ(ierr); 24683f2a96e3SMatthew G. Knepley ierr = PetscNew(&sbr);CHKERRQ(ierr); 24693f2a96e3SMatthew G. Knepley cr->data = sbr; 24703f2a96e3SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, "Split Points", &sbr->splitPoints);CHKERRQ(ierr); 24713f2a96e3SMatthew G. Knepley /* Create edge lengths */ 24723f2a96e3SMatthew G. Knepley ierr = DMPlexGetDepthStratum(cr->dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 24733f2a96e3SMatthew G. Knepley ierr = PetscSectionCreate(PETSC_COMM_SELF, &sbr->secEdgeLen);CHKERRQ(ierr); 24743f2a96e3SMatthew G. Knepley ierr = PetscSectionSetChart(sbr->secEdgeLen, eStart, eEnd);CHKERRQ(ierr); 24753f2a96e3SMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 24763f2a96e3SMatthew G. Knepley ierr = PetscSectionSetDof(sbr->secEdgeLen, e, 1);CHKERRQ(ierr); 24773f2a96e3SMatthew G. Knepley } 24783f2a96e3SMatthew G. Knepley ierr = PetscSectionSetUp(sbr->secEdgeLen);CHKERRQ(ierr); 24793f2a96e3SMatthew G. Knepley ierr = PetscSectionGetStorageSize(sbr->secEdgeLen, &edgeLenSize);CHKERRQ(ierr); 24803f2a96e3SMatthew G. Knepley ierr = PetscCalloc1(edgeLenSize, &sbr->edgeLen);CHKERRQ(ierr); 24813f2a96e3SMatthew G. Knepley /* Add edges of cells that are marked for refinement to edge queue */ 24823f2a96e3SMatthew G. Knepley if (!cr->adaptLabel) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_ARG_WRONGSTATE, "CellRefiner must have an adaptation label in order to use SBR algorithm"); 24833f2a96e3SMatthew G. Knepley ierr = PointQueueCreate(1024, &queue);CHKERRQ(ierr); 24843f2a96e3SMatthew G. Knepley ierr = DMLabelGetStratumIS(cr->adaptLabel, DM_ADAPT_REFINE, &refineIS);CHKERRQ(ierr); 24853f2a96e3SMatthew G. Knepley ierr = DMLabelGetStratumSize(cr->adaptLabel, DM_ADAPT_REFINE, &Nc);CHKERRQ(ierr); 24863f2a96e3SMatthew G. Knepley if (refineIS) {ierr = ISGetIndices(refineIS, &refineCells);CHKERRQ(ierr);} 24873f2a96e3SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 24883f2a96e3SMatthew G. Knepley PetscInt *closure = NULL; 24893f2a96e3SMatthew G. Knepley PetscInt Ncl, cl; 24903f2a96e3SMatthew G. Knepley 24913f2a96e3SMatthew G. Knepley ierr = DMLabelSetValue(sbr->splitPoints, refineCells[c], 2);CHKERRQ(ierr); 24923f2a96e3SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(cr->dm, refineCells[c], PETSC_TRUE, &Ncl, &closure);CHKERRQ(ierr); 24933f2a96e3SMatthew G. Knepley for (cl = 0; cl < Ncl; cl += 2) { 24943f2a96e3SMatthew G. Knepley const PetscInt edge = closure[cl]; 24953f2a96e3SMatthew G. Knepley 24963f2a96e3SMatthew G. Knepley if (edge >= eStart && edge < eEnd) { 24973f2a96e3SMatthew G. Knepley ierr = DMLabelSetValue(sbr->splitPoints, edge, 1);CHKERRQ(ierr); 24983f2a96e3SMatthew G. Knepley ierr = PointQueueEnqueue(queue, edge);CHKERRQ(ierr); 24993f2a96e3SMatthew G. Knepley } 25003f2a96e3SMatthew G. Knepley } 25013f2a96e3SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(cr->dm, refineCells[c], PETSC_TRUE, &Ncl, &closure);CHKERRQ(ierr); 25023f2a96e3SMatthew G. Knepley } 25033f2a96e3SMatthew G. Knepley if (refineIS) {ierr = ISRestoreIndices(refineIS, &refineCells);CHKERRQ(ierr);} 25043f2a96e3SMatthew G. Knepley ierr = ISDestroy(&refineIS);CHKERRQ(ierr); 25053f2a96e3SMatthew G. Knepley /* Setup communication */ 25063f2a96e3SMatthew G. Knepley ierr = MPI_Comm_size(PetscObjectComm((PetscObject) cr->dm), &size);CHKERRQ(ierr); 25073f2a96e3SMatthew G. Knepley ierr = DMGetPointSF(cr->dm, &pointSF);CHKERRQ(ierr); 25083f2a96e3SMatthew G. Knepley if (size > 1) { 25093f2a96e3SMatthew G. Knepley PetscInt pStart, pEnd; 25103f2a96e3SMatthew G. Knepley 25113f2a96e3SMatthew G. Knepley ierr = DMPlexGetChart(cr->dm, &pStart, &pEnd);CHKERRQ(ierr); 25123f2a96e3SMatthew G. Knepley ierr = PetscCalloc1(pEnd-pStart, &sbr->splitArray);CHKERRQ(ierr); 25133f2a96e3SMatthew G. Knepley } 25143f2a96e3SMatthew G. Knepley /* While edge queue is not empty: */ 25153f2a96e3SMatthew G. Knepley empty = PointQueueEmpty(queue); 25163f2a96e3SMatthew G. Knepley ierr = MPI_Allreduce(MPI_IN_PLACE, &empty, 1, MPIU_BOOL, MPI_LAND, PetscObjectComm((PetscObject) cr->dm));CHKERRQ(ierr); 25173f2a96e3SMatthew G. Knepley while (!empty) { 25183f2a96e3SMatthew G. Knepley ierr = SBRSplitLocalEdges_Private(cr, queue);CHKERRQ(ierr); 25193f2a96e3SMatthew G. Knepley /* Communicate marked edges 25203f2a96e3SMatthew G. Knepley An easy implementation is to allocate an array the size of the number of points. We put the splitPoints marks into the 25213f2a96e3SMatthew G. Knepley array, and then call PetscSFReduce()+PetscSFBcast() to make the marks consistent. 25223f2a96e3SMatthew G. Knepley 25233f2a96e3SMatthew G. Knepley TODO: We could use in-place communication with a different SF 25243f2a96e3SMatthew G. Knepley We use MPI_SUM for the Reduce, and check the result against the rootdegree. If sum >= rootdegree+1, then the edge has 25253f2a96e3SMatthew G. Knepley already been marked. If not, it might have been handled on the process in this round, but we add it anyway. 25263f2a96e3SMatthew G. Knepley 25273f2a96e3SMatthew G. Knepley In order to update the queue with the new edges from the label communication, we use BcastAnOp(MPI_SUM), so that new 25283f2a96e3SMatthew G. Knepley values will have 1+0=1 and old values will have 1+1=2. Loop over these, resetting the values to 1, and adding any new 25293f2a96e3SMatthew G. Knepley edge to the queue. 25303f2a96e3SMatthew G. Knepley */ 25313f2a96e3SMatthew G. Knepley if (size > 1) { 25323f2a96e3SMatthew G. Knepley ierr = SBRInitializeComm(cr, pointSF);CHKERRQ(ierr); 25333f2a96e3SMatthew G. Knepley ierr = PetscSFReduceBegin(pointSF, MPIU_INT, sbr->splitArray, sbr->splitArray, MPI_MAX);CHKERRQ(ierr); 25343f2a96e3SMatthew G. Knepley ierr = PetscSFReduceEnd(pointSF, MPIU_INT, sbr->splitArray, sbr->splitArray, MPI_MAX);CHKERRQ(ierr); 25353f2a96e3SMatthew G. Knepley ierr = PetscSFBcastBegin(pointSF, MPIU_INT, sbr->splitArray, sbr->splitArray);CHKERRQ(ierr); 25363f2a96e3SMatthew G. Knepley ierr = PetscSFBcastEnd(pointSF, MPIU_INT, sbr->splitArray, sbr->splitArray);CHKERRQ(ierr); 25373f2a96e3SMatthew G. Knepley ierr = SBRFinalizeComm(cr, pointSF, queue);CHKERRQ(ierr); 25383f2a96e3SMatthew G. Knepley } 25393f2a96e3SMatthew G. Knepley empty = PointQueueEmpty(queue); 25403f2a96e3SMatthew G. Knepley ierr = MPI_Allreduce(MPI_IN_PLACE, &empty, 1, MPIU_BOOL, MPI_LAND, PetscObjectComm((PetscObject) cr->dm));CHKERRQ(ierr); 25413f2a96e3SMatthew G. Knepley } 25423f2a96e3SMatthew G. Knepley ierr = PetscFree(sbr->splitArray);CHKERRQ(ierr); 25433f2a96e3SMatthew G. Knepley /* Calculate refineType for each cell */ 25443f2a96e3SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, "Refine Type", &cr->refineType);CHKERRQ(ierr); 25453f2a96e3SMatthew G. Knepley ierr = DMPlexGetChart(cr->dm, &pStart, &pEnd);CHKERRQ(ierr); 25463f2a96e3SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 25473f2a96e3SMatthew G. Knepley DMPolytopeType ct; 25483f2a96e3SMatthew G. Knepley PetscInt val; 25493f2a96e3SMatthew G. Knepley 25503f2a96e3SMatthew G. Knepley ierr = DMPlexGetCellType(cr->dm, p, &ct);CHKERRQ(ierr); 25513f2a96e3SMatthew G. Knepley switch (ct) { 25523f2a96e3SMatthew G. Knepley case DM_POLYTOPE_POINT: 25533f2a96e3SMatthew G. Knepley ierr = DMLabelSetValue(cr->refineType, p, 0);CHKERRQ(ierr);break; 25543f2a96e3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 25553f2a96e3SMatthew G. Knepley ierr = DMLabelGetValue(sbr->splitPoints, p, &val);CHKERRQ(ierr); 25563f2a96e3SMatthew G. Knepley if (val == 1) {ierr = DMLabelSetValue(cr->refineType, p, 2);CHKERRQ(ierr);} 25573f2a96e3SMatthew G. Knepley else {ierr = DMLabelSetValue(cr->refineType, p, 1);CHKERRQ(ierr);} 25583f2a96e3SMatthew G. Knepley break; 25593f2a96e3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 25603f2a96e3SMatthew G. Knepley ierr = DMLabelGetValue(sbr->splitPoints, p, &val);CHKERRQ(ierr); 25613f2a96e3SMatthew G. Knepley if (val == 2) { 25623f2a96e3SMatthew G. Knepley const PetscInt *cone; 25633f2a96e3SMatthew G. Knepley PetscReal lens[3]; 25643f2a96e3SMatthew G. Knepley PetscInt vals[3], i; 25653f2a96e3SMatthew G. Knepley 25663f2a96e3SMatthew G. Knepley ierr = DMPlexGetCone(cr->dm, p, &cone);CHKERRQ(ierr); 25673f2a96e3SMatthew G. Knepley for (i = 0; i < 3; ++i) { 25683f2a96e3SMatthew G. Knepley ierr = DMLabelGetValue(sbr->splitPoints, cone[i], &vals[i]);CHKERRQ(ierr); 25693f2a96e3SMatthew G. Knepley vals[i] = vals[i] < 0 ? 0 : vals[i]; 25703f2a96e3SMatthew G. Knepley ierr = SBRGetEdgeLen_Private(cr, cone[i], &lens[i]);CHKERRQ(ierr); 25713f2a96e3SMatthew G. Knepley } 25723f2a96e3SMatthew G. Knepley if (vals[0] && vals[1] && vals[2]) {ierr = DMLabelSetValue(cr->refineType, p, 4);CHKERRQ(ierr);} 25733f2a96e3SMatthew G. Knepley else if (vals[0] && vals[1]) {ierr = DMLabelSetValue(cr->refineType, p, lens[0] > lens[1] ? 5 : 6);CHKERRQ(ierr);} 25743f2a96e3SMatthew G. Knepley else if (vals[1] && vals[2]) {ierr = DMLabelSetValue(cr->refineType, p, lens[1] > lens[2] ? 7 : 8);CHKERRQ(ierr);} 25753f2a96e3SMatthew G. Knepley else if (vals[2] && vals[0]) {ierr = DMLabelSetValue(cr->refineType, p, lens[2] > lens[0] ? 9: 10);CHKERRQ(ierr);} 25763f2a96e3SMatthew G. Knepley else if (vals[0]) {ierr = DMLabelSetValue(cr->refineType, p, 11);CHKERRQ(ierr);} 25773f2a96e3SMatthew G. Knepley else if (vals[1]) {ierr = DMLabelSetValue(cr->refineType, p, 12);CHKERRQ(ierr);} 25783f2a96e3SMatthew G. Knepley else if (vals[2]) {ierr = DMLabelSetValue(cr->refineType, p, 13);CHKERRQ(ierr);} 25793f2a96e3SMatthew G. Knepley else SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Cell %D does not fit any refinement type (%D, %D, %D)", p, vals[0], vals[1], vals[2]); 25803f2a96e3SMatthew G. Knepley } else {ierr = DMLabelSetValue(cr->refineType, p, 3);CHKERRQ(ierr);} 25813f2a96e3SMatthew G. Knepley break; 25823f2a96e3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle points of type %s", DMPolytopeTypes[ct]); 25833f2a96e3SMatthew G. Knepley } 25843f2a96e3SMatthew G. Knepley ierr = DMLabelGetValue(sbr->splitPoints, p, &val);CHKERRQ(ierr); 25853f2a96e3SMatthew G. Knepley } 25863f2a96e3SMatthew G. Knepley /* Cleanup */ 25873f2a96e3SMatthew G. Knepley ierr = PointQueueDestroy(&queue);CHKERRQ(ierr); 25883f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 25893f2a96e3SMatthew G. Knepley } 25903f2a96e3SMatthew G. Knepley 25913f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerDestroy_SBR(DMPlexCellRefiner cr) 25923f2a96e3SMatthew G. Knepley { 25933f2a96e3SMatthew G. Knepley PlexRefiner_SBR *sbr = (PlexRefiner_SBR *) cr->data; 25943f2a96e3SMatthew G. Knepley PetscErrorCode ierr; 25953f2a96e3SMatthew G. Knepley 25963f2a96e3SMatthew G. Knepley PetscFunctionBegin; 25973f2a96e3SMatthew G. Knepley ierr = PetscFree(sbr->edgeLen);CHKERRQ(ierr); 25983f2a96e3SMatthew G. Knepley ierr = PetscSectionDestroy(&sbr->secEdgeLen);CHKERRQ(ierr); 25993f2a96e3SMatthew G. Knepley ierr = DMLabelDestroy(&sbr->splitPoints);CHKERRQ(ierr); 26003f2a96e3SMatthew G. Knepley ierr = PetscFree(cr->data);CHKERRQ(ierr); 26013f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 26023f2a96e3SMatthew G. Knepley } 26033f2a96e3SMatthew G. Knepley 26043f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_SBR(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt p, PetscInt *rt, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 26053f2a96e3SMatthew G. Knepley { 26063f2a96e3SMatthew G. Knepley /* Add 1 edge inside this triangle, making 2 new triangles. 26073f2a96e3SMatthew G. Knepley 2 26083f2a96e3SMatthew G. Knepley |\ 26093f2a96e3SMatthew G. Knepley | \ 26103f2a96e3SMatthew G. Knepley | \ 26113f2a96e3SMatthew G. Knepley | \ 26123f2a96e3SMatthew G. Knepley | 1 26133f2a96e3SMatthew G. Knepley | \ 26143f2a96e3SMatthew G. Knepley | B \ 26153f2a96e3SMatthew G. Knepley 2 1 26163f2a96e3SMatthew G. Knepley | / \ 26173f2a96e3SMatthew G. Knepley | ____/ 0 26183f2a96e3SMatthew G. Knepley |/ A \ 26193f2a96e3SMatthew G. Knepley 0-----0-----1 26203f2a96e3SMatthew G. Knepley */ 26213f2a96e3SMatthew G. Knepley static DMPolytopeType triT10[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE}; 26223f2a96e3SMatthew G. Knepley static PetscInt triS10[] = {1, 2}; 26233f2a96e3SMatthew G. Knepley static PetscInt triC10[] = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 26243f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 0, 26253f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 0}; 26263f2a96e3SMatthew G. Knepley static PetscInt triO10[] = {0, 0, 26273f2a96e3SMatthew G. Knepley 0, 0, -2, 26283f2a96e3SMatthew G. Knepley 0, 0, 0}; 26293f2a96e3SMatthew G. Knepley /* Add 1 edge inside this triangle, making 2 new triangles. 26303f2a96e3SMatthew G. Knepley 2 26313f2a96e3SMatthew G. Knepley |\ 26323f2a96e3SMatthew G. Knepley | \ 26333f2a96e3SMatthew G. Knepley | \ 26343f2a96e3SMatthew G. Knepley 0 \ 26353f2a96e3SMatthew G. Knepley | \ 26363f2a96e3SMatthew G. Knepley | \ 26373f2a96e3SMatthew G. Knepley | \ 26383f2a96e3SMatthew G. Knepley 2 A 1 26393f2a96e3SMatthew G. Knepley |\ \ 26403f2a96e3SMatthew G. Knepley 1 ---\ \ 26413f2a96e3SMatthew G. Knepley | B ----\\ 26423f2a96e3SMatthew G. Knepley 0-----0-----1 26433f2a96e3SMatthew G. Knepley */ 26443f2a96e3SMatthew G. Knepley static PetscInt triC11[] = {DM_POLYTOPE_POINT, 2, 1, 0, 0, DM_POLYTOPE_POINT, 1, 2, 0, 26453f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 0, 26463f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0}; 26473f2a96e3SMatthew G. Knepley static PetscInt triO11[] = {0, 0, 26483f2a96e3SMatthew G. Knepley 0, 0, -2, 26493f2a96e3SMatthew G. Knepley 0, 0, 0}; 26503f2a96e3SMatthew G. Knepley /* Add 1 edge inside this triangle, making 2 new triangles. 26513f2a96e3SMatthew G. Knepley 2 26523f2a96e3SMatthew G. Knepley |\ 26533f2a96e3SMatthew G. Knepley |\\ 26543f2a96e3SMatthew G. Knepley || \ 26553f2a96e3SMatthew G. Knepley | \ \ 26563f2a96e3SMatthew G. Knepley | | \ 26573f2a96e3SMatthew G. Knepley | | \ 26583f2a96e3SMatthew G. Knepley | | \ 26593f2a96e3SMatthew G. Knepley 2 \ 1 26603f2a96e3SMatthew G. Knepley | A | \ 26613f2a96e3SMatthew G. Knepley | | B \ 26623f2a96e3SMatthew G. Knepley | \ \ 26633f2a96e3SMatthew G. Knepley 0-----0-----1 26643f2a96e3SMatthew G. Knepley */ 26653f2a96e3SMatthew G. Knepley static PetscInt triC12[] = {DM_POLYTOPE_POINT, 2, 2, 0, 0, DM_POLYTOPE_POINT, 1, 0, 0, 26663f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, 26673f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 0}; 26683f2a96e3SMatthew G. Knepley static PetscInt triO12[] = {0, 0, 26693f2a96e3SMatthew G. Knepley 0, 0, -2, 26703f2a96e3SMatthew G. Knepley 0, 0, 0}; 26713f2a96e3SMatthew G. Knepley /* Add 2 edges inside this triangle, making 3 new triangles. 26723f2a96e3SMatthew G. Knepley 2 26733f2a96e3SMatthew G. Knepley |\ 26743f2a96e3SMatthew G. Knepley | \ 26753f2a96e3SMatthew G. Knepley | \ 26763f2a96e3SMatthew G. Knepley 0 \ 26773f2a96e3SMatthew G. Knepley | 1 26783f2a96e3SMatthew G. Knepley | \ 26793f2a96e3SMatthew G. Knepley | B \ 26803f2a96e3SMatthew G. Knepley 2-------1 26813f2a96e3SMatthew G. Knepley | C / \ 26823f2a96e3SMatthew G. Knepley 1 ____/ 0 26833f2a96e3SMatthew G. Knepley |/ A \ 26843f2a96e3SMatthew G. Knepley 0-----0-----1 26853f2a96e3SMatthew G. Knepley */ 26863f2a96e3SMatthew G. Knepley static DMPolytopeType triT20[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE}; 26873f2a96e3SMatthew G. Knepley static PetscInt triS20[] = {2, 3}; 26883f2a96e3SMatthew G. Knepley static PetscInt triC20[] = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 26893f2a96e3SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 1, 2, 0, 26903f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 0, 26913f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 1, 26923f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1}; 26933f2a96e3SMatthew G. Knepley static PetscInt triO20[] = {0, 0, 26943f2a96e3SMatthew G. Knepley 0, 0, 26953f2a96e3SMatthew G. Knepley 0, 0, -2, 26963f2a96e3SMatthew G. Knepley 0, 0, -2, 26973f2a96e3SMatthew G. Knepley 0, 0, 0}; 26983f2a96e3SMatthew G. Knepley /* Add 1 edge inside this triangle, making 2 new triangles. 26993f2a96e3SMatthew G. Knepley 2 27003f2a96e3SMatthew G. Knepley |\ 27013f2a96e3SMatthew G. Knepley | \ 27023f2a96e3SMatthew G. Knepley | \ 27033f2a96e3SMatthew G. Knepley 0 \ 27043f2a96e3SMatthew G. Knepley | 1 27053f2a96e3SMatthew G. Knepley | \ 27063f2a96e3SMatthew G. Knepley | B \ 27073f2a96e3SMatthew G. Knepley 2 1 27083f2a96e3SMatthew G. Knepley | /|\ 27093f2a96e3SMatthew G. Knepley 1 ____/ / 0 27103f2a96e3SMatthew G. Knepley |/ A / C \ 27113f2a96e3SMatthew G. Knepley 0-----0-----1 27123f2a96e3SMatthew G. Knepley */ 27133f2a96e3SMatthew G. Knepley static PetscInt triC21[] = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 27143f2a96e3SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 1, 0, 0, 27153f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 27163f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 0, 27173f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1}; 27183f2a96e3SMatthew G. Knepley static PetscInt triO21[] = {0, 0, 27193f2a96e3SMatthew G. Knepley 0, 0, 27203f2a96e3SMatthew G. Knepley 0, -2, -2, 27213f2a96e3SMatthew G. Knepley 0, 0, 0, 27223f2a96e3SMatthew G. Knepley 0, 0, 0}; 27233f2a96e3SMatthew G. Knepley /* Add 2 edges inside this triangle, making 3 new triangles. 27243f2a96e3SMatthew G. Knepley 2 27253f2a96e3SMatthew G. Knepley |\ 27263f2a96e3SMatthew G. Knepley | \ 27273f2a96e3SMatthew G. Knepley | \ 27283f2a96e3SMatthew G. Knepley 0 \ 27293f2a96e3SMatthew G. Knepley | \ 27303f2a96e3SMatthew G. Knepley | \ 27313f2a96e3SMatthew G. Knepley | \ 27323f2a96e3SMatthew G. Knepley 2 A 1 27333f2a96e3SMatthew G. Knepley |\ \ 27343f2a96e3SMatthew G. Knepley 1 ---\ \ 27353f2a96e3SMatthew G. Knepley |B \_C----\\ 27363f2a96e3SMatthew G. Knepley 0-----0-----1 27373f2a96e3SMatthew G. Knepley */ 27383f2a96e3SMatthew G. Knepley static PetscInt triC22[] = {DM_POLYTOPE_POINT, 2, 1, 0, 0, DM_POLYTOPE_POINT, 1, 2, 0, 27393f2a96e3SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 0, 0, 27403f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 0, 27413f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, 27423f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1}; 27433f2a96e3SMatthew G. Knepley static PetscInt triO22[] = {0, 0, 27443f2a96e3SMatthew G. Knepley 0, 0, 27453f2a96e3SMatthew G. Knepley 0, 0, -2, 27463f2a96e3SMatthew G. Knepley 0, 0, -2, 27473f2a96e3SMatthew G. Knepley 0, 0, 0}; 27483f2a96e3SMatthew G. Knepley /* Add 1 edge inside this triangle, making 2 new triangles. 27493f2a96e3SMatthew G. Knepley 2 27503f2a96e3SMatthew G. Knepley |\ 27513f2a96e3SMatthew G. Knepley | \ 27523f2a96e3SMatthew G. Knepley | \ 27533f2a96e3SMatthew G. Knepley 0 \ 27543f2a96e3SMatthew G. Knepley | \ 27553f2a96e3SMatthew G. Knepley | C \ 27563f2a96e3SMatthew G. Knepley | \ 27573f2a96e3SMatthew G. Knepley 2-------1 27583f2a96e3SMatthew G. Knepley |\ A \ 27593f2a96e3SMatthew G. Knepley 1 ---\ \ 27603f2a96e3SMatthew G. Knepley | B ----\\ 27613f2a96e3SMatthew G. Knepley 0-----0-----1 27623f2a96e3SMatthew G. Knepley */ 27633f2a96e3SMatthew G. Knepley static PetscInt triC23[] = {DM_POLYTOPE_POINT, 2, 1, 0, 0, DM_POLYTOPE_POINT, 1, 2, 0, 27643f2a96e3SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 1, 0, 27653f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 27663f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, 27673f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 1}; 27683f2a96e3SMatthew G. Knepley static PetscInt triO23[] = {0, 0, 27693f2a96e3SMatthew G. Knepley 0, 0, 27703f2a96e3SMatthew G. Knepley 0, -2, -2, 27713f2a96e3SMatthew G. Knepley 0, 0, 0, 27723f2a96e3SMatthew G. Knepley 0, 0, 0}; 27733f2a96e3SMatthew G. Knepley /* Add 2 edges inside this triangle, making 3 new triangles. 27743f2a96e3SMatthew G. Knepley 2 27753f2a96e3SMatthew G. Knepley |\ 27763f2a96e3SMatthew G. Knepley |\\ 27773f2a96e3SMatthew G. Knepley || \ 27783f2a96e3SMatthew G. Knepley | \ \ 27793f2a96e3SMatthew G. Knepley | | \ 27803f2a96e3SMatthew G. Knepley | | \ 27813f2a96e3SMatthew G. Knepley | | \ 27823f2a96e3SMatthew G. Knepley 2 \ C 1 27833f2a96e3SMatthew G. Knepley | A | / \ 27843f2a96e3SMatthew G. Knepley | | |B \ 27853f2a96e3SMatthew G. Knepley | \/ \ 27863f2a96e3SMatthew G. Knepley 0-----0-----1 27873f2a96e3SMatthew G. Knepley */ 27883f2a96e3SMatthew G. Knepley static PetscInt triC24[] = {DM_POLYTOPE_POINT, 2, 2, 0, 0, DM_POLYTOPE_POINT, 1, 0, 0, 27893f2a96e3SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 27903f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, 27913f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, 27923f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1}; 27933f2a96e3SMatthew G. Knepley static PetscInt triO24[] = {0, 0, 27943f2a96e3SMatthew G. Knepley 0, 0, 27953f2a96e3SMatthew G. Knepley 0, 0, -2, 27963f2a96e3SMatthew G. Knepley 0, 0, -2, 27973f2a96e3SMatthew G. Knepley 0, 0, 0}; 27983f2a96e3SMatthew G. Knepley /* Add 1 edge inside this triangle, making 2 new triangles. 27993f2a96e3SMatthew G. Knepley 2 28003f2a96e3SMatthew G. Knepley |\ 28013f2a96e3SMatthew G. Knepley |\\ 28023f2a96e3SMatthew G. Knepley || \ 28033f2a96e3SMatthew G. Knepley | \ \ 28043f2a96e3SMatthew G. Knepley | | \ 28053f2a96e3SMatthew G. Knepley | | \ 28063f2a96e3SMatthew G. Knepley | | \ 28073f2a96e3SMatthew G. Knepley 2 A \ 1 28083f2a96e3SMatthew G. Knepley |\ | \ 28093f2a96e3SMatthew G. Knepley | \__| B \ 28103f2a96e3SMatthew G. Knepley | C \\ \ 28113f2a96e3SMatthew G. Knepley 0-----0-----1 28123f2a96e3SMatthew G. Knepley */ 28133f2a96e3SMatthew G. Knepley static PetscInt triC25[] = {DM_POLYTOPE_POINT, 2, 2, 0, 0, DM_POLYTOPE_POINT, 1, 0, 0, 28143f2a96e3SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 2, 0, 28153f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 28163f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 0, 28173f2a96e3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1}; 28183f2a96e3SMatthew G. Knepley static PetscInt triO25[] = {0, 0, 28193f2a96e3SMatthew G. Knepley 0, 0, 28203f2a96e3SMatthew G. Knepley 0, -2, -2, 28213f2a96e3SMatthew G. Knepley 0, 0, 0, 28223f2a96e3SMatthew G. Knepley 0, 0, 0}; 28233f2a96e3SMatthew G. Knepley DMLabel rtype = cr->refineType; 28243f2a96e3SMatthew G. Knepley PetscInt val; 28253f2a96e3SMatthew G. Knepley PetscErrorCode ierr; 28263f2a96e3SMatthew G. Knepley 28273f2a96e3SMatthew G. Knepley 28283f2a96e3SMatthew G. Knepley PetscFunctionBeginHot; 28293f2a96e3SMatthew G. Knepley if (p < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point argument is invalid"); 28303f2a96e3SMatthew G. Knepley ierr = DMLabelGetValue(rtype, p, &val);CHKERRQ(ierr); 28313f2a96e3SMatthew G. Knepley if (rt) *rt = val; 28323f2a96e3SMatthew G. Knepley switch (source) { 28333f2a96e3SMatthew G. Knepley case DM_POLYTOPE_POINT: 28343f2a96e3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 28353f2a96e3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 28363f2a96e3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 28373f2a96e3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 28383f2a96e3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 28393f2a96e3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 28403f2a96e3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 28413f2a96e3SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 28423f2a96e3SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 28433f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, p, NULL, Nt, target, size, cone, ornt);CHKERRQ(ierr); 28443f2a96e3SMatthew G. Knepley break; 28453f2a96e3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 28463f2a96e3SMatthew G. Knepley if (val == 1) {ierr = DMPlexCellRefinerRefine_None(cr, source, p, NULL, Nt, target, size, cone, ornt);CHKERRQ(ierr);} 28473f2a96e3SMatthew G. Knepley else {ierr = DMPlexCellRefinerRefine_Regular(cr, source, p, NULL, Nt, target, size, cone, ornt);CHKERRQ(ierr);} 28483f2a96e3SMatthew G. Knepley break; 28493f2a96e3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 28503f2a96e3SMatthew G. Knepley switch (val) { 28513f2a96e3SMatthew G. Knepley case 12: *Nt = 2; *target = triT10; *size = triS10; *cone = triC10; *ornt = triO10; break; 28523f2a96e3SMatthew G. Knepley case 13: *Nt = 2; *target = triT10; *size = triS10; *cone = triC11; *ornt = triO11; break; 28533f2a96e3SMatthew G. Knepley case 11: *Nt = 2; *target = triT10; *size = triS10; *cone = triC12; *ornt = triO12; break; 28543f2a96e3SMatthew G. Knepley case 5: *Nt = 2; *target = triT20; *size = triS20; *cone = triC24; *ornt = triO24; break; 28553f2a96e3SMatthew G. Knepley case 6: *Nt = 2; *target = triT20; *size = triS20; *cone = triC21; *ornt = triO21; break; 28563f2a96e3SMatthew G. Knepley case 7: *Nt = 2; *target = triT20; *size = triS20; *cone = triC20; *ornt = triO20; break; 28573f2a96e3SMatthew G. Knepley case 8: *Nt = 2; *target = triT20; *size = triS20; *cone = triC23; *ornt = triO23; break; 28583f2a96e3SMatthew G. Knepley case 9: *Nt = 2; *target = triT20; *size = triS20; *cone = triC22; *ornt = triO22; break; 28593f2a96e3SMatthew G. Knepley case 10: *Nt = 2; *target = triT20; *size = triS20; *cone = triC25; *ornt = triO25; break; 28603f2a96e3SMatthew G. Knepley case 4: ierr = DMPlexCellRefinerRefine_Regular(cr, source, p, NULL, Nt, target, size, cone, ornt);CHKERRQ(ierr); break; 28613f2a96e3SMatthew G. Knepley default: ierr = DMPlexCellRefinerRefine_None(cr, source, p, NULL, Nt, target, size, cone, ornt);CHKERRQ(ierr); 28623f2a96e3SMatthew G. Knepley } 28633f2a96e3SMatthew G. Knepley break; 28643f2a96e3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 28653f2a96e3SMatthew G. Knepley } 28663f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 28673f2a96e3SMatthew G. Knepley } 28683f2a96e3SMatthew G. Knepley 28693f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_SBR(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt pp, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 28703f2a96e3SMatthew G. Knepley { 28713f2a96e3SMatthew G. Knepley /* We shift any input orientation in order to make it non-negative 28723f2a96e3SMatthew 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) 28733f2a96e3SMatthew G. Knepley The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 28743f2a96e3SMatthew G. Knepley Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 28753f2a96e3SMatthew G. Knepley */ 28763f2a96e3SMatthew G. Knepley PetscInt rt; 28773f2a96e3SMatthew G. Knepley PetscErrorCode ierr; 28783f2a96e3SMatthew G. Knepley 28793f2a96e3SMatthew G. Knepley PetscFunctionBeginHot; 28803f2a96e3SMatthew G. Knepley ierr = DMLabelGetValue(cr->refineType, pp, &rt);CHKERRQ(ierr); 28813f2a96e3SMatthew G. Knepley *rnew = r; 28823f2a96e3SMatthew G. Knepley *onew = o; 28833f2a96e3SMatthew G. Knepley switch (rt) { 28843f2a96e3SMatthew G. Knepley case 5: 28853f2a96e3SMatthew G. Knepley case 6: 28863f2a96e3SMatthew G. Knepley case 7: 28873f2a96e3SMatthew G. Knepley case 8: 28883f2a96e3SMatthew G. Knepley case 9: 28893f2a96e3SMatthew G. Knepley case 10: 28903f2a96e3SMatthew G. Knepley switch (ct) { 28913f2a96e3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 28923f2a96e3SMatthew G. Knepley break; 28933f2a96e3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 28943f2a96e3SMatthew G. Knepley break; 28953f2a96e3SMatthew G. Knepley default: break; 28963f2a96e3SMatthew G. Knepley } 28973f2a96e3SMatthew G. Knepley break; 28983f2a96e3SMatthew G. Knepley case 11: 28993f2a96e3SMatthew G. Knepley case 12: 29003f2a96e3SMatthew G. Knepley case 13: 29013f2a96e3SMatthew G. Knepley switch (ct) { 29023f2a96e3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 29033f2a96e3SMatthew G. Knepley break; 29043f2a96e3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 29053f2a96e3SMatthew G. Knepley *onew = po < 0 ? -(o+1) : o; 29063f2a96e3SMatthew G. Knepley *rnew = po < 0 ? (r+1)%2 : r; 29073f2a96e3SMatthew G. Knepley break; 29083f2a96e3SMatthew G. Knepley default: break; 29093f2a96e3SMatthew G. Knepley } 29103f2a96e3SMatthew G. Knepley break; 29113f2a96e3SMatthew G. Knepley case 2: 29123f2a96e3SMatthew G. Knepley case 4: 29133f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerMapSubcells_Regular(cr, pct, pp, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 29143f2a96e3SMatthew G. Knepley break; 29153f2a96e3SMatthew G. Knepley default: ierr = DMPlexCellRefinerMapSubcells_None(cr, pct, pp, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 29163f2a96e3SMatthew G. Knepley } 29173f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 29183f2a96e3SMatthew G. Knepley } 29193f2a96e3SMatthew G. Knepley 2920412e9a14SMatthew G. Knepley static PetscErrorCode CellRefinerCreateOffset_Internal(DMPlexCellRefiner cr, PetscInt ctOrder[], PetscInt ctStart[], PetscInt **offset) 2921412e9a14SMatthew G. Knepley { 2922412e9a14SMatthew G. Knepley PetscInt c, cN, *off; 292375d3a19aSMatthew G. Knepley PetscErrorCode ierr; 292475d3a19aSMatthew G. Knepley 292575d3a19aSMatthew G. Knepley PetscFunctionBegin; 29263f2a96e3SMatthew G. Knepley if (cr->refineType) { 29273f2a96e3SMatthew G. Knepley IS rtIS; 29283f2a96e3SMatthew G. Knepley const PetscInt *reftypes; 29293f2a96e3SMatthew G. Knepley PetscInt Nrt, r; 29303f2a96e3SMatthew G. Knepley 29313f2a96e3SMatthew G. Knepley ierr = DMLabelGetNumValues(cr->refineType, &Nrt);CHKERRQ(ierr); 29323f2a96e3SMatthew G. Knepley ierr = DMLabelGetValueIS(cr->refineType, &rtIS);CHKERRQ(ierr); 29333f2a96e3SMatthew G. Knepley ierr = ISGetIndices(rtIS, &reftypes);CHKERRQ(ierr); 29343f2a96e3SMatthew G. Knepley ierr = PetscCalloc1(Nrt*DM_NUM_POLYTOPES, &off);CHKERRQ(ierr); 29353f2a96e3SMatthew G. Knepley for (r = 0; r < Nrt; ++r) { 29363f2a96e3SMatthew G. Knepley const PetscInt rt = reftypes[r]; 29373f2a96e3SMatthew G. Knepley IS rtIS; 29383f2a96e3SMatthew G. Knepley const PetscInt *points; 29393f2a96e3SMatthew G. Knepley DMPolytopeType ct; 29403f2a96e3SMatthew G. Knepley PetscInt p; 29413f2a96e3SMatthew G. Knepley 29423f2a96e3SMatthew G. Knepley ierr = DMLabelGetStratumIS(cr->refineType, rt, &rtIS);CHKERRQ(ierr); 29433f2a96e3SMatthew G. Knepley ierr = ISGetIndices(rtIS, &points);CHKERRQ(ierr); 29443f2a96e3SMatthew G. Knepley p = points[0]; 29453f2a96e3SMatthew G. Knepley ierr = ISRestoreIndices(rtIS, &points);CHKERRQ(ierr); 29463f2a96e3SMatthew G. Knepley ierr = ISDestroy(&rtIS);CHKERRQ(ierr); 29473f2a96e3SMatthew G. Knepley ierr = DMPlexGetCellType(cr->dm, p, &ct);CHKERRQ(ierr); 29483f2a96e3SMatthew G. Knepley for (cN = DM_POLYTOPE_POINT; cN < DM_NUM_POLYTOPES; ++cN) { 29493f2a96e3SMatthew G. Knepley const DMPolytopeType ctNew = (DMPolytopeType) cN; 29503f2a96e3SMatthew G. Knepley DMPolytopeType *rct; 29513f2a96e3SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 29523f2a96e3SMatthew G. Knepley PetscInt Nct, n, s; 29533f2a96e3SMatthew G. Knepley 29543f2a96e3SMatthew G. Knepley if (DMPolytopeTypeGetDim(ct) < 0 || DMPolytopeTypeGetDim(ctNew) < 0) {off[r*DM_NUM_POLYTOPES+ctNew] = -1; break;} 29553f2a96e3SMatthew G. Knepley off[r*DM_NUM_POLYTOPES+ctNew] = 0; 29563f2a96e3SMatthew G. Knepley for (s = 0; s <= r; ++s) { 29573f2a96e3SMatthew G. Knepley const PetscInt st = reftypes[s]; 29583f2a96e3SMatthew G. Knepley DMPolytopeType sct; 29593f2a96e3SMatthew G. Knepley PetscInt q, qrt; 29603f2a96e3SMatthew G. Knepley 29613f2a96e3SMatthew G. Knepley ierr = DMLabelGetStratumIS(cr->refineType, st, &rtIS);CHKERRQ(ierr); 29623f2a96e3SMatthew G. Knepley ierr = ISGetIndices(rtIS, &points);CHKERRQ(ierr); 29633f2a96e3SMatthew G. Knepley q = points[0]; 29643f2a96e3SMatthew G. Knepley ierr = ISRestoreIndices(rtIS, &points);CHKERRQ(ierr); 29653f2a96e3SMatthew G. Knepley ierr = ISDestroy(&rtIS);CHKERRQ(ierr); 29663f2a96e3SMatthew G. Knepley ierr = DMPlexGetCellType(cr->dm, q, &sct);CHKERRQ(ierr); 29673f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, sct, q, &qrt, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 29683f2a96e3SMatthew G. Knepley if (st != qrt) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Refine type %D of point %D does not match predicted type %D", qrt, q, st); 29693f2a96e3SMatthew G. Knepley if (st == rt) { 29703f2a96e3SMatthew G. Knepley for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) break; 29713f2a96e3SMatthew G. Knepley if (n == Nct) off[r*DM_NUM_POLYTOPES+ctNew] = -1; 29723f2a96e3SMatthew G. Knepley break; 29733f2a96e3SMatthew G. Knepley } 29743f2a96e3SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 29753f2a96e3SMatthew G. Knepley if (rct[n] == ctNew) { 29763f2a96e3SMatthew G. Knepley PetscInt sn; 29773f2a96e3SMatthew G. Knepley 29783f2a96e3SMatthew G. Knepley ierr = DMLabelGetStratumSize(cr->refineType, st, &sn);CHKERRQ(ierr); 29793f2a96e3SMatthew G. Knepley off[r*DM_NUM_POLYTOPES+ctNew] += sn * rsize[n]; 29803f2a96e3SMatthew G. Knepley } 29813f2a96e3SMatthew G. Knepley } 29823f2a96e3SMatthew G. Knepley } 29833f2a96e3SMatthew G. Knepley } 29843f2a96e3SMatthew G. Knepley } 29853f2a96e3SMatthew G. Knepley #if 0 29863f2a96e3SMatthew G. Knepley { 29873f2a96e3SMatthew G. Knepley PetscInt cols = 8; 29883f2a96e3SMatthew G. Knepley PetscInt f, g; 29893f2a96e3SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "Offsets\n");CHKERRQ(ierr); 29903f2a96e3SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " ");CHKERRQ(ierr); 29913f2a96e3SMatthew G. Knepley for (g = 0; g < cols; ++g) { 29923f2a96e3SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " % 14s", DMPolytopeTypes[g]);CHKERRQ(ierr); 29933f2a96e3SMatthew G. Knepley } 29943f2a96e3SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 29953f2a96e3SMatthew G. Knepley for (f = 0; f < Nrt; ++f) { 29963f2a96e3SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "%2d |", reftypes[f]);CHKERRQ(ierr); 29973f2a96e3SMatthew G. Knepley for (g = 0; g < cols; ++g) { 29983f2a96e3SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " % 14d", PetscRealPart(off[f*DM_NUM_POLYTOPES+g]));CHKERRQ(ierr); 29993f2a96e3SMatthew G. Knepley } 30003f2a96e3SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr); 30013f2a96e3SMatthew G. Knepley } 30023f2a96e3SMatthew G. Knepley } 30033f2a96e3SMatthew G. Knepley #endif 30043f2a96e3SMatthew G. Knepley ierr = ISRestoreIndices(rtIS, &reftypes);CHKERRQ(ierr); 30053f2a96e3SMatthew G. Knepley ierr = ISDestroy(&rtIS);CHKERRQ(ierr); 30063f2a96e3SMatthew G. Knepley } else { 3007412e9a14SMatthew G. Knepley ierr = PetscCalloc1(DM_NUM_POLYTOPES*DM_NUM_POLYTOPES, &off);CHKERRQ(ierr); 3008412e9a14SMatthew G. Knepley for (c = DM_POLYTOPE_POINT; c < DM_NUM_POLYTOPES; ++c) { 3009412e9a14SMatthew G. Knepley const DMPolytopeType ct = (DMPolytopeType) c; 3010412e9a14SMatthew G. Knepley for (cN = DM_POLYTOPE_POINT; cN < DM_NUM_POLYTOPES; ++cN) { 3011412e9a14SMatthew G. Knepley const DMPolytopeType ctNew = (DMPolytopeType) cN; 3012412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3013412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 3014412e9a14SMatthew G. Knepley PetscInt Nct, n, i; 3015412e9a14SMatthew G. Knepley 3016412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ct) < 0 || DMPolytopeTypeGetDim(ctNew) < 0) {off[ct*DM_NUM_POLYTOPES+ctNew] = -1; break;} 3017412e9a14SMatthew G. Knepley off[ct*DM_NUM_POLYTOPES+ctNew] = 0; 3018412e9a14SMatthew G. Knepley for (i = DM_POLYTOPE_POINT; i < DM_NUM_POLYTOPES; ++i) { 3019412e9a14SMatthew G. Knepley const DMPolytopeType ict = (DMPolytopeType) ctOrder[i]; 3020412e9a14SMatthew G. Knepley const DMPolytopeType ictn = (DMPolytopeType) ctOrder[i+1]; 3021412e9a14SMatthew G. Knepley 30223f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ict, PETSC_DETERMINE, NULL, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 3023412e9a14SMatthew G. Knepley if (ict == ct) { 3024412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) break; 3025412e9a14SMatthew G. Knepley if (n == Nct) off[ct*DM_NUM_POLYTOPES+ctNew] = -1; 3026412e9a14SMatthew G. Knepley break; 3027412e9a14SMatthew G. Knepley } 3028412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) off[ct*DM_NUM_POLYTOPES+ctNew] += (ctStart[ictn]-ctStart[ict]) * rsize[n]; 3029412e9a14SMatthew G. Knepley } 3030412e9a14SMatthew G. Knepley } 3031412e9a14SMatthew G. Knepley } 30323f2a96e3SMatthew G. Knepley } 3033412e9a14SMatthew G. Knepley *offset = off; 3034412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3035412e9a14SMatthew G. Knepley } 3036412e9a14SMatthew G. Knepley 3037412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetStarts(DMPlexCellRefiner cr, const PetscInt ctStart[], const PetscInt ctStartNew[]) 3038412e9a14SMatthew G. Knepley { 3039412e9a14SMatthew G. Knepley const PetscInt ctSize = DM_NUM_POLYTOPES+1; 3040412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3041412e9a14SMatthew G. Knepley 3042412e9a14SMatthew G. Knepley PetscFunctionBegin; 3043412e9a14SMatthew G. Knepley if (cr->setupcalled) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_ARG_WRONGSTATE, "Must call this function before DMPlexCellRefinerSetUp()"); 3044412e9a14SMatthew G. Knepley ierr = PetscCalloc2(ctSize, &cr->ctStart, ctSize, &cr->ctStartNew);CHKERRQ(ierr); 3045412e9a14SMatthew G. Knepley ierr = PetscArraycpy(cr->ctStart, ctStart, ctSize);CHKERRQ(ierr); 3046412e9a14SMatthew G. Knepley ierr = PetscArraycpy(cr->ctStartNew, ctStartNew, ctSize);CHKERRQ(ierr); 3047412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3048412e9a14SMatthew G. Knepley } 3049412e9a14SMatthew G. Knepley 3050412e9a14SMatthew G. Knepley /* Construct cell type order since we must loop over cell types in depth order */ 3051412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCreateCellTypeOrder_Internal(DMPolytopeType ctCell, PetscInt *ctOrder[], PetscInt *ctOrderInv[]) 3052412e9a14SMatthew G. Knepley { 3053412e9a14SMatthew G. Knepley PetscInt *ctO, *ctOInv; 3054412e9a14SMatthew G. Knepley PetscInt c, d, off = 0; 3055412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3056412e9a14SMatthew G. Knepley 3057412e9a14SMatthew G. Knepley PetscFunctionBegin; 3058412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctO, DM_NUM_POLYTOPES+1, &ctOInv);CHKERRQ(ierr); 3059412e9a14SMatthew G. Knepley for (d = 3; d >= DMPolytopeTypeGetDim(ctCell); --d) { 3060412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 3061412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue; 3062412e9a14SMatthew G. Knepley ctO[off++] = c; 3063412e9a14SMatthew G. Knepley } 3064412e9a14SMatthew G. Knepley } 3065412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ctCell) != 0) { 3066412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 3067412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != 0) continue; 3068412e9a14SMatthew G. Knepley ctO[off++] = c; 3069412e9a14SMatthew G. Knepley } 3070412e9a14SMatthew G. Knepley } 3071412e9a14SMatthew G. Knepley for (d = DMPolytopeTypeGetDim(ctCell)-1; d > 0; --d) { 3072412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 3073412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue; 3074412e9a14SMatthew G. Knepley ctO[off++] = c; 3075412e9a14SMatthew G. Knepley } 3076412e9a14SMatthew G. Knepley } 3077412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 3078412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) >= 0) continue; 3079412e9a14SMatthew G. Knepley ctO[off++] = c; 3080412e9a14SMatthew G. Knepley } 3081412e9a14SMatthew G. Knepley if (off != DM_NUM_POLYTOPES+1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid offset %D for cell type order", off); 3082412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 3083412e9a14SMatthew G. Knepley ctOInv[ctO[c]] = c; 3084412e9a14SMatthew G. Knepley } 3085412e9a14SMatthew G. Knepley *ctOrder = ctO; 3086412e9a14SMatthew G. Knepley *ctOrderInv = ctOInv; 3087412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3088412e9a14SMatthew G. Knepley } 3089412e9a14SMatthew G. Knepley 3090412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerSetUp(DMPlexCellRefiner cr) 3091412e9a14SMatthew G. Knepley { 3092412e9a14SMatthew G. Knepley DM dm = cr->dm; 3093412e9a14SMatthew G. Knepley DMPolytopeType ctCell; 3094412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p, c; 3095412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3096412e9a14SMatthew G. Knepley 3097412e9a14SMatthew G. Knepley PetscFunctionBegin; 3098412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 3099412e9a14SMatthew G. Knepley if (cr->setupcalled) PetscFunctionReturn(0); 3100a5801f52SStefano Zampini if (cr->ops->setup) { 3101a5801f52SStefano Zampini ierr = (*cr->ops->setup)(cr);CHKERRQ(ierr); 3102a5801f52SStefano Zampini } 3103412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3104a5801f52SStefano Zampini if (pEnd > pStart) { 3105a5801f52SStefano Zampini ierr = DMPlexGetCellType(dm, 0, &ctCell);CHKERRQ(ierr); 3106a5801f52SStefano Zampini } else { 3107412e9a14SMatthew G. Knepley PetscInt dim; 3108a57030b0SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3109412e9a14SMatthew G. Knepley switch (dim) { 3110412e9a14SMatthew G. Knepley case 0: ctCell = DM_POLYTOPE_POINT;break; 3111412e9a14SMatthew G. Knepley case 1: ctCell = DM_POLYTOPE_SEGMENT;break; 3112412e9a14SMatthew G. Knepley case 2: ctCell = DM_POLYTOPE_TRIANGLE;break; 3113412e9a14SMatthew G. Knepley case 3: ctCell = DM_POLYTOPE_TETRAHEDRON;break; 3114a5801f52SStefano Zampini default: ctCell = DM_POLYTOPE_UNKNOWN; 3115412e9a14SMatthew G. Knepley } 3116412e9a14SMatthew G. Knepley } 3117412e9a14SMatthew G. Knepley ierr = DMPlexCreateCellTypeOrder_Internal(ctCell, &cr->ctOrder, &cr->ctOrderInv);CHKERRQ(ierr); 3118412e9a14SMatthew G. Knepley /* Construct sizes and offsets for each cell type */ 3119412e9a14SMatthew G. Knepley if (!cr->ctStart) { 3120412e9a14SMatthew G. Knepley PetscInt *ctS, *ctSN, *ctC, *ctCN; 3121412e9a14SMatthew G. Knepley 3122412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctS, DM_NUM_POLYTOPES+1, &ctSN);CHKERRQ(ierr); 3123412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctC, DM_NUM_POLYTOPES+1, &ctCN);CHKERRQ(ierr); 3124412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3125412e9a14SMatthew G. Knepley DMPolytopeType ct; 3126412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3127412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 3128412e9a14SMatthew G. Knepley PetscInt Nct, n; 3129412e9a14SMatthew G. Knepley 3130412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 3131412e9a14SMatthew G. Knepley if ((PetscInt) ct < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No cell type for point %D", p); 3132412e9a14SMatthew G. Knepley ++ctC[ct]; 31333f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, p, NULL, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 3134412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) ctCN[rct[n]] += rsize[n]; 3135412e9a14SMatthew G. Knepley } 3136412e9a14SMatthew G. Knepley for (c = 0; c < DM_NUM_POLYTOPES; ++c) { 3137412e9a14SMatthew G. Knepley const PetscInt ct = cr->ctOrder[c]; 3138412e9a14SMatthew G. Knepley const PetscInt ctn = cr->ctOrder[c+1]; 3139412e9a14SMatthew G. Knepley 3140412e9a14SMatthew G. Knepley ctS[ctn] = ctS[ct] + ctC[ct]; 3141412e9a14SMatthew G. Knepley ctSN[ctn] = ctSN[ct] + ctCN[ct]; 3142412e9a14SMatthew G. Knepley } 3143412e9a14SMatthew G. Knepley ierr = PetscFree2(ctC, ctCN);CHKERRQ(ierr); 3144412e9a14SMatthew G. Knepley cr->ctStart = ctS; 3145412e9a14SMatthew G. Knepley cr->ctStartNew = ctSN; 3146412e9a14SMatthew G. Knepley } 3147412e9a14SMatthew G. Knepley ierr = CellRefinerCreateOffset_Internal(cr, cr->ctOrder, cr->ctStart, &cr->offset);CHKERRQ(ierr); 3148412e9a14SMatthew G. Knepley cr->setupcalled = PETSC_TRUE; 3149412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3150412e9a14SMatthew G. Knepley } 3151412e9a14SMatthew G. Knepley 3152412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView_Ascii(DMPlexCellRefiner cr, PetscViewer v) 3153412e9a14SMatthew G. Knepley { 3154412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3155412e9a14SMatthew G. Knepley 3156412e9a14SMatthew G. Knepley PetscFunctionBegin; 3157412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(v, "Cell Refiner: %s\n", DMPlexCellRefinerTypes[cr->type]);CHKERRQ(ierr); 3158412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3159412e9a14SMatthew G. Knepley } 3160412e9a14SMatthew G. Knepley 3161412e9a14SMatthew G. Knepley /* 3162412e9a14SMatthew G. Knepley DMPlexCellRefinerView - Views a DMPlexCellRefiner object 3163412e9a14SMatthew G. Knepley 3164412e9a14SMatthew G. Knepley Collective on cr 3165412e9a14SMatthew G. Knepley 3166412e9a14SMatthew G. Knepley Input Parameters: 3167412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 3168412e9a14SMatthew G. Knepley - viewer - The PetscViewer object 3169412e9a14SMatthew G. Knepley 3170412e9a14SMatthew G. Knepley Level: beginner 3171412e9a14SMatthew G. Knepley 3172412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerCreate() 3173412e9a14SMatthew G. Knepley */ 3174412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView(DMPlexCellRefiner cr, PetscViewer viewer) 3175412e9a14SMatthew G. Knepley { 3176412e9a14SMatthew G. Knepley PetscBool iascii; 3177412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3178412e9a14SMatthew G. Knepley 3179412e9a14SMatthew G. Knepley PetscFunctionBegin; 3180412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 3181412e9a14SMatthew G. Knepley if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 3182412e9a14SMatthew G. Knepley if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) cr), &viewer);CHKERRQ(ierr);} 3183412e9a14SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 3184412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 3185412e9a14SMatthew G. Knepley if (iascii) {ierr = DMPlexCellRefinerView_Ascii(cr, viewer);CHKERRQ(ierr);} 3186412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 3187412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3188412e9a14SMatthew G. Knepley } 3189412e9a14SMatthew G. Knepley 3190412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerDestroy(DMPlexCellRefiner *cr) 3191412e9a14SMatthew G. Knepley { 3192412e9a14SMatthew G. Knepley PetscInt c; 3193412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3194412e9a14SMatthew G. Knepley 3195412e9a14SMatthew G. Knepley PetscFunctionBegin; 3196412e9a14SMatthew G. Knepley if (!*cr) PetscFunctionReturn(0); 3197412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(*cr, DM_CLASSID, 1); 3198a5801f52SStefano Zampini if ((*cr)->ops->destroy) { 3199a5801f52SStefano Zampini ierr = ((*cr)->ops->destroy)(*cr);CHKERRQ(ierr); 3200a5801f52SStefano Zampini } 3201412e9a14SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) (*cr)->dm);CHKERRQ(ierr); 32023f2a96e3SMatthew G. Knepley ierr = DMLabelDestroy(&(*cr)->refineType);CHKERRQ(ierr); 3203412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->ctOrder, (*cr)->ctOrderInv);CHKERRQ(ierr); 3204412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->ctStart, (*cr)->ctStartNew);CHKERRQ(ierr); 3205412e9a14SMatthew G. Knepley ierr = PetscFree((*cr)->offset);CHKERRQ(ierr); 3206412e9a14SMatthew G. Knepley for (c = 0; c < DM_NUM_POLYTOPES; ++c) { 3207412e9a14SMatthew G. Knepley ierr = PetscFEDestroy(&(*cr)->coordFE[c]);CHKERRQ(ierr); 3208412e9a14SMatthew G. Knepley ierr = PetscFEGeomDestroy(&(*cr)->refGeom[c]);CHKERRQ(ierr); 3209412e9a14SMatthew G. Knepley } 3210412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->coordFE, (*cr)->refGeom);CHKERRQ(ierr); 3211412e9a14SMatthew G. Knepley ierr = PetscHeaderDestroy(cr);CHKERRQ(ierr); 3212412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3213412e9a14SMatthew G. Knepley } 3214412e9a14SMatthew G. Knepley 3215412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerCreate(DM dm, DMPlexCellRefiner *cr) 3216412e9a14SMatthew G. Knepley { 3217412e9a14SMatthew G. Knepley DMPlexCellRefiner tmp; 3218412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3219412e9a14SMatthew G. Knepley 3220412e9a14SMatthew G. Knepley PetscFunctionBegin; 3221412e9a14SMatthew G. Knepley PetscValidPointer(cr, 2); 3222412e9a14SMatthew G. Knepley *cr = NULL; 3223412e9a14SMatthew G. Knepley ierr = PetscHeaderCreate(tmp, DM_CLASSID, "DMPlexCellRefiner", "Cell Refiner", "DMPlexCellRefiner", PETSC_COMM_SELF, DMPlexCellRefinerDestroy, DMPlexCellRefinerView);CHKERRQ(ierr); 3224412e9a14SMatthew G. Knepley tmp->setupcalled = PETSC_FALSE; 3225412e9a14SMatthew G. Knepley 3226412e9a14SMatthew G. Knepley tmp->dm = dm; 3227412e9a14SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); 3228412e9a14SMatthew G. Knepley ierr = DMPlexGetCellRefinerType(dm, &tmp->type);CHKERRQ(ierr); 3229412e9a14SMatthew G. Knepley switch (tmp->type) { 323096ca5757SLisandro Dalcin case DM_REFINER_REGULAR: 3231412e9a14SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_Regular; 3232412e9a14SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_Regular; 3233412e9a14SMatthew G. Knepley tmp->ops->getcellvertices = DMPlexCellRefinerGetCellVertices_Regular; 3234412e9a14SMatthew G. Knepley tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_Regular; 3235a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 3236412e9a14SMatthew G. Knepley tmp->ops->getaffinetransforms = DMPlexCellRefinerGetAffineTransforms_Regular; 3237412e9a14SMatthew G. Knepley tmp->ops->getaffinefacetransforms = DMPlexCellRefinerGetAffineFaceTransforms_Regular; 3238412e9a14SMatthew G. Knepley break; 323996ca5757SLisandro Dalcin case DM_REFINER_TO_BOX: 324096ca5757SLisandro Dalcin tmp->ops->refine = DMPlexCellRefinerRefine_ToBox; 324196ca5757SLisandro Dalcin tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToBox; 324296ca5757SLisandro Dalcin tmp->ops->getcellvertices = DMPlexCellRefinerGetCellVertices_ToBox; 324396ca5757SLisandro Dalcin tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_ToBox; 3244a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 3245412e9a14SMatthew G. Knepley break; 324696ca5757SLisandro Dalcin case DM_REFINER_TO_SIMPLEX: 3247412e9a14SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_ToSimplex; 3248412e9a14SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToSimplex; 3249a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 3250412e9a14SMatthew G. Knepley break; 3251cf4091a3SMatthew G. Knepley case DM_REFINER_ALFELD2D: 3252cf4091a3SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_Alfeld2D; 3253cf4091a3SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_None; 3254a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 3255cf4091a3SMatthew G. Knepley break; 3256cf4091a3SMatthew G. Knepley case DM_REFINER_ALFELD3D: 3257cf4091a3SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_Alfeld3D; 3258cf4091a3SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_None; 3259a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 3260cf4091a3SMatthew G. Knepley break; 3261a5801f52SStefano Zampini case DM_REFINER_BOUNDARYLAYER: 3262a5801f52SStefano Zampini tmp->ops->setup = DMPlexCellRefinerSetUp_BL; 3263a5801f52SStefano Zampini tmp->ops->destroy = DMPlexCellRefinerDestroy_BL; 3264cf4091a3SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_BL; 3265cf4091a3SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_BL; 3266a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_BL; 3267cf4091a3SMatthew G. Knepley break; 32683f2a96e3SMatthew G. Knepley case DM_REFINER_SBR: 32693f2a96e3SMatthew G. Knepley tmp->ops->setup = DMPlexCellRefinerSetUp_SBR; 32703f2a96e3SMatthew G. Knepley tmp->ops->destroy = DMPlexCellRefinerDestroy_SBR; 32713f2a96e3SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_SBR; 32723f2a96e3SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_SBR; 32733f2a96e3SMatthew G. Knepley tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 32743f2a96e3SMatthew G. Knepley break; 3275412e9a14SMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Invalid cell refiner type %s", DMPlexCellRefinerTypes[tmp->type]); 3276412e9a14SMatthew G. Knepley } 3277412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES, &tmp->coordFE, DM_NUM_POLYTOPES, &tmp->refGeom);CHKERRQ(ierr); 3278412e9a14SMatthew G. Knepley *cr = tmp; 3279412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3280412e9a14SMatthew G. Knepley } 3281412e9a14SMatthew G. Knepley 3282412e9a14SMatthew G. Knepley /*@ 3283412e9a14SMatthew G. Knepley DMPlexCellRefinerGetAffineTransforms - Gets the affine map from the reference cell to each subcell 3284412e9a14SMatthew G. Knepley 3285412e9a14SMatthew G. Knepley Input Parameters: 3286412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 3287412e9a14SMatthew G. Knepley - ct - The cell type 3288412e9a14SMatthew G. Knepley 3289412e9a14SMatthew G. Knepley Output Parameters: 3290412e9a14SMatthew G. Knepley + Nc - The number of subcells produced from this cell type 3291412e9a14SMatthew G. Knepley . v0 - The translation of the first vertex for each subcell 3292412e9a14SMatthew G. Knepley . J - The Jacobian for each subcell (map from reference cell to subcell) 3293412e9a14SMatthew G. Knepley - invJ - The inverse Jacobian for each subcell 3294412e9a14SMatthew G. Knepley 3295412e9a14SMatthew G. Knepley Level: developer 3296412e9a14SMatthew G. Knepley 3297412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineFaceTransforms(), Create() 3298412e9a14SMatthew G. Knepley @*/ 3299412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[]) 3300412e9a14SMatthew G. Knepley { 3301412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3302412e9a14SMatthew G. Knepley 3303412e9a14SMatthew G. Knepley PetscFunctionBegin; 3304412e9a14SMatthew G. Knepley if (!cr->ops->getaffinetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine transforms from this refiner"); 3305412e9a14SMatthew G. Knepley ierr = (*cr->ops->getaffinetransforms)(cr, ct, Nc, v0, J, invJ);CHKERRQ(ierr); 3306412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3307412e9a14SMatthew G. Knepley } 3308412e9a14SMatthew G. Knepley 3309412e9a14SMatthew G. Knepley /*@ 3310412e9a14SMatthew G. Knepley DMPlexCellRefinerGetAffineFaceTransforms - Gets the affine map from the reference face cell to each face in the given cell 3311412e9a14SMatthew G. Knepley 3312412e9a14SMatthew G. Knepley Input Parameters: 3313412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 3314412e9a14SMatthew G. Knepley - ct - The cell type 3315412e9a14SMatthew G. Knepley 3316412e9a14SMatthew G. Knepley Output Parameters: 3317412e9a14SMatthew G. Knepley + Nf - The number of faces for this cell type 3318412e9a14SMatthew G. Knepley . v0 - The translation of the first vertex for each face 3319412e9a14SMatthew G. Knepley . J - The Jacobian for each face (map from original cell to subcell) 3320412e9a14SMatthew G. Knepley . invJ - The inverse Jacobian for each face 3321412e9a14SMatthew G. Knepley - detJ - The determinant of the Jacobian for each face 3322412e9a14SMatthew G. Knepley 3323412e9a14SMatthew G. Knepley Note: The Jacobian and inverse Jacboian will be rectangular, and the inverse is really a generalized inverse. 3324412e9a14SMatthew G. Knepley 3325412e9a14SMatthew G. Knepley Level: developer 3326412e9a14SMatthew G. Knepley 3327412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineTransforms(), Create() 3328412e9a14SMatthew G. Knepley @*/ 3329412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[]) 3330412e9a14SMatthew G. Knepley { 3331412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3332412e9a14SMatthew G. Knepley 3333412e9a14SMatthew G. Knepley PetscFunctionBegin; 3334412e9a14SMatthew G. Knepley if (!cr->ops->getaffinefacetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine face transforms from this refiner"); 3335412e9a14SMatthew G. Knepley ierr = (*cr->ops->getaffinefacetransforms)(cr, ct, Nf, v0, J, invJ, detJ);CHKERRQ(ierr); 3336412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3337412e9a14SMatthew G. Knepley } 3338412e9a14SMatthew G. Knepley 3339412e9a14SMatthew G. Knepley /* Numbering regularly refined meshes 3340412e9a14SMatthew G. Knepley 3341412e9a14SMatthew G. Knepley We want the numbering of the new mesh to respect the same depth stratification as the old mesh. We first compute 3342412e9a14SMatthew G. Knepley the number of new points at each depth. This means that offsets for each depth can be computed, making no assumptions 3343412e9a14SMatthew G. Knepley about the order of different cell types. 3344412e9a14SMatthew G. Knepley 3345412e9a14SMatthew G. Knepley However, when we want to order different depth strata, it will be very useful to make assumptions about contiguous 3346412e9a14SMatthew G. Knepley numbering of different cell types, especially if we want to compute new numberings without communication. Therefore, we 3347412e9a14SMatthew G. Knepley will require that cells are numbering contiguously for each cell type, and that those blocks come in the same order as 3348412e9a14SMatthew G. Knepley the cell type enumeration within a given depth stratum. 3349412e9a14SMatthew G. Knepley 3350412e9a14SMatthew 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 3351412e9a14SMatthew G. Knepley start at the new depth offset, run through all prior cell types incrementing by the total addition from that type, then 3352412e9a14SMatthew G. Knepley offset by the old cell type number and replica number for the insertion. 3353412e9a14SMatthew G. Knepley */ 33543f2a96e3SMatthew G. Knepley 33553f2a96e3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetReducedPointNumber(DMPlexCellRefiner cr, PetscInt rt, PetscInt p, PetscInt *rp) 33563f2a96e3SMatthew G. Knepley { 33573f2a96e3SMatthew G. Knepley IS rtIS; 33583f2a96e3SMatthew G. Knepley const PetscInt *points; 33593f2a96e3SMatthew G. Knepley PetscInt n; 33603f2a96e3SMatthew G. Knepley PetscErrorCode ierr; 33613f2a96e3SMatthew G. Knepley 33623f2a96e3SMatthew G. Knepley PetscFunctionBegin; 33633f2a96e3SMatthew G. Knepley /* TODO Move this inside the DMLabel so that I do not have to create the IS */ 33643f2a96e3SMatthew G. Knepley ierr = DMLabelGetStratumIS(cr->refineType, rt, &rtIS);CHKERRQ(ierr); 33653f2a96e3SMatthew G. Knepley ierr = ISGetLocalSize(rtIS, &n);CHKERRQ(ierr); 33663f2a96e3SMatthew G. Knepley ierr = ISGetIndices(rtIS, &points);CHKERRQ(ierr); 33673f2a96e3SMatthew G. Knepley ierr = PetscFindInt(p, n, points, rp);CHKERRQ(ierr); 33683f2a96e3SMatthew G. Knepley ierr = ISRestoreIndices(rtIS, &points);CHKERRQ(ierr); 33693f2a96e3SMatthew G. Knepley ierr = ISDestroy(&rtIS);CHKERRQ(ierr); 33703f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 33713f2a96e3SMatthew G. Knepley } 33723f2a96e3SMatthew G. Knepley 33733f2a96e3SMatthew G. Knepley /* 33743f2a96e3SMatthew G. Knepley DMPlexCellRefinerGetNewPoint - Get the number of a point in the refined mesh based on information from the original mesh. 33753f2a96e3SMatthew G. Knepley 33763f2a96e3SMatthew G. Knepley Not collective 33773f2a96e3SMatthew G. Knepley 33783f2a96e3SMatthew G. Knepley Input Parameters: 33793f2a96e3SMatthew G. Knepley + cr - The cell refiner 33803f2a96e3SMatthew G. Knepley . ct - The type of the original point which produces the new point 33813f2a96e3SMatthew G. Knepley . ctNew - The type of the new point 33823f2a96e3SMatthew G. Knepley . p - The original point which produces the new point 33833f2a96e3SMatthew G. Knepley - r - The replica number of the new point, meaning it is the rth point of type ctNew produced from p 33843f2a96e3SMatthew G. Knepley 33853f2a96e3SMatthew G. Knepley Output Parameters: 33863f2a96e3SMatthew G. Knepley . pNew - The new point number 33873f2a96e3SMatthew G. Knepley 33883f2a96e3SMatthew G. Knepley Level: developer 33893f2a96e3SMatthew G. Knepley 33903f2a96e3SMatthew G. Knepley .seealso: DMPlexCellRefinerRefine() 33913f2a96e3SMatthew G. Knepley */ 3392412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetNewPoint(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType ctNew, PetscInt p, PetscInt r, PetscInt *pNew) 3393412e9a14SMatthew G. Knepley { 3394412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3395412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 33963f2a96e3SMatthew G. Knepley PetscInt rt, Nct, n, off, rp; 3397412e9a14SMatthew G. Knepley PetscInt ctS = cr->ctStart[ct], ctE = cr->ctStart[cr->ctOrder[cr->ctOrderInv[ct]+1]]; 3398412e9a14SMatthew G. Knepley PetscInt ctSN = cr->ctStartNew[ctNew], ctEN = cr->ctStartNew[cr->ctOrder[cr->ctOrderInv[ctNew]+1]]; 33993f2a96e3SMatthew G. Knepley PetscInt newp = ctSN, cind; 3400412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3401412e9a14SMatthew G. Knepley 3402412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 3403412e9a14SMatthew 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); 34043f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, p, &rt, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 34053f2a96e3SMatthew G. Knepley if (cr->refineType) { 34063f2a96e3SMatthew G. Knepley /* TODO Make this a function in DMLabel */ 34073f2a96e3SMatthew G. Knepley { 34083f2a96e3SMatthew G. Knepley IS rtIS; 34093f2a96e3SMatthew G. Knepley const PetscInt *reftypes; 34103f2a96e3SMatthew G. Knepley PetscInt Nrt; 3411412e9a14SMatthew G. Knepley 34123f2a96e3SMatthew G. Knepley ierr = DMLabelGetNumValues(cr->refineType, &Nrt);CHKERRQ(ierr); 34133f2a96e3SMatthew G. Knepley ierr = DMLabelGetValueIS(cr->refineType, &rtIS);CHKERRQ(ierr); 34143f2a96e3SMatthew G. Knepley ierr = ISGetIndices(rtIS, &reftypes);CHKERRQ(ierr); 34153f2a96e3SMatthew G. Knepley for (cind = 0; cind < Nrt; ++cind) if (reftypes[cind] == rt) break; 34163f2a96e3SMatthew G. Knepley if (cind >= Nrt) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Unable to locate refine type %D", rt); 34173f2a96e3SMatthew G. Knepley ierr = ISRestoreIndices(rtIS, &reftypes);CHKERRQ(ierr); 34183f2a96e3SMatthew G. Knepley ierr = ISDestroy(&rtIS);CHKERRQ(ierr); 34193f2a96e3SMatthew G. Knepley } 34203f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerGetReducedPointNumber(cr, rt, p, &rp);CHKERRQ(ierr); 34213f2a96e3SMatthew G. Knepley if (rp < 0) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell type %s point %D does not have refine type %D", DMPolytopeTypes[ct], p, rt); 34223f2a96e3SMatthew G. Knepley } else { 34233f2a96e3SMatthew G. Knepley cind = ct; 34243f2a96e3SMatthew G. Knepley rp = p - ctS; 34253f2a96e3SMatthew G. Knepley } 34263f2a96e3SMatthew G. Knepley off = cr->offset[cind*DM_NUM_POLYTOPES + ctNew]; 34273f2a96e3SMatthew G. Knepley if (off < 0) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell type %s (%D) of point %D does not produce type %s", DMPolytopeTypes[ct], rt, p, DMPolytopeTypes[ctNew]); 3428412e9a14SMatthew G. Knepley newp += off; 3429412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 3430412e9a14SMatthew G. Knepley if (rct[n] == ctNew) { 3431412e9a14SMatthew G. Knepley if (rsize[n] && r >= rsize[n]) 3432412e9a14SMatthew 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]); 34333f2a96e3SMatthew G. Knepley newp += rp * rsize[n] + r; 3434412e9a14SMatthew G. Knepley break; 3435412e9a14SMatthew G. Knepley } 3436412e9a14SMatthew G. Knepley } 3437412e9a14SMatthew G. Knepley 3438412e9a14SMatthew 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); 3439412e9a14SMatthew G. Knepley *pNew = newp; 3440412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3441412e9a14SMatthew G. Knepley } 3442412e9a14SMatthew G. Knepley 3443412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetConeSizes(DMPlexCellRefiner cr, DM rdm) 3444412e9a14SMatthew G. Knepley { 3445412e9a14SMatthew G. Knepley DM dm = cr->dm; 3446412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p, pNew; 3447412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3448412e9a14SMatthew G. Knepley 3449412e9a14SMatthew G. Knepley PetscFunctionBegin; 3450412e9a14SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 3451412e9a14SMatthew G. Knepley ierr = DMCreateLabel(rdm, "celltype");CHKERRQ(ierr); 3452412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3453412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3454412e9a14SMatthew G. Knepley DMPolytopeType ct; 3455412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3456412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 3457412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 3458412e9a14SMatthew G. Knepley 3459412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 34603f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 3461412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 3462412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 3463412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 3464412e9a14SMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, pNew, DMPolytopeTypeGetConeSize(rct[n]));CHKERRQ(ierr); 3465412e9a14SMatthew G. Knepley ierr = DMPlexSetCellType(rdm, pNew, rct[n]);CHKERRQ(ierr); 3466412e9a14SMatthew G. Knepley } 3467412e9a14SMatthew G. Knepley } 3468412e9a14SMatthew G. Knepley } 3469412e9a14SMatthew G. Knepley { 3470412e9a14SMatthew G. Knepley DMLabel ctLabel; 3471412e9a14SMatthew G. Knepley DM_Plex *plex = (DM_Plex *) rdm->data; 3472412e9a14SMatthew G. Knepley 3473412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(rdm, &ctLabel);CHKERRQ(ierr); 3474412e9a14SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) ctLabel, &plex->celltypeState);CHKERRQ(ierr); 3475412e9a14SMatthew G. Knepley } 3476412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3477412e9a14SMatthew G. Knepley } 3478412e9a14SMatthew G. Knepley 3479412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCones(DMPlexCellRefiner cr, DM rdm) 3480412e9a14SMatthew G. Knepley { 3481412e9a14SMatthew G. Knepley DM dm = cr->dm; 3482412e9a14SMatthew G. Knepley DMPolytopeType ct; 3483412e9a14SMatthew G. Knepley PetscInt *coneNew, *orntNew; 3484412e9a14SMatthew G. Knepley PetscInt maxConeSize = 0, pStart, pEnd, p, pNew; 3485412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3486412e9a14SMatthew G. Knepley 3487412e9a14SMatthew G. Knepley PetscFunctionBegin; 3488412e9a14SMatthew G. Knepley for (p = 0; p < DM_NUM_POLYTOPES; ++p) maxConeSize = PetscMax(maxConeSize, DMPolytopeTypeGetConeSize((DMPolytopeType) p)); 3489412e9a14SMatthew G. Knepley ierr = PetscMalloc2(maxConeSize, &coneNew, maxConeSize, &orntNew);CHKERRQ(ierr); 3490412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3491412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3492412e9a14SMatthew G. Knepley const PetscInt *cone, *ornt; 3493412e9a14SMatthew G. Knepley PetscInt coff, ooff, c; 3494412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3495412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 3496412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 3497412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 3498412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 3499412e9a14SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &ornt);CHKERRQ(ierr); 35003f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 3501412e9a14SMatthew G. Knepley for (n = 0, coff = 0, ooff = 0; n < Nct; ++n) { 3502412e9a14SMatthew G. Knepley const DMPolytopeType ctNew = rct[n]; 3503412e9a14SMatthew G. Knepley const PetscInt csizeNew = DMPolytopeTypeGetConeSize(ctNew); 3504412e9a14SMatthew G. Knepley 3505412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 3506412e9a14SMatthew G. Knepley /* pNew is a subcell produced by subdividing p */ 3507412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 3508412e9a14SMatthew G. Knepley for (c = 0; c < csizeNew; ++c) { 3509412e9a14SMatthew G. Knepley PetscInt ppp = -1; /* Parent Parent point: Parent of point pp */ 3510412e9a14SMatthew G. Knepley PetscInt pp = p; /* Parent point: Point in the original mesh producing new cone point */ 3511412e9a14SMatthew G. Knepley PetscInt po = 0; /* Orientation of parent point pp in parent parent point ppp */ 3512412e9a14SMatthew G. Knepley DMPolytopeType pct = ct; /* Parent type: Cell type for parent of new cone point */ 3513412e9a14SMatthew G. Knepley const PetscInt *pcone = cone; /* Parent cone: Cone of parent point pp */ 3514412e9a14SMatthew G. Knepley PetscInt pr = -1; /* Replica number of pp that produces new cone point */ 3515412e9a14SMatthew G. Knepley const DMPolytopeType ft = (DMPolytopeType) rcone[coff++]; /* Cell type for new cone point of pNew */ 3516412e9a14SMatthew G. Knepley const PetscInt fn = rcone[coff++]; /* Number of cones of p that need to be taken when producing new cone point */ 3517412e9a14SMatthew G. Knepley PetscInt fo = rornt[ooff++]; /* Orientation of new cone point in pNew */ 3518412e9a14SMatthew G. Knepley PetscInt lc; 3519412e9a14SMatthew G. Knepley 3520412e9a14SMatthew G. Knepley /* Get the type (pct) and point number (pp) of the parent point in the original mesh which produces this cone point */ 3521412e9a14SMatthew G. Knepley for (lc = 0; lc < fn; ++lc) { 3522412e9a14SMatthew G. Knepley const PetscInt *ppornt; 3523412e9a14SMatthew G. Knepley PetscInt pcp; 3524412e9a14SMatthew G. Knepley 3525412e9a14SMatthew G. Knepley ierr = DMPolytopeMapCell(pct, po, rcone[coff++], &pcp);CHKERRQ(ierr); 3526412e9a14SMatthew G. Knepley ppp = pp; 3527412e9a14SMatthew G. Knepley pp = pcone[pcp]; 3528412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, pp, &pct);CHKERRQ(ierr); 3529412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, pp, &pcone);CHKERRQ(ierr); 3530412e9a14SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, ppp, &ppornt);CHKERRQ(ierr); 3531cf4091a3SMatthew G. Knepley if (po < 0 && pct != DM_POLYTOPE_POINT) { 3532cf4091a3SMatthew G. Knepley const PetscInt pornt = ppornt[pcp]; 3533cf4091a3SMatthew G. Knepley const PetscInt pcsize = DMPolytopeTypeGetConeSize(pct); 3534cf4091a3SMatthew G. Knepley const PetscInt pcstart = pornt < 0 ? -(pornt+1) : pornt; 3535cf4091a3SMatthew G. Knepley const PetscInt rcstart = (pcstart+pcsize-1)%pcsize; 3536cf4091a3SMatthew G. Knepley po = pornt < 0 ? -(rcstart+1) : rcstart; 3537cf4091a3SMatthew G. Knepley } else { 3538412e9a14SMatthew G. Knepley po = ppornt[pcp]; 3539412e9a14SMatthew G. Knepley } 3540cf4091a3SMatthew G. Knepley } 3541412e9a14SMatthew G. Knepley pr = rcone[coff++]; 3542412e9a14SMatthew G. Knepley /* Orientation po of pp maps (pr, fo) -> (pr', fo') */ 35433f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerMapSubcells(cr, pct, pp, po, ft, pr, fo, &pr, &fo);CHKERRQ(ierr); 3544412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, pct, ft, pp, pr, &coneNew[c]);CHKERRQ(ierr); 3545412e9a14SMatthew G. Knepley orntNew[c] = fo; 3546412e9a14SMatthew G. Knepley } 3547412e9a14SMatthew G. Knepley ierr = DMPlexSetCone(rdm, pNew, coneNew);CHKERRQ(ierr); 3548412e9a14SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, pNew, orntNew);CHKERRQ(ierr); 3549412e9a14SMatthew G. Knepley } 3550412e9a14SMatthew G. Knepley } 3551412e9a14SMatthew G. Knepley } 3552412e9a14SMatthew G. Knepley ierr = PetscFree2(coneNew, orntNew);CHKERRQ(ierr); 35533f2a96e3SMatthew G. Knepley ierr = DMViewFromOptions(rdm, NULL, "-rdm_view");CHKERRQ(ierr); 3554412e9a14SMatthew G. Knepley ierr = DMPlexSymmetrize(rdm);CHKERRQ(ierr); 3555412e9a14SMatthew G. Knepley ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 3556412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3557412e9a14SMatthew G. Knepley } 3558412e9a14SMatthew G. Knepley 3559412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCoordinateFE(DMPlexCellRefiner cr, DMPolytopeType ct, PetscFE *fe) 3560412e9a14SMatthew G. Knepley { 3561412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3562412e9a14SMatthew G. Knepley 3563412e9a14SMatthew G. Knepley PetscFunctionBegin; 3564412e9a14SMatthew G. Knepley if (!cr->coordFE[ct]) { 3565412e9a14SMatthew G. Knepley PetscInt dim, cdim; 3566412e9a14SMatthew G. Knepley PetscBool isSimplex; 3567412e9a14SMatthew G. Knepley 3568412e9a14SMatthew G. Knepley switch (ct) { 3569412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: dim = 1; isSimplex = PETSC_TRUE; break; 3570412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: dim = 2; isSimplex = PETSC_TRUE; break; 3571412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: dim = 2; isSimplex = PETSC_FALSE; break; 3572412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: dim = 3; isSimplex = PETSC_TRUE; break; 3573412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: dim = 3; isSimplex = PETSC_FALSE; break; 3574412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No coordinate FE for cell type %s", DMPolytopeTypes[ct]); 3575412e9a14SMatthew G. Knepley } 3576412e9a14SMatthew G. Knepley ierr = DMGetCoordinateDim(cr->dm, &cdim);CHKERRQ(ierr); 3577412e9a14SMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, cdim, isSimplex, 1, PETSC_DETERMINE, &cr->coordFE[ct]);CHKERRQ(ierr); 3578412e9a14SMatthew G. Knepley { 3579412e9a14SMatthew G. Knepley PetscDualSpace dsp; 3580412e9a14SMatthew G. Knepley PetscQuadrature quad; 3581412e9a14SMatthew G. Knepley DM K; 3582412e9a14SMatthew G. Knepley PetscFEGeom *cg; 3583412e9a14SMatthew G. Knepley PetscReal *Xq, *xq, *wq; 3584412e9a14SMatthew G. Knepley PetscInt Nq, q; 3585412e9a14SMatthew G. Knepley 3586412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCellVertices(cr, ct, &Nq, &Xq);CHKERRQ(ierr); 3587412e9a14SMatthew G. Knepley ierr = PetscMalloc1(Nq*cdim, &xq);CHKERRQ(ierr); 3588412e9a14SMatthew G. Knepley for (q = 0; q < Nq*cdim; ++q) xq[q] = Xq[q]; 3589412e9a14SMatthew G. Knepley ierr = PetscMalloc1(Nq, &wq);CHKERRQ(ierr); 3590412e9a14SMatthew G. Knepley for (q = 0; q < Nq; ++q) wq[q] = 1.0; 3591412e9a14SMatthew G. Knepley ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &quad);CHKERRQ(ierr); 3592412e9a14SMatthew G. Knepley ierr = PetscQuadratureSetData(quad, dim, 1, Nq, xq, wq);CHKERRQ(ierr); 3593412e9a14SMatthew G. Knepley ierr = PetscFESetQuadrature(cr->coordFE[ct], quad);CHKERRQ(ierr); 3594412e9a14SMatthew G. Knepley 3595412e9a14SMatthew G. Knepley ierr = PetscFEGetDualSpace(cr->coordFE[ct], &dsp);CHKERRQ(ierr); 3596412e9a14SMatthew G. Knepley ierr = PetscDualSpaceGetDM(dsp, &K);CHKERRQ(ierr); 3597412e9a14SMatthew G. Knepley ierr = PetscFEGeomCreate(quad, 1, cdim, PETSC_FALSE, &cr->refGeom[ct]);CHKERRQ(ierr); 3598412e9a14SMatthew G. Knepley cg = cr->refGeom[ct]; 3599412e9a14SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(K, 0, NULL, cg->v, cg->J, cg->invJ, cg->detJ);CHKERRQ(ierr); 3600412e9a14SMatthew G. Knepley ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr); 3601412e9a14SMatthew G. Knepley } 3602412e9a14SMatthew G. Knepley } 3603412e9a14SMatthew G. Knepley *fe = cr->coordFE[ct]; 3604412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3605412e9a14SMatthew G. Knepley } 3606412e9a14SMatthew G. Knepley 3607412e9a14SMatthew G. Knepley /* 3608412e9a14SMatthew G. Knepley DMPlexCellRefinerMapLocalizedCoordinates - Given a cell of type ct with localized coordinates x, we generate localized coordinates xr for subcell r of type rct. 3609412e9a14SMatthew G. Knepley 3610412e9a14SMatthew G. Knepley Not collective 3611412e9a14SMatthew G. Knepley 3612412e9a14SMatthew G. Knepley Input Parameters: 3613412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner 3614412e9a14SMatthew G. Knepley . ct - The type of the parent cell 3615412e9a14SMatthew G. Knepley . rct - The type of the produced cell 3616412e9a14SMatthew G. Knepley . r - The index of the produced cell 3617412e9a14SMatthew G. Knepley - x - The localized coordinates for the parent cell 3618412e9a14SMatthew G. Knepley 3619412e9a14SMatthew G. Knepley Output Parameter: 3620412e9a14SMatthew G. Knepley . xr - The localized coordinates for the produced cell 3621412e9a14SMatthew G. Knepley 3622412e9a14SMatthew G. Knepley Level: developer 3623412e9a14SMatthew G. Knepley 3624412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerSetCoordinates() 3625412e9a14SMatthew G. Knepley */ 3626412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapLocalizedCoordinates(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, const PetscScalar x[], PetscScalar xr[]) 3627412e9a14SMatthew G. Knepley { 3628412e9a14SMatthew G. Knepley PetscFE fe = NULL; 3629412e9a14SMatthew G. Knepley PetscInt cdim, Nv, v, *subcellV; 3630412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3631412e9a14SMatthew G. Knepley 3632412e9a14SMatthew G. Knepley PetscFunctionBegin; 3633412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCoordinateFE(cr, ct, &fe);CHKERRQ(ierr); 3634412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetSubcellVertices(cr, ct, rct, r, &Nv, &subcellV);CHKERRQ(ierr); 3635412e9a14SMatthew G. Knepley ierr = PetscFEGetNumComponents(fe, &cdim);CHKERRQ(ierr); 3636412e9a14SMatthew G. Knepley for (v = 0; v < Nv; ++v) { 3637412e9a14SMatthew G. Knepley ierr = PetscFEInterpolate_Static(fe, x, cr->refGeom[ct], subcellV[v], &xr[v*cdim]);CHKERRQ(ierr); 3638412e9a14SMatthew G. Knepley } 3639412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3640412e9a14SMatthew G. Knepley } 3641412e9a14SMatthew G. Knepley 3642412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCoordinates(DMPlexCellRefiner cr, DM rdm) 3643412e9a14SMatthew G. Knepley { 3644412e9a14SMatthew G. Knepley DM dm = cr->dm, cdm; 3645412e9a14SMatthew G. Knepley PetscSection coordSection, coordSectionNew; 3646412e9a14SMatthew G. Knepley Vec coordsLocal, coordsLocalNew; 3647412e9a14SMatthew G. Knepley const PetscScalar *coords; 3648412e9a14SMatthew G. Knepley PetscScalar *coordsNew; 3649412e9a14SMatthew G. Knepley const DMBoundaryType *bd; 3650412e9a14SMatthew G. Knepley const PetscReal *maxCell, *L; 3651412e9a14SMatthew G. Knepley PetscBool isperiodic, localizeVertices = PETSC_FALSE, localizeCells = PETSC_FALSE; 3652412e9a14SMatthew G. Knepley PetscInt dE, d, cStart, cEnd, c, vStartNew, vEndNew, v, pStart, pEnd, p, ocStart, ocEnd; 3653412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3654412e9a14SMatthew G. Knepley 3655412e9a14SMatthew G. Knepley PetscFunctionBegin; 3656412e9a14SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 365790b157c4SStefano Zampini ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 365890b157c4SStefano Zampini /* Determine if we need to localize coordinates when generating them */ 3659b9ccc978SStefano Zampini if (isperiodic) { 3660412e9a14SMatthew G. Knepley localizeVertices = PETSC_TRUE; 3661412e9a14SMatthew G. Knepley if (!maxCell) { 3662412e9a14SMatthew G. Knepley PetscBool localized; 3663412e9a14SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 3664412e9a14SMatthew G. Knepley if (!localized) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Cannot refine a periodic mesh if coordinates have not been localized"); 3665412e9a14SMatthew G. Knepley localizeCells = PETSC_TRUE; 3666b9ccc978SStefano Zampini } 3667b9ccc978SStefano Zampini } 3668b9ccc978SStefano Zampini 3669b9ccc978SStefano Zampini ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 3670412e9a14SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &dE);CHKERRQ(ierr); 3671412e9a14SMatthew G. Knepley if (maxCell) { 3672412e9a14SMatthew G. Knepley PetscReal maxCellNew[3]; 3673412e9a14SMatthew G. Knepley 3674412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) maxCellNew[d] = maxCell[d]/2.0; 3675412e9a14SMatthew G. Knepley ierr = DMSetPeriodicity(rdm, isperiodic, maxCellNew, L, bd);CHKERRQ(ierr); 3676412e9a14SMatthew G. Knepley } else { 3677412e9a14SMatthew G. Knepley ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 3678412e9a14SMatthew G. Knepley } 3679b9ccc978SStefano Zampini ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &coordSectionNew);CHKERRQ(ierr); 3680b9ccc978SStefano Zampini ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 3681412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dE);CHKERRQ(ierr); 3682412e9a14SMatthew G. Knepley ierr = DMPlexGetDepthStratum(rdm, 0, &vStartNew, &vEndNew);CHKERRQ(ierr); 3683412e9a14SMatthew G. Knepley if (localizeCells) {ierr = PetscSectionSetChart(coordSectionNew, 0, vEndNew);CHKERRQ(ierr);} 3684412e9a14SMatthew G. Knepley else {ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vEndNew);CHKERRQ(ierr);} 3685b9ccc978SStefano Zampini 3686412e9a14SMatthew G. Knepley /* Localization should be inherited */ 3687412e9a14SMatthew G. Knepley /* Stefano calculates parent cells for each new cell for localization */ 3688412e9a14SMatthew G. Knepley /* Localized cells need coordinates of closure */ 3689412e9a14SMatthew G. Knepley for (v = vStartNew; v < vEndNew; ++v) { 3690412e9a14SMatthew G. Knepley ierr = PetscSectionSetDof(coordSectionNew, v, dE);CHKERRQ(ierr); 3691412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dE);CHKERRQ(ierr); 3692412e9a14SMatthew G. Knepley } 3693412e9a14SMatthew G. Knepley if (localizeCells) { 3694412e9a14SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 3695412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 3696412e9a14SMatthew G. Knepley PetscInt dof; 369790b157c4SStefano Zampini 3698412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr); 3699412e9a14SMatthew G. Knepley if (dof) { 3700412e9a14SMatthew G. Knepley DMPolytopeType ct; 3701412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3702412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 3703412e9a14SMatthew G. Knepley PetscInt dim, cNew, Nct, n, r; 370490b157c4SStefano Zampini 3705412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 3706412e9a14SMatthew G. Knepley dim = DMPolytopeTypeGetDim(ct); 37073f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, c, NULL, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 3708412e9a14SMatthew G. Knepley /* This allows for different cell types */ 3709412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 3710412e9a14SMatthew G. Knepley if (dim != DMPolytopeTypeGetDim(rct[n])) continue; 3711412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 3712412e9a14SMatthew G. Knepley PetscInt *closure = NULL; 3713412e9a14SMatthew G. Knepley PetscInt clSize, cl, Nv = 0; 371490b157c4SStefano Zampini 3715412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], c, r, &cNew);CHKERRQ(ierr); 3716412e9a14SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 3717412e9a14SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) {if ((closure[cl] >= vStartNew) && (closure[cl] < vEndNew)) ++Nv;} 3718412e9a14SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 3719412e9a14SMatthew G. Knepley ierr = PetscSectionSetDof(coordSectionNew, cNew, Nv * dE);CHKERRQ(ierr); 3720412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSectionNew, cNew, 0, Nv * dE);CHKERRQ(ierr); 37219fc2a3f3SStefano Zampini } 372290b157c4SStefano Zampini } 372390b157c4SStefano Zampini } 3724412e9a14SMatthew G. Knepley } 372575d3a19aSMatthew G. Knepley } 372675d3a19aSMatthew G. Knepley ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 3727412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-coarse_dm_view");CHKERRQ(ierr); 372846e270d4SMatthew G. Knepley ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 3729412e9a14SMatthew G. Knepley { 3730412e9a14SMatthew G. Knepley VecType vtype; 3731412e9a14SMatthew G. Knepley PetscInt coordSizeNew, bs; 3732412e9a14SMatthew G. Knepley const char *name; 3733412e9a14SMatthew G. Knepley 3734412e9a14SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); 3735412e9a14SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordsLocalNew);CHKERRQ(ierr); 373675d3a19aSMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 3737412e9a14SMatthew G. Knepley ierr = VecSetSizes(coordsLocalNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 3738412e9a14SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) coordsLocal, &name);CHKERRQ(ierr); 3739412e9a14SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordsLocalNew, name);CHKERRQ(ierr); 3740412e9a14SMatthew G. Knepley ierr = VecGetBlockSize(coordsLocal, &bs);CHKERRQ(ierr); 3741412e9a14SMatthew G. Knepley ierr = VecSetBlockSize(coordsLocalNew, bs);CHKERRQ(ierr); 3742412e9a14SMatthew G. Knepley ierr = VecGetType(coordsLocal, &vtype);CHKERRQ(ierr); 3743412e9a14SMatthew G. Knepley ierr = VecSetType(coordsLocalNew, vtype);CHKERRQ(ierr); 3744b5da9499SMatthew G. Knepley } 3745412e9a14SMatthew G. Knepley ierr = VecGetArrayRead(coordsLocal, &coords);CHKERRQ(ierr); 3746412e9a14SMatthew G. Knepley ierr = VecGetArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr); 3747412e9a14SMatthew G. Knepley ierr = PetscSectionGetChart(coordSection, &ocStart, &ocEnd);CHKERRQ(ierr); 3748412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3749412e9a14SMatthew G. Knepley /* First set coordinates for vertices*/ 3750412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3751412e9a14SMatthew G. Knepley DMPolytopeType ct; 3752412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3753412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 3754412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 3755412e9a14SMatthew G. Knepley PetscBool hasVertex = PETSC_FALSE, isLocalized = PETSC_FALSE; 375690b157c4SStefano Zampini 3757412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 37583f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 3759412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 3760412e9a14SMatthew G. Knepley if (rct[n] == DM_POLYTOPE_POINT) {hasVertex = PETSC_TRUE; break;} 3761412e9a14SMatthew G. Knepley } 3762412e9a14SMatthew G. Knepley if (localizeVertices && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) { 3763412e9a14SMatthew G. Knepley PetscInt dof; 3764412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, p, &dof);CHKERRQ(ierr); 3765412e9a14SMatthew G. Knepley if (dof) isLocalized = PETSC_TRUE; 3766412e9a14SMatthew G. Knepley } 3767412e9a14SMatthew G. Knepley if (hasVertex) { 3768a5801f52SStefano Zampini const PetscScalar *icoords = NULL; 3769412e9a14SMatthew G. Knepley PetscScalar *pcoords = NULL; 3770412e9a14SMatthew G. Knepley PetscInt Nc, Nv, v, d; 377190b157c4SStefano Zampini 3772412e9a14SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr); 3773a5801f52SStefano Zampini 3774a5801f52SStefano Zampini icoords = pcoords; 3775a5801f52SStefano Zampini Nv = Nc/dE; 3776a5801f52SStefano Zampini if (ct != DM_POLYTOPE_POINT) { 3777412e9a14SMatthew G. Knepley if (localizeVertices) { 3778412e9a14SMatthew G. Knepley PetscScalar anchor[3]; 377990b157c4SStefano Zampini 3780412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) anchor[d] = pcoords[d]; 3781412e9a14SMatthew G. Knepley if (!isLocalized) { 3782a5801f52SStefano Zampini for (v = 0; v < Nv; ++v) {ierr = DMLocalizeCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], &pcoords[v*dE]);CHKERRQ(ierr);} 3783412e9a14SMatthew G. Knepley } else { 3784412e9a14SMatthew G. Knepley Nv = Nc/(2*dE); 3785a5801f52SStefano Zampini icoords = pcoords + Nv*dE; 3786a5801f52SStefano Zampini for (v = Nv; v < Nv*2; ++v) {ierr = DMLocalizeCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], &pcoords[v*dE]);CHKERRQ(ierr);} 378790b157c4SStefano Zampini } 3788b5da9499SMatthew G. Knepley } 378990b157c4SStefano Zampini } 3790412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 3791412e9a14SMatthew G. Knepley if (rct[n] != DM_POLYTOPE_POINT) continue; 3792412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 3793a5801f52SStefano Zampini PetscScalar vcoords[3]; 3794412e9a14SMatthew G. Knepley PetscInt vNew, off; 3795b5da9499SMatthew G. Knepley 3796412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &vNew);CHKERRQ(ierr); 3797412e9a14SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, vNew, &off);CHKERRQ(ierr); 3798a5801f52SStefano Zampini ierr = DMPlexCellRefinerMapCoordinates(cr, ct, rct[n], r, Nv, dE, icoords, vcoords);CHKERRQ(ierr); 3799eac51794SMatthew G. Knepley ierr = DMPlexSnapToGeomModel(dm, p, vcoords, &coordsNew[off]);CHKERRQ(ierr); 3800b5da9499SMatthew G. Knepley } 38019fc2a3f3SStefano Zampini } 3802a5801f52SStefano Zampini ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr); 3803412e9a14SMatthew G. Knepley } 3804412e9a14SMatthew G. Knepley } 3805412e9a14SMatthew G. Knepley /* Then set coordinates for cells by localizing */ 3806412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3807412e9a14SMatthew G. Knepley DMPolytopeType ct; 3808412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3809412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 3810412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 3811412e9a14SMatthew G. Knepley PetscBool isLocalized = PETSC_FALSE; 381290b157c4SStefano Zampini 3813412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 38143f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 3815412e9a14SMatthew G. Knepley if (localizeCells && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) { 3816412e9a14SMatthew G. Knepley PetscInt dof; 3817412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, p, &dof);CHKERRQ(ierr); 3818412e9a14SMatthew G. Knepley if (dof) isLocalized = PETSC_TRUE; 3819b5da9499SMatthew G. Knepley } 3820412e9a14SMatthew G. Knepley if (isLocalized) { 3821412e9a14SMatthew G. Knepley const PetscScalar *pcoords; 38229fc2a3f3SStefano Zampini 3823412e9a14SMatthew G. Knepley ierr = DMPlexPointLocalRead(cdm, p, coords, &pcoords);CHKERRQ(ierr); 3824412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 3825412e9a14SMatthew G. Knepley const PetscInt Nr = rsize[n]; 382690b157c4SStefano Zampini 3827412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ct) != DMPolytopeTypeGetDim(rct[n])) continue; 3828412e9a14SMatthew G. Knepley for (r = 0; r < Nr; ++r) { 3829412e9a14SMatthew G. Knepley PetscInt pNew, offNew; 383090b157c4SStefano Zampini 3831412e9a14SMatthew G. Knepley /* It looks like Stefano and Lisandro are allowing localized coordinates without defining the periodic boundary, which means that 3832412e9a14SMatthew G. Knepley DMLocalizeCoordinate_Internal() will not work. Localized coordinates will have to have obtained by the affine map of the larger 3833412e9a14SMatthew G. Knepley cell to the ones it produces. */ 3834412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 3835412e9a14SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, pNew, &offNew);CHKERRQ(ierr); 3836412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapLocalizedCoordinates(cr, ct, rct[n], r, pcoords, &coordsNew[offNew]);CHKERRQ(ierr); 383790b157c4SStefano Zampini } 383890b157c4SStefano Zampini } 383990b157c4SStefano Zampini } 384090b157c4SStefano Zampini } 3841412e9a14SMatthew G. Knepley ierr = VecRestoreArrayRead(coordsLocal, &coords);CHKERRQ(ierr); 3842412e9a14SMatthew G. Knepley ierr = VecRestoreArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr); 3843412e9a14SMatthew G. Knepley ierr = DMSetCoordinatesLocal(rdm, coordsLocalNew);CHKERRQ(ierr); 3844412e9a14SMatthew G. Knepley /* TODO Stefano has a final reduction if some hybrid coordinates cannot be found. (needcoords) Should not be needed. */ 3845412e9a14SMatthew G. Knepley ierr = VecDestroy(&coordsLocalNew);CHKERRQ(ierr); 384675d3a19aSMatthew G. Knepley ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 3847412e9a14SMatthew G. Knepley if (!localizeCells) {ierr = DMLocalizeCoordinates(rdm);CHKERRQ(ierr);} 384875d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 384975d3a19aSMatthew G. Knepley } 385075d3a19aSMatthew G. Knepley 3851963fc26aSMatthew G. Knepley /*@ 3852963fc26aSMatthew G. Knepley DMPlexCreateProcessSF - Create an SF which just has process connectivity 3853963fc26aSMatthew G. Knepley 3854d083f849SBarry Smith Collective on dm 3855963fc26aSMatthew G. Knepley 3856963fc26aSMatthew G. Knepley Input Parameters: 3857963fc26aSMatthew G. Knepley + dm - The DM 3858963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity 3859963fc26aSMatthew G. Knepley 3860963fc26aSMatthew G. Knepley Output Parameters: 3861963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL 3862963fc26aSMatthew G. Knepley - sfProcess - An SF encoding the process connectivity, or NULL 3863963fc26aSMatthew G. Knepley 3864963fc26aSMatthew G. Knepley Level: developer 3865963fc26aSMatthew G. Knepley 3866963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 3867963fc26aSMatthew G. Knepley @*/ 3868963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 386975d3a19aSMatthew G. Knepley { 387075d3a19aSMatthew G. Knepley PetscInt numRoots, numLeaves, l; 387175d3a19aSMatthew G. Knepley const PetscInt *localPoints; 387275d3a19aSMatthew G. Knepley const PetscSFNode *remotePoints; 387375d3a19aSMatthew G. Knepley PetscInt *localPointsNew; 387475d3a19aSMatthew G. Knepley PetscSFNode *remotePointsNew; 387575d3a19aSMatthew G. Knepley PetscInt *ranks, *ranksNew; 38769852e123SBarry Smith PetscMPIInt size; 387775d3a19aSMatthew G. Knepley PetscErrorCode ierr; 387875d3a19aSMatthew G. Knepley 387975d3a19aSMatthew G. Knepley PetscFunctionBegin; 3880963fc26aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3881963fc26aSMatthew G. Knepley PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 3882963fc26aSMatthew G. Knepley if (processRanks) {PetscValidPointer(processRanks, 3);} 3883963fc26aSMatthew G. Knepley if (sfProcess) {PetscValidPointer(sfProcess, 4);} 38849852e123SBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 388575d3a19aSMatthew G. Knepley ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 3886785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 388775d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 388875d3a19aSMatthew G. Knepley ranks[l] = remotePoints[l].rank; 388975d3a19aSMatthew G. Knepley } 389075d3a19aSMatthew G. Knepley ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 3891785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 3892785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 3893785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 389475d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 389575d3a19aSMatthew G. Knepley ranksNew[l] = ranks[l]; 389675d3a19aSMatthew G. Knepley localPointsNew[l] = l; 389775d3a19aSMatthew G. Knepley remotePointsNew[l].index = 0; 389875d3a19aSMatthew G. Knepley remotePointsNew[l].rank = ranksNew[l]; 389975d3a19aSMatthew G. Knepley } 390075d3a19aSMatthew G. Knepley ierr = PetscFree(ranks);CHKERRQ(ierr); 3901963fc26aSMatthew G. Knepley if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 3902963fc26aSMatthew G. Knepley else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 3903963fc26aSMatthew G. Knepley if (sfProcess) { 390475d3a19aSMatthew G. Knepley ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 3905963fc26aSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 390675d3a19aSMatthew G. Knepley ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 39079852e123SBarry Smith ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 3908963fc26aSMatthew G. Knepley } 390975d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 391075d3a19aSMatthew G. Knepley } 391175d3a19aSMatthew G. Knepley 3912412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateSF(DMPlexCellRefiner cr, DM rdm) 391375d3a19aSMatthew G. Knepley { 3914412e9a14SMatthew G. Knepley DM dm = cr->dm; 3915412e9a14SMatthew G. Knepley DMPlexCellRefiner *crRem; 391675d3a19aSMatthew G. Knepley PetscSF sf, sfNew, sfProcess; 391775d3a19aSMatthew G. Knepley IS processRanks; 3918412e9a14SMatthew G. Knepley MPI_Datatype ctType; 391975d3a19aSMatthew G. Knepley PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 392075d3a19aSMatthew G. Knepley const PetscInt *localPoints, *neighbors; 392175d3a19aSMatthew G. Knepley const PetscSFNode *remotePoints; 392275d3a19aSMatthew G. Knepley PetscInt *localPointsNew; 392375d3a19aSMatthew G. Knepley PetscSFNode *remotePointsNew; 3924412e9a14SMatthew G. Knepley PetscInt *ctStartRem, *ctStartNewRem; 3925412e9a14SMatthew G. Knepley PetscInt ctSize = DM_NUM_POLYTOPES+1, numNeighbors, n, pStartNew, pEndNew, pNew, pNewRem; 39263f2a96e3SMatthew G. Knepley /* Brute force algorithm */ 39273f2a96e3SMatthew G. Knepley PetscSF rsf; 39283f2a96e3SMatthew G. Knepley PetscSection s; 39293f2a96e3SMatthew G. Knepley const PetscInt *rootdegree; 39303f2a96e3SMatthew G. Knepley PetscInt *rootPointsNew, *remoteOffsets; 39313f2a96e3SMatthew G. Knepley PetscInt numPointsNew, pStart, pEnd, p; 393275d3a19aSMatthew G. Knepley PetscErrorCode ierr; 393375d3a19aSMatthew G. Knepley 393475d3a19aSMatthew G. Knepley PetscFunctionBegin; 393575d3a19aSMatthew G. Knepley ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 393675d3a19aSMatthew G. Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 393775d3a19aSMatthew G. Knepley ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 3938add09238SMatthew G. Knepley /* Calculate size of new SF */ 393975d3a19aSMatthew G. Knepley ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 394075d3a19aSMatthew G. Knepley if (numRoots < 0) PetscFunctionReturn(0); 394175d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 394275d3a19aSMatthew G. Knepley const PetscInt p = localPoints[l]; 3943412e9a14SMatthew G. Knepley DMPolytopeType ct; 3944412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3945412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 3946412e9a14SMatthew G. Knepley PetscInt Nct, n; 394775d3a19aSMatthew G. Knepley 3948412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 39493f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 39503f2a96e3SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 39513f2a96e3SMatthew G. Knepley numLeavesNew += rsize[n]; 39520314a74cSLawrence Mitchell } 39533f2a96e3SMatthew G. Knepley } 39543f2a96e3SMatthew G. Knepley if (cr->refineType) { 39553f2a96e3SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 39563f2a96e3SMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &s);CHKERRQ(ierr); 39573f2a96e3SMatthew G. Knepley ierr = PetscSectionSetChart(s, pStart, pEnd);CHKERRQ(ierr); 39583f2a96e3SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 39593f2a96e3SMatthew G. Knepley DMPolytopeType ct; 39603f2a96e3SMatthew G. Knepley DMPolytopeType *rct; 39613f2a96e3SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 39623f2a96e3SMatthew G. Knepley PetscInt Nct, n; 39633f2a96e3SMatthew G. Knepley 39643f2a96e3SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 39653f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 39663f2a96e3SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 39673f2a96e3SMatthew G. Knepley ierr = PetscSectionAddDof(s, p, rsize[n]);CHKERRQ(ierr); 39683f2a96e3SMatthew G. Knepley } 39693f2a96e3SMatthew G. Knepley } 39703f2a96e3SMatthew G. Knepley ierr = PetscSectionSetUp(s);CHKERRQ(ierr); 39713f2a96e3SMatthew G. Knepley ierr = PetscSectionGetStorageSize(s, &numPointsNew);CHKERRQ(ierr); 39723f2a96e3SMatthew G. Knepley ierr = PetscSFCreateRemoteOffsets(sf, s, s, &remoteOffsets);CHKERRQ(ierr); 39733f2a96e3SMatthew G. Knepley ierr = PetscSFCreateSectionSF(sf, s, remoteOffsets, s, &rsf);CHKERRQ(ierr); 39743f2a96e3SMatthew G. Knepley ierr = PetscFree(remoteOffsets);CHKERRQ(ierr); 39753f2a96e3SMatthew G. Knepley ierr = PetscSFComputeDegreeBegin(sf, &rootdegree);CHKERRQ(ierr); 39763f2a96e3SMatthew G. Knepley ierr = PetscSFComputeDegreeEnd(sf, &rootdegree);CHKERRQ(ierr); 39773f2a96e3SMatthew G. Knepley ierr = PetscMalloc1(numPointsNew, &rootPointsNew);CHKERRQ(ierr); 39783f2a96e3SMatthew G. Knepley for (p = 0; p < numPointsNew; ++p) rootPointsNew[p] = -1; 39793f2a96e3SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 39803f2a96e3SMatthew G. Knepley DMPolytopeType ct; 39813f2a96e3SMatthew G. Knepley DMPolytopeType *rct; 39823f2a96e3SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 39833f2a96e3SMatthew G. Knepley PetscInt Nct, n, r, off; 39843f2a96e3SMatthew G. Knepley 39853f2a96e3SMatthew G. Knepley if (!rootdegree[p-pStart]) continue; 39863f2a96e3SMatthew G. Knepley ierr = PetscSectionGetOffset(s, p, &off);CHKERRQ(ierr); 39873f2a96e3SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 39883f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 39893f2a96e3SMatthew G. Knepley for (n = 0, m = 0; n < Nct; ++n) { 39903f2a96e3SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r, ++m) { 39913f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 39923f2a96e3SMatthew G. Knepley rootPointsNew[off+m] = pNew; 39933f2a96e3SMatthew G. Knepley } 39943f2a96e3SMatthew G. Knepley } 39953f2a96e3SMatthew G. Knepley } 39963f2a96e3SMatthew G. Knepley ierr = PetscSFBcastBegin(rsf, MPIU_INT, rootPointsNew, rootPointsNew);CHKERRQ(ierr); 39973f2a96e3SMatthew G. Knepley ierr = PetscSFBcastEnd(rsf, MPIU_INT, rootPointsNew, rootPointsNew);CHKERRQ(ierr); 39983f2a96e3SMatthew G. Knepley ierr = PetscSFDestroy(&rsf);CHKERRQ(ierr); 39993f2a96e3SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 40003f2a96e3SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 40013f2a96e3SMatthew G. Knepley for (l = 0, m = 0; l < numLeaves; ++l) { 40023f2a96e3SMatthew G. Knepley const PetscInt p = localPoints[l]; 40033f2a96e3SMatthew G. Knepley DMPolytopeType ct; 40043f2a96e3SMatthew G. Knepley DMPolytopeType *rct; 40053f2a96e3SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 40063f2a96e3SMatthew G. Knepley PetscInt Nct, n, r, q, off; 40073f2a96e3SMatthew G. Knepley 40083f2a96e3SMatthew G. Knepley ierr = PetscSectionGetOffset(s, p, &off);CHKERRQ(ierr); 40093f2a96e3SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 40103f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 40113f2a96e3SMatthew G. Knepley for (n = 0, q = 0; n < Nct; ++n) { 40123f2a96e3SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r, ++m, ++q) { 40133f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 40143f2a96e3SMatthew G. Knepley localPointsNew[m] = pNew; 40153f2a96e3SMatthew G. Knepley remotePointsNew[m].index = rootPointsNew[off+q]; 40163f2a96e3SMatthew G. Knepley remotePointsNew[m].rank = remotePoints[l].rank; 40173f2a96e3SMatthew G. Knepley } 40183f2a96e3SMatthew G. Knepley } 40193f2a96e3SMatthew G. Knepley } 40203f2a96e3SMatthew G. Knepley ierr = PetscSectionDestroy(&s);CHKERRQ(ierr); 40213f2a96e3SMatthew G. Knepley ierr = PetscFree(rootPointsNew);CHKERRQ(ierr); 40223f2a96e3SMatthew G. Knepley } else { 4023412e9a14SMatthew G. Knepley /* Communicate ctStart and cStartNew for each remote rank */ 402475d3a19aSMatthew G. Knepley ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 402575d3a19aSMatthew G. Knepley ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 4026412e9a14SMatthew G. Knepley ierr = PetscMalloc2(ctSize*numNeighbors, &ctStartRem, ctSize*numNeighbors, &ctStartNewRem);CHKERRQ(ierr); 4027412e9a14SMatthew G. Knepley ierr = MPI_Type_contiguous(ctSize, MPIU_INT, &ctType);CHKERRQ(ierr); 4028412e9a14SMatthew G. Knepley ierr = MPI_Type_commit(&ctType);CHKERRQ(ierr); 4029412e9a14SMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr); 4030412e9a14SMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr); 4031412e9a14SMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr); 4032412e9a14SMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr); 4033412e9a14SMatthew G. Knepley ierr = MPI_Type_free(&ctType);CHKERRQ(ierr); 403475d3a19aSMatthew G. Knepley ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 4035412e9a14SMatthew G. Knepley ierr = PetscMalloc1(numNeighbors, &crRem);CHKERRQ(ierr); 4036412e9a14SMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) { 4037412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &crRem[n]);CHKERRQ(ierr); 4038412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetStarts(crRem[n], &ctStartRem[n*ctSize], &ctStartNewRem[n*ctSize]); 4039412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(crRem[n]);CHKERRQ(ierr); 4040412e9a14SMatthew G. Knepley } 4041412e9a14SMatthew G. Knepley ierr = PetscFree2(ctStartRem, ctStartNewRem);CHKERRQ(ierr); 404275d3a19aSMatthew G. Knepley /* Calculate new point SF */ 4043785e854fSJed Brown ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 4044785e854fSJed Brown ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 404575d3a19aSMatthew G. Knepley ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 404675d3a19aSMatthew G. Knepley for (l = 0, m = 0; l < numLeaves; ++l) { 404775d3a19aSMatthew G. Knepley PetscInt p = localPoints[l]; 4048412e9a14SMatthew G. Knepley PetscInt pRem = remotePoints[l].index; 4049412e9a14SMatthew G. Knepley PetscMPIInt rankRem = remotePoints[l].rank; 4050412e9a14SMatthew G. Knepley DMPolytopeType ct; 4051412e9a14SMatthew G. Knepley DMPolytopeType *rct; 4052412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 4053412e9a14SMatthew G. Knepley PetscInt neighbor, Nct, n, r; 405475d3a19aSMatthew G. Knepley 4055412e9a14SMatthew G. Knepley ierr = PetscFindInt(rankRem, numNeighbors, neighbors, &neighbor);CHKERRQ(ierr); 4056412e9a14SMatthew G. Knepley if (neighbor < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rankRem); 4057412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 40583f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 4059412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 4060412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 4061412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 4062412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(crRem[neighbor], ct, rct[n], pRem, r, &pNewRem);CHKERRQ(ierr); 4063412e9a14SMatthew G. Knepley localPointsNew[m] = pNew; 4064412e9a14SMatthew G. Knepley remotePointsNew[m].index = pNewRem; 4065412e9a14SMatthew G. Knepley remotePointsNew[m].rank = rankRem; 40660314a74cSLawrence Mitchell ++m; 40670314a74cSLawrence Mitchell } 40686ce3c06aSMatthew G. Knepley } 40696ce3c06aSMatthew G. Knepley } 4070412e9a14SMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) {ierr = DMPlexCellRefinerDestroy(&crRem[n]);CHKERRQ(ierr);} 4071412e9a14SMatthew G. Knepley ierr = PetscFree(crRem);CHKERRQ(ierr); 4072d7eabd03SStefano Zampini if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew); 407375d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 407475d3a19aSMatthew G. Knepley ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 40753f2a96e3SMatthew G. Knepley } 4076ba3c3d50SMatthew G. Knepley { 4077ba3c3d50SMatthew G. Knepley PetscSFNode *rp, *rtmp; 4078ba3c3d50SMatthew G. Knepley PetscInt *lp, *idx, *ltmp, i; 4079ba3c3d50SMatthew G. Knepley 4080ba3c3d50SMatthew G. Knepley /* SF needs sorted leaves to correct calculate Gather */ 4081ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &idx);CHKERRQ(ierr); 4082ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 4083ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 4084c7c54c77SMatthew G. Knepley for (i = 0; i < numLeavesNew; ++i) { 4085d7eabd03SStefano 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); 4086c7c54c77SMatthew G. Knepley idx[i] = i; 4087c7c54c77SMatthew G. Knepley } 4088ba3c3d50SMatthew G. Knepley ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 4089ba3c3d50SMatthew G. Knepley for (i = 0; i < numLeavesNew; ++i) { 4090ba3c3d50SMatthew G. Knepley lp[i] = localPointsNew[idx[i]]; 4091ba3c3d50SMatthew G. Knepley rp[i] = remotePointsNew[idx[i]]; 4092ba3c3d50SMatthew G. Knepley } 4093ba3c3d50SMatthew G. Knepley ltmp = localPointsNew; 4094ba3c3d50SMatthew G. Knepley localPointsNew = lp; 4095ba3c3d50SMatthew G. Knepley rtmp = remotePointsNew; 4096ba3c3d50SMatthew G. Knepley remotePointsNew = rp; 4097ba3c3d50SMatthew G. Knepley ierr = PetscFree(idx);CHKERRQ(ierr); 4098ba3c3d50SMatthew G. Knepley ierr = PetscFree(ltmp);CHKERRQ(ierr); 4099ba3c3d50SMatthew G. Knepley ierr = PetscFree(rtmp);CHKERRQ(ierr); 4100ba3c3d50SMatthew G. Knepley } 410175d3a19aSMatthew G. Knepley ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 410275d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 410375d3a19aSMatthew G. Knepley } 410475d3a19aSMatthew G. Knepley 4105e7887635SMatthew G. Knepley static PetscErrorCode RefineLabel_Internal(DMPlexCellRefiner cr, DMLabel label, DMLabel labelNew) 410675d3a19aSMatthew G. Knepley { 4107412e9a14SMatthew G. Knepley DM dm = cr->dm; 4108e7887635SMatthew G. Knepley IS valueIS; 4109e7887635SMatthew G. Knepley const PetscInt *values; 4110e7887635SMatthew G. Knepley PetscInt defVal, Nv, val; 411175d3a19aSMatthew G. Knepley PetscErrorCode ierr; 411275d3a19aSMatthew G. Knepley 411375d3a19aSMatthew G. Knepley PetscFunctionBegin; 41145aa44df4SToby Isaac ierr = DMLabelGetDefaultValue(label, &defVal);CHKERRQ(ierr); 41155aa44df4SToby Isaac ierr = DMLabelSetDefaultValue(labelNew, defVal);CHKERRQ(ierr); 411675d3a19aSMatthew G. Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 4117e7887635SMatthew G. Knepley ierr = ISGetLocalSize(valueIS, &Nv);CHKERRQ(ierr); 411875d3a19aSMatthew G. Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 4119e7887635SMatthew G. Knepley for (val = 0; val < Nv; ++val) { 412075d3a19aSMatthew G. Knepley IS pointIS; 412175d3a19aSMatthew G. Knepley const PetscInt *points; 4122412e9a14SMatthew G. Knepley PetscInt numPoints, p; 412375d3a19aSMatthew G. Knepley 41242bc5314cSMichael Lange /* Ensure refined label is created with same number of strata as 41252bc5314cSMichael Lange * original (even if no entries here). */ 4126ad8374ffSToby Isaac ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 4127412e9a14SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 4128412e9a14SMatthew G. Knepley ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 4129412e9a14SMatthew G. Knepley ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 4130412e9a14SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 4131412e9a14SMatthew G. Knepley const PetscInt point = points[p]; 4132412e9a14SMatthew G. Knepley DMPolytopeType ct; 4133412e9a14SMatthew G. Knepley DMPolytopeType *rct; 4134412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 4135e7887635SMatthew G. Knepley PetscInt Nct, n, r, pNew; 4136412e9a14SMatthew G. Knepley 4137412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, point, &ct);CHKERRQ(ierr); 41383f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, point, NULL, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 4139412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 4140412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 4141412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], point, r, &pNew);CHKERRQ(ierr); 4142412e9a14SMatthew G. Knepley ierr = DMLabelSetValue(labelNew, pNew, values[val]);CHKERRQ(ierr); 414327fcede3SMatthew G. Knepley } 414475d3a19aSMatthew G. Knepley } 414575d3a19aSMatthew G. Knepley } 414675d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 414775d3a19aSMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 414875d3a19aSMatthew G. Knepley } 414975d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 415075d3a19aSMatthew G. Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 4151e7887635SMatthew G. Knepley PetscFunctionReturn(0); 4152e7887635SMatthew G. Knepley } 4153e7887635SMatthew G. Knepley 4154e7887635SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateLabels(DMPlexCellRefiner cr, DM rdm) 4155e7887635SMatthew G. Knepley { 4156e7887635SMatthew G. Knepley DM dm = cr->dm; 4157e7887635SMatthew G. Knepley PetscInt numLabels, l; 4158e7887635SMatthew G. Knepley PetscErrorCode ierr; 4159e7887635SMatthew G. Knepley 4160e7887635SMatthew G. Knepley PetscFunctionBegin; 4161e7887635SMatthew G. Knepley ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 4162e7887635SMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 4163e7887635SMatthew G. Knepley DMLabel label, labelNew; 4164e7887635SMatthew G. Knepley const char *lname; 4165e7887635SMatthew G. Knepley PetscBool isDepth, isCellType; 4166e7887635SMatthew G. Knepley 4167e7887635SMatthew G. Knepley ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 4168e7887635SMatthew G. Knepley ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 4169e7887635SMatthew G. Knepley if (isDepth) continue; 4170e7887635SMatthew G. Knepley ierr = PetscStrcmp(lname, "celltype", &isCellType);CHKERRQ(ierr); 4171e7887635SMatthew G. Knepley if (isCellType) continue; 4172e7887635SMatthew G. Knepley ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 4173e7887635SMatthew G. Knepley ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 4174e7887635SMatthew G. Knepley ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 4175e7887635SMatthew G. Knepley ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr); 417675d3a19aSMatthew G. Knepley } 417775d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 417875d3a19aSMatthew G. Knepley } 417975d3a19aSMatthew G. Knepley 418075d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */ 4181412e9a14SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform(DM dm, DMPlexCellRefiner cr, DM *dmRefined) 418275d3a19aSMatthew G. Knepley { 418375d3a19aSMatthew G. Knepley DM rdm; 4184412e9a14SMatthew G. Knepley PetscInt dim, embedDim, depth; 418575d3a19aSMatthew G. Knepley PetscErrorCode ierr; 418675d3a19aSMatthew G. Knepley 418775d3a19aSMatthew G. Knepley PetscFunctionBegin; 4188412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 418975d3a19aSMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 419075d3a19aSMatthew G. Knepley ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 4191c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 4192c73cfb54SMatthew G. Knepley ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 41936dcbd917SStefano Zampini ierr = DMGetCoordinateDim(dm, &embedDim);CHKERRQ(ierr); 41946dcbd917SStefano Zampini ierr = DMSetCoordinateDim(rdm, embedDim);CHKERRQ(ierr); 419575d3a19aSMatthew G. Knepley /* Calculate number of new points of each depth */ 419675d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 41971e573d11SMatthew G. Knepley if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 419875d3a19aSMatthew G. Knepley /* Step 1: Set chart */ 4199412e9a14SMatthew G. Knepley ierr = DMPlexSetChart(rdm, 0, cr->ctStartNew[cr->ctOrder[DM_NUM_POLYTOPES]]);CHKERRQ(ierr); 42006d7373e8SToby Isaac /* Step 2: Set cone/support sizes (automatically stratifies) */ 4201412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetConeSizes(cr, rdm);CHKERRQ(ierr); 420275d3a19aSMatthew G. Knepley /* Step 3: Setup refined DM */ 420375d3a19aSMatthew G. Knepley ierr = DMSetUp(rdm);CHKERRQ(ierr); 42046d7373e8SToby Isaac /* Step 4: Set cones and supports (automatically symmetrizes) */ 4205412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetCones(cr, rdm);CHKERRQ(ierr); 42066d7373e8SToby Isaac /* Step 5: Create pointSF */ 4207412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreateSF(cr, rdm);CHKERRQ(ierr); 42086d7373e8SToby Isaac /* Step 6: Create labels */ 4209412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreateLabels(cr, rdm);CHKERRQ(ierr); 42106d7373e8SToby Isaac /* Step 7: Set coordinates */ 4211412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetCoordinates(cr, rdm);CHKERRQ(ierr); 421275d3a19aSMatthew G. Knepley *dmRefined = rdm; 421375d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 421475d3a19aSMatthew G. Knepley } 421575d3a19aSMatthew G. Knepley 42162389894bSMatthew G. Knepley /*@ 42172389894bSMatthew G. Knepley DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 42182389894bSMatthew G. Knepley 42192389894bSMatthew G. Knepley Input Parameter: 42202389894bSMatthew G. Knepley . dm - The coarse DM 42212389894bSMatthew G. Knepley 42222389894bSMatthew G. Knepley Output Parameter: 42232389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh 42242389894bSMatthew G. Knepley 42252389894bSMatthew G. Knepley Level: developer 42262389894bSMatthew G. Knepley 422797d8846cSMatthew Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetSubpointIS() 42282389894bSMatthew G. Knepley @*/ 42292389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 42302389894bSMatthew G. Knepley { 4231412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 4232412e9a14SMatthew G. Knepley PetscInt *fpoints; 4233327c2912SStefano Zampini PetscInt pStart, pEnd, p, vStart, vEnd, v; 42342389894bSMatthew G. Knepley PetscErrorCode ierr; 42352389894bSMatthew G. Knepley 42362389894bSMatthew G. Knepley PetscFunctionBegin; 42372389894bSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 42382389894bSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 4239412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr); 4240412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 42412389894bSMatthew G. Knepley ierr = PetscMalloc1(pEnd-pStart, &fpoints);CHKERRQ(ierr); 42422389894bSMatthew G. Knepley for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 4243412e9a14SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 4244327c2912SStefano Zampini PetscInt vNew = -1; /* silent overzelous may be used uninitialized */ 4245327c2912SStefano Zampini 4246412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, DM_POLYTOPE_POINT, DM_POLYTOPE_POINT, p, 0, &vNew);CHKERRQ(ierr); 4247412e9a14SMatthew G. Knepley fpoints[v-pStart] = vNew; 42482389894bSMatthew G. Knepley } 4249412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 42502389894bSMatthew G. Knepley ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 42512389894bSMatthew G. Knepley PetscFunctionReturn(0); 42522389894bSMatthew G. Knepley } 42532389894bSMatthew G. Knepley 42540e2b6761SMatthew G. Knepley /*@ 42550e2b6761SMatthew G. Knepley DMPlexSetRefinementUniform - Set the flag for uniform refinement 42560e2b6761SMatthew G. Knepley 42570e2b6761SMatthew G. Knepley Input Parameters: 42580e2b6761SMatthew G. Knepley + dm - The DM 42590e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement 42600e2b6761SMatthew G. Knepley 42610e2b6761SMatthew G. Knepley Level: developer 42620e2b6761SMatthew G. Knepley 42630e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 42640e2b6761SMatthew G. Knepley @*/ 426575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 426675d3a19aSMatthew G. Knepley { 426775d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 426875d3a19aSMatthew G. Knepley 426975d3a19aSMatthew G. Knepley PetscFunctionBegin; 427075d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 427175d3a19aSMatthew G. Knepley mesh->refinementUniform = refinementUniform; 427275d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 427375d3a19aSMatthew G. Knepley } 427475d3a19aSMatthew G. Knepley 42750e2b6761SMatthew G. Knepley /*@ 42760e2b6761SMatthew G. Knepley DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 42770e2b6761SMatthew G. Knepley 42780e2b6761SMatthew G. Knepley Input Parameter: 42790e2b6761SMatthew G. Knepley . dm - The DM 42800e2b6761SMatthew G. Knepley 42810e2b6761SMatthew G. Knepley Output Parameter: 42820e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement 42830e2b6761SMatthew G. Knepley 42840e2b6761SMatthew G. Knepley Level: developer 42850e2b6761SMatthew G. Knepley 42860e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 42870e2b6761SMatthew G. Knepley @*/ 428875d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 428975d3a19aSMatthew G. Knepley { 429075d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 429175d3a19aSMatthew G. Knepley 429275d3a19aSMatthew G. Knepley PetscFunctionBegin; 429375d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 429475d3a19aSMatthew G. Knepley PetscValidPointer(refinementUniform, 2); 429575d3a19aSMatthew G. Knepley *refinementUniform = mesh->refinementUniform; 429675d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 429775d3a19aSMatthew G. Knepley } 429875d3a19aSMatthew G. Knepley 42990e2b6761SMatthew G. Knepley /*@ 43000e2b6761SMatthew G. Knepley DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 43010e2b6761SMatthew G. Knepley 43020e2b6761SMatthew G. Knepley Input Parameters: 43030e2b6761SMatthew G. Knepley + dm - The DM 43040e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh 43050e2b6761SMatthew G. Knepley 43060e2b6761SMatthew G. Knepley Level: developer 43070e2b6761SMatthew G. Knepley 43080e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 43090e2b6761SMatthew G. Knepley @*/ 431075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 431175d3a19aSMatthew G. Knepley { 431275d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 431375d3a19aSMatthew G. Knepley 431475d3a19aSMatthew G. Knepley PetscFunctionBegin; 431575d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 431675d3a19aSMatthew G. Knepley mesh->refinementLimit = refinementLimit; 431775d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 431875d3a19aSMatthew G. Knepley } 431975d3a19aSMatthew G. Knepley 43200e2b6761SMatthew G. Knepley /*@ 43210e2b6761SMatthew G. Knepley DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 43220e2b6761SMatthew G. Knepley 43230e2b6761SMatthew G. Knepley Input Parameter: 43240e2b6761SMatthew G. Knepley . dm - The DM 43250e2b6761SMatthew G. Knepley 43260e2b6761SMatthew G. Knepley Output Parameter: 43270e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh 43280e2b6761SMatthew G. Knepley 43290e2b6761SMatthew G. Knepley Level: developer 43300e2b6761SMatthew G. Knepley 43310e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 43320e2b6761SMatthew G. Knepley @*/ 433375d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 433475d3a19aSMatthew G. Knepley { 433575d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 433675d3a19aSMatthew G. Knepley 433775d3a19aSMatthew G. Knepley PetscFunctionBegin; 433875d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 433975d3a19aSMatthew G. Knepley PetscValidPointer(refinementLimit, 2); 434075d3a19aSMatthew G. Knepley /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 434175d3a19aSMatthew G. Knepley *refinementLimit = mesh->refinementLimit; 434275d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 434375d3a19aSMatthew G. Knepley } 434475d3a19aSMatthew G. Knepley 4345b28003e6SMatthew G. Knepley /*@ 4346b28003e6SMatthew G. Knepley DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 4347b28003e6SMatthew G. Knepley 4348b28003e6SMatthew G. Knepley Input Parameters: 4349b28003e6SMatthew G. Knepley + dm - The DM 4350b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh 4351b28003e6SMatthew G. Knepley 4352b28003e6SMatthew G. Knepley Note: The calling sequence is refinementFunc(coords, limit) 4353b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid 4354b28003e6SMatthew G. Knepley $ limit - The maximum cell volume for a cell containing this point 4355b28003e6SMatthew G. Knepley 4356b28003e6SMatthew G. Knepley Level: developer 4357b28003e6SMatthew G. Knepley 4358b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 4359b28003e6SMatthew G. Knepley @*/ 4360b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 4361b28003e6SMatthew G. Knepley { 4362b28003e6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 4363b28003e6SMatthew G. Knepley 4364b28003e6SMatthew G. Knepley PetscFunctionBegin; 4365b28003e6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4366b28003e6SMatthew G. Knepley mesh->refinementFunc = refinementFunc; 4367b28003e6SMatthew G. Knepley PetscFunctionReturn(0); 4368b28003e6SMatthew G. Knepley } 4369b28003e6SMatthew G. Knepley 4370b28003e6SMatthew G. Knepley /*@ 4371b28003e6SMatthew G. Knepley DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 4372b28003e6SMatthew G. Knepley 4373b28003e6SMatthew G. Knepley Input Parameter: 4374b28003e6SMatthew G. Knepley . dm - The DM 4375b28003e6SMatthew G. Knepley 4376b28003e6SMatthew G. Knepley Output Parameter: 4377b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh 4378b28003e6SMatthew G. Knepley 4379b28003e6SMatthew G. Knepley Note: The calling sequence is refinementFunc(coords, limit) 4380b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid 4381b28003e6SMatthew G. Knepley $ limit - The maximum cell volume for a cell containing this point 4382b28003e6SMatthew G. Knepley 4383b28003e6SMatthew G. Knepley Level: developer 4384b28003e6SMatthew G. Knepley 4385b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 4386b28003e6SMatthew G. Knepley @*/ 4387b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 4388b28003e6SMatthew G. Knepley { 4389b28003e6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 4390b28003e6SMatthew G. Knepley 4391b28003e6SMatthew G. Knepley PetscFunctionBegin; 4392b28003e6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4393b28003e6SMatthew G. Knepley PetscValidPointer(refinementFunc, 2); 4394b28003e6SMatthew G. Knepley *refinementFunc = mesh->refinementFunc; 4395b28003e6SMatthew G. Knepley PetscFunctionReturn(0); 4396b28003e6SMatthew G. Knepley } 4397b28003e6SMatthew G. Knepley 4398e7887635SMatthew G. Knepley static PetscErrorCode RefineDiscLabels_Internal(DMPlexCellRefiner cr, DM rdm) 4399e7887635SMatthew G. Knepley { 4400e7887635SMatthew G. Knepley DM dm = cr->dm; 4401e7887635SMatthew G. Knepley PetscInt Nf, f, Nds, s; 4402e7887635SMatthew G. Knepley PetscErrorCode ierr; 4403e7887635SMatthew G. Knepley 4404e7887635SMatthew G. Knepley PetscFunctionBegin; 4405e7887635SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 4406e7887635SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 4407e7887635SMatthew G. Knepley DMLabel label, labelNew; 4408e7887635SMatthew G. Knepley PetscObject obj; 4409e7887635SMatthew G. Knepley const char *lname; 4410e7887635SMatthew G. Knepley 4411e7887635SMatthew G. Knepley ierr = DMGetField(rdm, f, &label, &obj);CHKERRQ(ierr); 4412e7887635SMatthew G. Knepley if (!label) continue; 4413e7887635SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 4414e7887635SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew);CHKERRQ(ierr); 4415e7887635SMatthew G. Knepley ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr); 4416e7887635SMatthew G. Knepley ierr = DMSetField_Internal(rdm, f, labelNew, obj);CHKERRQ(ierr); 4417e7887635SMatthew G. Knepley ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr); 4418e7887635SMatthew G. Knepley } 4419e7887635SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 4420e7887635SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 4421e7887635SMatthew G. Knepley DMLabel label, labelNew; 4422e7887635SMatthew G. Knepley const char *lname; 4423e7887635SMatthew G. Knepley 4424e7887635SMatthew G. Knepley ierr = DMGetRegionNumDS(rdm, s, &label, NULL, NULL);CHKERRQ(ierr); 4425e7887635SMatthew G. Knepley if (!label) continue; 4426e7887635SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 4427e7887635SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew);CHKERRQ(ierr); 4428e7887635SMatthew G. Knepley ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr); 4429e7887635SMatthew G. Knepley ierr = DMSetRegionNumDS(rdm, s, labelNew, NULL, NULL);CHKERRQ(ierr); 4430e7887635SMatthew G. Knepley ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr); 4431e7887635SMatthew G. Knepley } 4432e7887635SMatthew G. Knepley PetscFunctionReturn(0); 4433e7887635SMatthew G. Knepley } 4434e7887635SMatthew G. Knepley 44353f2a96e3SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerAdaptLabel(DM dm, DMLabel adaptLabel, DM *dmRefined) 44363f2a96e3SMatthew G. Knepley { 44373f2a96e3SMatthew G. Knepley DMPlexCellRefiner cr; 44383f2a96e3SMatthew G. Knepley DM cdm, rcdm; 44393f2a96e3SMatthew G. Knepley PetscErrorCode ierr; 44403f2a96e3SMatthew G. Knepley 44413f2a96e3SMatthew G. Knepley PetscFunctionBegin; 44423f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr); 44433f2a96e3SMatthew G. Knepley cr->adaptLabel = adaptLabel; 44443f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 44453f2a96e3SMatthew G. Knepley ierr = DMPlexRefineUniform(dm, cr, dmRefined);CHKERRQ(ierr); 44463f2a96e3SMatthew G. Knepley ierr = DMCopyDisc(dm, *dmRefined);CHKERRQ(ierr); 44473f2a96e3SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 44483f2a96e3SMatthew G. Knepley ierr = DMGetCoordinateDM(*dmRefined, &rcdm);CHKERRQ(ierr); 44493f2a96e3SMatthew G. Knepley ierr = DMCopyDisc(cdm, rcdm);CHKERRQ(ierr); 44503f2a96e3SMatthew G. Knepley ierr = RefineDiscLabels_Internal(cr, *dmRefined);CHKERRQ(ierr); 44513f2a96e3SMatthew G. Knepley ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 44523f2a96e3SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 44533f2a96e3SMatthew G. Knepley PetscFunctionReturn(0); 44543f2a96e3SMatthew G. Knepley } 44553f2a96e3SMatthew G. Knepley 44560d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 44570d1cd5e0SMatthew G. Knepley { 4458492b8470SStefano Zampini PetscBool isUniform; 4459412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 44600d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 44610d1cd5e0SMatthew G. Knepley 44620d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 44630d1cd5e0SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 4464412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-initref_dm_view");CHKERRQ(ierr); 44650d1cd5e0SMatthew G. Knepley if (isUniform) { 446651a74b61SMatthew G. Knepley DM cdm, rcdm; 4467492b8470SStefano Zampini PetscBool localized; 44680d1cd5e0SMatthew G. Knepley 4469412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr); 4470412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 4471492b8470SStefano Zampini ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 4472412e9a14SMatthew G. Knepley ierr = DMPlexRefineUniform(dm, cr, dmRefined);CHKERRQ(ierr); 44739a7e3c0aSMatthew G. Knepley ierr = DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);CHKERRQ(ierr); 4474e7887635SMatthew G. Knepley ierr = DMCopyDisc(dm, *dmRefined);CHKERRQ(ierr); 447551a74b61SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 447651a74b61SMatthew G. Knepley ierr = DMGetCoordinateDM(*dmRefined, &rcdm);CHKERRQ(ierr); 447751a74b61SMatthew G. Knepley ierr = DMCopyDisc(cdm, rcdm);CHKERRQ(ierr); 4478e7887635SMatthew G. Knepley ierr = RefineDiscLabels_Internal(cr, *dmRefined);CHKERRQ(ierr); 44790d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 4480412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 44810d1cd5e0SMatthew G. Knepley } else { 44820d1cd5e0SMatthew G. Knepley ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 44830d1cd5e0SMatthew G. Knepley } 4484*6d7c9049SMatthew G. Knepley if (*dmRefined) { 4485*6d7c9049SMatthew G. Knepley ((DM_Plex *) (*dmRefined)->data)->printFEM = ((DM_Plex *) dm->data)->printFEM; 4486*6d7c9049SMatthew G. Knepley ((DM_Plex *) (*dmRefined)->data)->printL2 = ((DM_Plex *) dm->data)->printL2; 4487*6d7c9049SMatthew G. Knepley } 44880d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 44890d1cd5e0SMatthew G. Knepley } 44900d1cd5e0SMatthew G. Knepley 44910d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 44920d1cd5e0SMatthew G. Knepley { 44930d1cd5e0SMatthew G. Knepley DM cdm = dm; 44940d1cd5e0SMatthew G. Knepley PetscInt r; 44950d1cd5e0SMatthew G. Knepley PetscBool isUniform, localized; 44960d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 44970d1cd5e0SMatthew G. Knepley 44980d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 44990d1cd5e0SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 45000d1cd5e0SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 45010d1cd5e0SMatthew G. Knepley if (isUniform) { 45020d1cd5e0SMatthew G. Knepley for (r = 0; r < nlevels; ++r) { 4503412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 450451a74b61SMatthew G. Knepley DM codm, rcodm; 45050d1cd5e0SMatthew G. Knepley 4506412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(cdm, &cr);CHKERRQ(ierr); 4507412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 4508412e9a14SMatthew G. Knepley ierr = DMPlexRefineUniform(cdm, cr, &dmRefined[r]);CHKERRQ(ierr); 45099a7e3c0aSMatthew G. Knepley ierr = DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);CHKERRQ(ierr); 45109a7e3c0aSMatthew G. Knepley ierr = DMSetRefineLevel(dmRefined[r], cdm->levelup+1);CHKERRQ(ierr); 4511e7887635SMatthew G. Knepley ierr = DMCopyDisc(cdm, dmRefined[r]);CHKERRQ(ierr); 451251a74b61SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &codm);CHKERRQ(ierr); 451351a74b61SMatthew G. Knepley ierr = DMGetCoordinateDM(dmRefined[r], &rcodm);CHKERRQ(ierr); 451451a74b61SMatthew G. Knepley ierr = DMCopyDisc(codm, rcodm);CHKERRQ(ierr); 4515e7887635SMatthew G. Knepley ierr = RefineDiscLabels_Internal(cr, dmRefined[r]);CHKERRQ(ierr); 45160d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 45170d1cd5e0SMatthew G. Knepley ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 45180d1cd5e0SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 4519*6d7c9049SMatthew G. Knepley if (dmRefined[r]) { 4520*6d7c9049SMatthew G. Knepley ((DM_Plex *) (dmRefined[r])->data)->printFEM = ((DM_Plex *) dm->data)->printFEM; 4521*6d7c9049SMatthew G. Knepley ((DM_Plex *) (dmRefined[r])->data)->printL2 = ((DM_Plex *) dm->data)->printL2; 4522*6d7c9049SMatthew G. Knepley } 45230d1cd5e0SMatthew G. Knepley cdm = dmRefined[r]; 4524412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 45250d1cd5e0SMatthew G. Knepley } 45260d1cd5e0SMatthew G. Knepley } else { 45270d1cd5e0SMatthew G. Knepley for (r = 0; r < nlevels; ++r) { 45280d1cd5e0SMatthew G. Knepley ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 4529e7887635SMatthew G. Knepley ierr = DMCopyDisc(cdm, dmRefined[r]);CHKERRQ(ierr); 45300d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 45310d1cd5e0SMatthew G. Knepley if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 45320d1cd5e0SMatthew G. Knepley ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 4533*6d7c9049SMatthew G. Knepley if (dmRefined[r]) { 4534*6d7c9049SMatthew G. Knepley ((DM_Plex *) (dmRefined[r])->data)->printFEM = ((DM_Plex *) dm->data)->printFEM; 4535*6d7c9049SMatthew G. Knepley ((DM_Plex *) (dmRefined[r])->data)->printL2 = ((DM_Plex *) dm->data)->printL2; 4536*6d7c9049SMatthew G. Knepley } 45370d1cd5e0SMatthew G. Knepley cdm = dmRefined[r]; 45380d1cd5e0SMatthew G. Knepley } 45390d1cd5e0SMatthew G. Knepley } 45400d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 45410d1cd5e0SMatthew G. Knepley } 4542