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 5cf4091a3SMatthew G. Knepley const char * const DMPlexCellRefinerTypes[] = {"Regular", "ToBox", "ToSimplex", "Alfeld2D", "Alfeld3D", "PowellSabin", "BoundaryLayer", "DMPlexCellRefinerTypes", "DM_REFINER_", 0}; 675d3a19aSMatthew G. Knepley 709789c4cSMatthew G. Knepley /* 809789c4cSMatthew G. Knepley Note that j and invj are non-square: 909789c4cSMatthew G. Knepley v0 + j x_face = x_cell 1009789c4cSMatthew G. Knepley invj (x_cell - v0) = x_face 1109789c4cSMatthew G. Knepley */ 12412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[]) 1309789c4cSMatthew G. Knepley { 1409789c4cSMatthew G. Knepley /* 1509789c4cSMatthew G. Knepley 2 1609789c4cSMatthew G. Knepley |\ 1709789c4cSMatthew G. Knepley | \ 1809789c4cSMatthew G. Knepley | \ 1909789c4cSMatthew G. Knepley | \ 2009789c4cSMatthew G. Knepley | \ 2109789c4cSMatthew G. Knepley | \ 2209789c4cSMatthew G. Knepley | \ 2309789c4cSMatthew G. Knepley 2 1 2409789c4cSMatthew G. Knepley | \ 2509789c4cSMatthew G. Knepley | \ 2609789c4cSMatthew G. Knepley | \ 2709789c4cSMatthew G. Knepley 0---0-------1 28412e9a14SMatthew G. Knepley v0[Nf][dc]: 3 x 2 29412e9a14SMatthew G. Knepley J[Nf][df][dc]: 3 x 1 x 2 30412e9a14SMatthew G. Knepley invJ[Nf][dc][df]: 3 x 2 x 1 31412e9a14SMatthew G. Knepley detJ[Nf]: 3 3209789c4cSMatthew G. Knepley */ 33412e9a14SMatthew G. Knepley static PetscReal tri_v0[] = {0.0, -1.0, 0.0, 0.0, -1.0, 0.0}; 34412e9a14SMatthew G. Knepley static PetscReal tri_J[] = {1.0, 0.0, -1.0, 1.0, 0.0, -1.0}; 35412e9a14SMatthew G. Knepley static PetscReal tri_invJ[] = {1.0, 0.0, -0.5, 0.5, 0.0, -1.0}; 36412e9a14SMatthew G. Knepley static PetscReal tri_detJ[] = {1.0, 1.414213562373095, 1.0}; 3709789c4cSMatthew G. Knepley /* 3809789c4cSMatthew G. Knepley 3---------2---------2 3909789c4cSMatthew G. Knepley | | 4009789c4cSMatthew G. Knepley | | 4109789c4cSMatthew G. Knepley | | 4209789c4cSMatthew G. Knepley 3 1 4309789c4cSMatthew G. Knepley | | 4409789c4cSMatthew G. Knepley | | 4509789c4cSMatthew G. Knepley | | 4609789c4cSMatthew G. Knepley 0---------0---------1 47412e9a14SMatthew G. Knepley 48412e9a14SMatthew G. Knepley v0[Nf][dc]: 4 x 2 49412e9a14SMatthew G. Knepley J[Nf][df][dc]: 4 x 1 x 2 50412e9a14SMatthew G. Knepley invJ[Nf][dc][df]: 4 x 2 x 1 51412e9a14SMatthew G. Knepley detJ[Nf]: 4 5209789c4cSMatthew G. Knepley */ 53412e9a14SMatthew G. Knepley static PetscReal quad_v0[] = {0.0, -1.0, 1.0, 0.0, 0.0, 1.0 -1.0, 0.0}; 54412e9a14SMatthew G. Knepley static PetscReal quad_J[] = {1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, -1.0}; 55412e9a14SMatthew G. Knepley static PetscReal quad_invJ[] = {1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, -1.0}; 56412e9a14SMatthew G. Knepley static PetscReal quad_detJ[] = {1.0, 1.0, 1.0, 1.0}; 57412e9a14SMatthew G. Knepley 58412e9a14SMatthew G. Knepley PetscFunctionBegin; 59412e9a14SMatthew G. Knepley switch (ct) { 60412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: if (Nf) *Nf = 3; if (v0) *v0 = tri_v0; if (J) *J = tri_J; if (invJ) *invJ = tri_invJ; if (detJ) *detJ = tri_detJ; break; 61412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: if (Nf) *Nf = 4; if (v0) *v0 = quad_v0; if (J) *J = quad_J; if (invJ) *invJ = quad_invJ; if (detJ) *detJ = quad_detJ; break; 6209789c4cSMatthew G. Knepley default: 63412e9a14SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 6409789c4cSMatthew G. Knepley } 6509789c4cSMatthew G. Knepley PetscFunctionReturn(0); 6609789c4cSMatthew G. Knepley } 6709789c4cSMatthew G. Knepley 68bed052eaSMatthew G. Knepley /* Gets the affine map from the original cell to each subcell */ 69412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetAffineTransforms_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[]) 70bed052eaSMatthew G. Knepley { 71260b6d3fSMatthew G. Knepley /* 72260b6d3fSMatthew G. Knepley 2 73260b6d3fSMatthew G. Knepley |\ 74260b6d3fSMatthew G. Knepley | \ 75260b6d3fSMatthew G. Knepley | \ 76260b6d3fSMatthew G. Knepley | \ 77260b6d3fSMatthew G. Knepley | C \ 78260b6d3fSMatthew G. Knepley | \ 79260b6d3fSMatthew G. Knepley | \ 80260b6d3fSMatthew G. Knepley 2---1---1 81260b6d3fSMatthew G. Knepley |\ D / \ 82260b6d3fSMatthew G. Knepley | 2 0 \ 83260b6d3fSMatthew G. Knepley |A \ / B \ 84260b6d3fSMatthew G. Knepley 0---0-------1 85260b6d3fSMatthew G. Knepley */ 86412e9a14SMatthew G. Knepley static PetscReal tri_v0[] = {-1.0, -1.0, 0.0, -1.0, -1.0, 0.0, 0.0, -1.0}; 87412e9a14SMatthew G. Knepley static PetscReal tri_J[] = {0.5, 0.0, 88412e9a14SMatthew G. Knepley 0.0, 0.5, 89412e9a14SMatthew G. Knepley 90412e9a14SMatthew G. Knepley 0.5, 0.0, 91412e9a14SMatthew G. Knepley 0.0, 0.5, 92412e9a14SMatthew G. Knepley 93412e9a14SMatthew G. Knepley 0.5, 0.0, 94412e9a14SMatthew G. Knepley 0.0, 0.5, 95412e9a14SMatthew G. Knepley 96412e9a14SMatthew G. Knepley 0.0, -0.5, 97412e9a14SMatthew G. Knepley 0.5, 0.5}; 98412e9a14SMatthew G. Knepley static PetscReal tri_invJ[] = {2.0, 0.0, 99412e9a14SMatthew G. Knepley 0.0, 2.0, 100412e9a14SMatthew G. Knepley 101412e9a14SMatthew G. Knepley 2.0, 0.0, 102412e9a14SMatthew G. Knepley 0.0, 2.0, 103412e9a14SMatthew G. Knepley 104412e9a14SMatthew G. Knepley 2.0, 0.0, 105412e9a14SMatthew G. Knepley 0.0, 2.0, 106412e9a14SMatthew G. Knepley 107412e9a14SMatthew G. Knepley 2.0, 2.0, 108412e9a14SMatthew G. Knepley -2.0, 0.0}; 109260b6d3fSMatthew G. Knepley /* 110260b6d3fSMatthew G. Knepley 3---------2---------2 111260b6d3fSMatthew G. Knepley | | | 112260b6d3fSMatthew G. Knepley | D 2 C | 113260b6d3fSMatthew G. Knepley | | | 114260b6d3fSMatthew G. Knepley 3----3----0----1----1 115260b6d3fSMatthew G. Knepley | | | 116260b6d3fSMatthew G. Knepley | A 0 B | 117260b6d3fSMatthew G. Knepley | | | 118260b6d3fSMatthew G. Knepley 0---------0---------1 119260b6d3fSMatthew G. Knepley */ 120412e9a14SMatthew G. Knepley static PetscReal quad_v0[] = {-1.0, -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0}; 121412e9a14SMatthew G. Knepley static PetscReal quad_J[] = {0.5, 0.0, 122412e9a14SMatthew G. Knepley 0.0, 0.5, 123412e9a14SMatthew G. Knepley 124412e9a14SMatthew G. Knepley 0.5, 0.0, 125412e9a14SMatthew G. Knepley 0.0, 0.5, 126412e9a14SMatthew G. Knepley 127412e9a14SMatthew G. Knepley 0.5, 0.0, 128412e9a14SMatthew G. Knepley 0.0, 0.5, 129412e9a14SMatthew G. Knepley 130412e9a14SMatthew G. Knepley 0.5, 0.0, 131412e9a14SMatthew G. Knepley 0.0, 0.5}; 132412e9a14SMatthew G. Knepley static PetscReal quad_invJ[] = {2.0, 0.0, 133412e9a14SMatthew G. Knepley 0.0, 2.0, 134412e9a14SMatthew G. Knepley 135412e9a14SMatthew G. Knepley 2.0, 0.0, 136412e9a14SMatthew G. Knepley 0.0, 2.0, 137412e9a14SMatthew G. Knepley 138412e9a14SMatthew G. Knepley 2.0, 0.0, 139412e9a14SMatthew G. Knepley 0.0, 2.0, 140412e9a14SMatthew G. Knepley 141412e9a14SMatthew G. Knepley 2.0, 0.0, 142412e9a14SMatthew G. Knepley 0.0, 2.0}; 143c1879b55SMatthew G. Knepley /* 144c1879b55SMatthew G. Knepley Bottom (viewed from top) Top 145c1879b55SMatthew G. Knepley 1---------2---------2 7---------2---------6 146c1879b55SMatthew G. Knepley | | | | | | 147c1879b55SMatthew G. Knepley | B 2 C | | H 2 G | 148c1879b55SMatthew G. Knepley | | | | | | 149c1879b55SMatthew G. Knepley 3----3----0----1----1 3----3----0----1----1 150c1879b55SMatthew G. Knepley | | | | | | 151c1879b55SMatthew G. Knepley | A 0 D | | E 0 F | 152c1879b55SMatthew G. Knepley | | | | | | 153c1879b55SMatthew G. Knepley 0---------0---------3 4---------0---------5 154c1879b55SMatthew G. Knepley */ 155412e9a14SMatthew G. Knepley static PetscReal hex_v0[] = {-1.0, -1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0, -1.0, 156412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0}; 157412e9a14SMatthew G. Knepley static PetscReal hex_J[] = {0.5, 0.0, 0.0, 158412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 159412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 160bed052eaSMatthew G. Knepley 161412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 162412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 163412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 164412e9a14SMatthew G. Knepley 165412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 166412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 167412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 168412e9a14SMatthew G. Knepley 169412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 170412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 171412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 172412e9a14SMatthew G. Knepley 173412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 174412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 175412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 176412e9a14SMatthew G. Knepley 177412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 178412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 179412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 180412e9a14SMatthew G. Knepley 181412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 182412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 183412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 184412e9a14SMatthew G. Knepley 185412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 186412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 187412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5}; 188412e9a14SMatthew G. Knepley static PetscReal hex_invJ[] = {2.0, 0.0, 0.0, 189412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 190412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 191412e9a14SMatthew G. Knepley 192412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 193412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 194412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 195412e9a14SMatthew G. Knepley 196412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 197412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 198412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 199412e9a14SMatthew G. Knepley 200412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 201412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 202412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 203412e9a14SMatthew G. Knepley 204412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 205412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 206412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 207412e9a14SMatthew G. Knepley 208412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 209412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 210412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 211412e9a14SMatthew G. Knepley 212412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 213412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 214412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 215412e9a14SMatthew G. Knepley 216412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 217412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 218412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0}; 219bed052eaSMatthew G. Knepley 220bed052eaSMatthew G. Knepley PetscFunctionBegin; 221412e9a14SMatthew G. Knepley switch (ct) { 222412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: if (Nc) *Nc = 4; if (v0) *v0 = tri_v0; if (J) *J = tri_J; if (invJ) *invJ = tri_invJ; break; 223412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: if (Nc) *Nc = 4; if (v0) *v0 = quad_v0; if (J) *J = quad_J; if (invJ) *invJ = quad_invJ; break; 224412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: if (Nc) *Nc = 8; if (v0) *v0 = hex_v0; if (J) *J = hex_J; if (invJ) *invJ = hex_invJ; break; 225412e9a14SMatthew G. Knepley default: 226412e9a14SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 227412e9a14SMatthew G. Knepley } 228bed052eaSMatthew G. Knepley PetscFunctionReturn(0); 229bed052eaSMatthew G. Knepley } 230bed052eaSMatthew G. Knepley 23180389061SMatthew G. Knepley /* Should this be here or in the DualSpace somehow? */ 232412e9a14SMatthew G. Knepley PetscErrorCode CellRefinerInCellTest_Internal(DMPolytopeType ct, const PetscReal point[], PetscBool *inside) 23380389061SMatthew G. Knepley { 23480389061SMatthew G. Knepley PetscReal sum = 0.0; 23580389061SMatthew G. Knepley PetscInt d; 23680389061SMatthew G. Knepley 23780389061SMatthew G. Knepley PetscFunctionBegin; 23880389061SMatthew G. Knepley *inside = PETSC_TRUE; 239412e9a14SMatthew G. Knepley switch (ct) { 240412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 241412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 242412e9a14SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) { 24380389061SMatthew G. Knepley if (point[d] < -1.0) {*inside = PETSC_FALSE; break;} 24480389061SMatthew G. Knepley sum += point[d]; 24580389061SMatthew G. Knepley } 246412e9a14SMatthew G. Knepley if (sum > PETSC_SMALL) {*inside = PETSC_FALSE; break;} 24780389061SMatthew G. Knepley break; 248412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 249412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 250412e9a14SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) 251412e9a14SMatthew G. Knepley if (PetscAbsReal(point[d]) > 1.+PETSC_SMALL) {*inside = PETSC_FALSE; break;} 25294339e62SJed Brown break; 25380389061SMatthew G. Knepley default: 254412e9a14SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 25580389061SMatthew G. Knepley } 25680389061SMatthew G. Knepley PetscFunctionReturn(0); 25780389061SMatthew G. Knepley } 25880389061SMatthew G. Knepley 259412e9a14SMatthew G. Knepley /* Regular Refinment of Hybrid Meshes 26075d3a19aSMatthew G. Knepley 261412e9a14SMatthew G. Knepley We would like to express regular refinement as a small set of rules that can be applied on every point of the Plex 262412e9a14SMatthew G. Knepley to automatically generate a refined Plex. In fact, we would like these rules to be general enough to encompass other 263412e9a14SMatthew G. Knepley transformations, such as changing from one type of cell to another, as simplex to hex. 26475d3a19aSMatthew G. Knepley 265412e9a14SMatthew G. Knepley To start, we can create a function that takes an original cell type and returns the number of new cells replacing it 266412e9a14SMatthew G. Knepley and the types of the new cells. 267518a8359SMatthew G. Knepley 268412e9a14SMatthew G. Knepley We need the group multiplication table for group actions from the dihedral group for each cell type. 26942525629SMatthew G. Knepley 270412e9a14SMatthew G. Knepley We need an operator which takes in a cell, and produces a new set of cells with new faces and correct orientations. I think 271412e9a14SMatthew G. Knepley we can just write this operator for faces with identity, and then compose the face orientation actions to get the actual 272412e9a14SMatthew G. Knepley (face, orient) pairs for each subcell. 273412e9a14SMatthew G. Knepley */ 2740314a74cSLawrence Mitchell 27575d3a19aSMatthew G. Knepley /* 276412e9a14SMatthew G. Knepley Input Parameters: 277412e9a14SMatthew G. Knepley + ct - The type of the input cell 278*a5801f52SStefano Zampini . co - The orientation of this cell in its parent 279412e9a14SMatthew G. Knepley - cp - The requested cone point of this cell assuming orientation 0 280412e9a14SMatthew G. Knepley 281412e9a14SMatthew G. Knepley Output Parameters: 282*a5801f52SStefano Zampini . cpnew - The new cone point, taking into account the orientation co 283412e9a14SMatthew G. Knepley */ 284412e9a14SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPolytopeMapCell(DMPolytopeType ct, PetscInt co, PetscInt cp, PetscInt *cpnew) 285412e9a14SMatthew G. Knepley { 286412e9a14SMatthew G. Knepley const PetscInt csize = DMPolytopeTypeGetConeSize(ct); 287412e9a14SMatthew G. Knepley 288412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 289412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_POINT) {*cpnew = cp;} 290412e9a14SMatthew G. Knepley else {*cpnew = (co < 0 ? -(co+1)-cp+csize : co+cp)%csize;} 291412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 292412e9a14SMatthew G. Knepley } 293412e9a14SMatthew G. Knepley 294412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCellVertices_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 295412e9a14SMatthew G. Knepley { 296412e9a14SMatthew G. Knepley static PetscReal seg_v[] = {-1.0, 0.0, 1.0}; 297412e9a14SMatthew G. Knepley static PetscReal tri_v[] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0}; 298412e9a14SMatthew G. Knepley static PetscReal quad_v[] = {-1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0}; 299412e9a14SMatthew G. Knepley static PetscReal tet_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 300412e9a14SMatthew G. Knepley -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, -1.0, 1.0, -1.0, 301412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, -1.0, 1.0}; 302412e9a14SMatthew G. Knepley static PetscReal hex_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 303412e9a14SMatthew G. Knepley -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0, -1.0, 304412e9a14SMatthew G. Knepley -1.0, 1.0, -1.0, 0.0, 1.0, -1.0, 1.0, 1.0, -1.0, 305412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0, -1.0, 0.0, 306412e9a14SMatthew G. Knepley -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 307412e9a14SMatthew G. Knepley -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 308412e9a14SMatthew G. Knepley -1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 1.0, -1.0, 1.0, 309412e9a14SMatthew G. Knepley -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 310412e9a14SMatthew G. Knepley -1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0}; 311412e9a14SMatthew G. Knepley 312412e9a14SMatthew G. Knepley PetscFunctionBegin; 313412e9a14SMatthew G. Knepley switch (ct) { 314412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nv = 3; *subcellV = seg_v; break; 315412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 6; *subcellV = tri_v; break; 316412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nv = 9; *subcellV = quad_v; break; 317412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 10; *subcellV = tet_v; break; 318412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nv = 27; *subcellV = hex_v; break; 319412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 320412e9a14SMatthew G. Knepley } 321412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 322412e9a14SMatthew G. Knepley } 323412e9a14SMatthew G. Knepley 32496ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerGetCellVertices_ToBox(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 325412e9a14SMatthew G. Knepley { 326412e9a14SMatthew G. Knepley static PetscReal tri_v[] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0/3.0, -1.0/3.0}; 327412e9a14SMatthew G. Knepley static PetscReal tet_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 328412e9a14SMatthew G. Knepley -1.0, 0.0, -1.0, -1.0/3.0, -1.0/3.0, -1.0, 0.0, 0.0, -1.0, -1.0, 1.0, -1.0, 329412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, -1.0/3.0, -1.0, -1.0/3.0, 0.0, -1.0, 0.0, 330412e9a14SMatthew G. Knepley -1.0, -1.0/3.0, -1.0/3.0, -1.0/3.0, -1.0/3.0, -1.0/3.0, -1.0, 0.0, 0.0, 331412e9a14SMatthew G. Knepley -1.0, -1.0, 1.0, -0.5, -0.5, -0.5}; 332412e9a14SMatthew G. Knepley PetscErrorCode ierr; 333412e9a14SMatthew G. Knepley 334412e9a14SMatthew G. Knepley PetscFunctionBegin; 335412e9a14SMatthew G. Knepley switch (ct) { 336412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 337412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 338412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 339412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCellVertices_Regular(cr, ct, Nv, subcellV);CHKERRQ(ierr);break; 340412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 7; *subcellV = tri_v; break; 341412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 15; *subcellV = tet_v; break; 342412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 343412e9a14SMatthew G. Knepley } 344412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 345412e9a14SMatthew G. Knepley } 346412e9a14SMatthew G. Knepley 347412e9a14SMatthew G. Knepley /* 348412e9a14SMatthew G. Knepley DMPlexCellRefinerGetCellVertices - Get the set of refined vertices lying in the closure of a reference cell of given type 349412e9a14SMatthew G. Knepley 350412e9a14SMatthew G. Knepley Input Parameters: 351412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 352412e9a14SMatthew G. Knepley - ct - The cell type 353412e9a14SMatthew G. Knepley 354412e9a14SMatthew G. Knepley Output Parameters: 355412e9a14SMatthew G. Knepley + Nv - The number of refined vertices in the closure of the reference cell of given type 356412e9a14SMatthew G. Knepley - subcellV - The coordinates of these vertices in the reference cell 357412e9a14SMatthew G. Knepley 358412e9a14SMatthew G. Knepley Level: developer 359412e9a14SMatthew G. Knepley 360412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetSubcellVertices() 361412e9a14SMatthew G. Knepley */ 362412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCellVertices(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 363412e9a14SMatthew G. Knepley { 364412e9a14SMatthew G. Knepley PetscErrorCode ierr; 365412e9a14SMatthew G. Knepley 366412e9a14SMatthew G. Knepley PetscFunctionBegin; 367*a5801f52SStefano Zampini if (!cr->ops->getcellvertices) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]); 368412e9a14SMatthew G. Knepley ierr = (*cr->ops->getcellvertices)(cr, ct, Nv, subcellV);CHKERRQ(ierr); 369412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 370412e9a14SMatthew G. Knepley } 371412e9a14SMatthew G. Knepley 372412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 373412e9a14SMatthew G. Knepley { 374412e9a14SMatthew G. Knepley static PetscInt seg_v[] = {0, 1, 1, 2}; 375412e9a14SMatthew G. Knepley static PetscInt tri_v[] = {0, 3, 5, 3, 1, 4, 5, 4, 2, 3, 4, 5}; 376412e9a14SMatthew G. Knepley static PetscInt quad_v[] = {0, 4, 8, 7, 4, 1, 5, 8, 8, 5, 2, 6, 7, 8, 6, 3}; 377412e9a14SMatthew G. Knepley static PetscInt tet_v[] = {0, 3, 1, 6, 3, 2, 4, 8, 1, 4, 5, 7, 6, 8, 7, 9, 378412e9a14SMatthew G. Knepley 1, 6, 3, 7, 8, 4, 3, 7, 7, 3, 1, 4, 7, 3, 8, 6}; 379412e9a14SMatthew 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, 380412e9a14SMatthew 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}; 381412e9a14SMatthew G. Knepley 382412e9a14SMatthew G. Knepley PetscFunctionBegin; 383412e9a14SMatthew G. Knepley if (ct != rct) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Cell type %s does not produce %s", DMPolytopeTypes[ct], DMPolytopeTypes[rct]); 384412e9a14SMatthew G. Knepley switch (ct) { 385412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nv = 2; *subcellV = &seg_v[r*(*Nv)]; break; 386412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 3; *subcellV = &tri_v[r*(*Nv)]; break; 387412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nv = 4; *subcellV = &quad_v[r*(*Nv)]; break; 388412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 4; *subcellV = &tet_v[r*(*Nv)]; break; 389412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nv = 8; *subcellV = &hex_v[r*(*Nv)]; break; 390412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 391412e9a14SMatthew G. Knepley } 392412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 393412e9a14SMatthew G. Knepley } 394412e9a14SMatthew G. Knepley 39596ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerGetSubcellVertices_ToBox(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 396412e9a14SMatthew G. Knepley { 397412e9a14SMatthew G. Knepley static PetscInt tri_v[] = {0, 3, 6, 5, 3, 1, 4, 6, 5, 6, 4, 2}; 398412e9a14SMatthew 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}; 399412e9a14SMatthew G. Knepley PetscErrorCode ierr; 400412e9a14SMatthew G. Knepley 401412e9a14SMatthew G. Knepley PetscFunctionBegin; 402412e9a14SMatthew G. Knepley switch (ct) { 403412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 404412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 405412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 406412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetSubcellVertices_Regular(cr, ct, rct, r, Nv, subcellV);CHKERRQ(ierr);break; 407412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 408412e9a14SMatthew 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]); 409412e9a14SMatthew G. Knepley *Nv = 4; *subcellV = &tri_v[r*(*Nv)]; break; 410412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 411412e9a14SMatthew 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]); 412412e9a14SMatthew G. Knepley *Nv = 8; *subcellV = &tet_v[r*(*Nv)]; break; 413412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 414412e9a14SMatthew G. Knepley } 415412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 416412e9a14SMatthew G. Knepley } 417412e9a14SMatthew G. Knepley 418412e9a14SMatthew G. Knepley /* 419412e9a14SMatthew G. Knepley DMPlexCellRefinerGetSubcellVertices - Get the set of refined vertices defining a subcell in the reference cell of given type 420412e9a14SMatthew G. Knepley 421412e9a14SMatthew G. Knepley Input Parameters: 422412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 423412e9a14SMatthew G. Knepley . ct - The cell type 424412e9a14SMatthew G. Knepley . rct - The type of subcell 425412e9a14SMatthew G. Knepley - r - The subcell index 426412e9a14SMatthew G. Knepley 427412e9a14SMatthew G. Knepley Output Parameters: 428412e9a14SMatthew G. Knepley + Nv - The number of refined vertices in the subcell 429412e9a14SMatthew G. Knepley - subcellV - The indices of these vertices in the set of vertices returned by DMPlexCellRefinerGetCellVertices() 430412e9a14SMatthew G. Knepley 431412e9a14SMatthew G. Knepley Level: developer 432412e9a14SMatthew G. Knepley 433412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetCellVertices() 434412e9a14SMatthew G. Knepley */ 435412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 436412e9a14SMatthew G. Knepley { 437412e9a14SMatthew G. Knepley PetscErrorCode ierr; 438412e9a14SMatthew G. Knepley 439412e9a14SMatthew G. Knepley PetscFunctionBegin; 440*a5801f52SStefano Zampini if (!cr->ops->getsubcellvertices) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]); 441412e9a14SMatthew G. Knepley ierr = (*cr->ops->getsubcellvertices)(cr, ct, rct, r, Nv, subcellV);CHKERRQ(ierr); 442412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 443412e9a14SMatthew G. Knepley } 444412e9a14SMatthew G. Knepley 445412e9a14SMatthew G. Knepley /* 446412e9a14SMatthew G. Knepley Input Parameters: 447412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner 448412e9a14SMatthew G. Knepley . pct - The cell type of the parent, from whom the new cell is being produced 449*a5801f52SStefano Zampini . ct - The type being produced 450*a5801f52SStefano Zampini . r - The replica number requested for the produced cell type 451*a5801f52SStefano Zampini . Nv - Number of vertices in the closure of the parent cell 452*a5801f52SStefano Zampini . dE - Spatial dimension 453*a5801f52SStefano Zampini - in - array of size Nv*dE, holding coordinates of the vertices in the closure of the parent cell 454*a5801f52SStefano Zampini 455*a5801f52SStefano Zampini Output Parameters: 456*a5801f52SStefano Zampini . out - The coordinates of the new vertices 457*a5801f52SStefano Zampini */ 458*a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapCoordinates(DMPlexCellRefiner cr, DMPolytopeType pct, DMPolytopeType ct, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[]) 459*a5801f52SStefano Zampini { 460*a5801f52SStefano Zampini PetscErrorCode ierr; 461*a5801f52SStefano Zampini 462*a5801f52SStefano Zampini PetscFunctionBeginHot; 463*a5801f52SStefano Zampini if (!cr->ops->mapcoords) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]); 464*a5801f52SStefano Zampini ierr = (*cr->ops->mapcoords)(cr, pct, ct, r, Nv, dE, in, out);CHKERRQ(ierr); 465*a5801f52SStefano Zampini PetscFunctionReturn(0); 466*a5801f52SStefano Zampini } 467*a5801f52SStefano Zampini 468*a5801f52SStefano Zampini /* Computes new vertex as the barycenter */ 469*a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapCoordinates_Barycenter(DMPlexCellRefiner cr, DMPolytopeType pct, DMPolytopeType ct, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[]) 470*a5801f52SStefano Zampini { 471*a5801f52SStefano Zampini PetscInt v,d; 472*a5801f52SStefano Zampini 473*a5801f52SStefano Zampini PetscFunctionBeginHot; 474*a5801f52SStefano Zampini if (ct != DM_POLYTOPE_POINT) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for refined point type %s",DMPolytopeTypes[ct]); 475*a5801f52SStefano Zampini for (d = 0; d < dE; ++d) out[d] = 0.0; 476*a5801f52SStefano Zampini for (v = 0; v < Nv; ++v) for (d = 0; d < dE; ++d) out[d] += in[v*dE+d]; 477*a5801f52SStefano Zampini for (d = 0; d < dE; ++d) out[d] /= Nv; 478*a5801f52SStefano Zampini PetscFunctionReturn(0); 479*a5801f52SStefano Zampini } 480*a5801f52SStefano Zampini 481*a5801f52SStefano Zampini /* 482*a5801f52SStefano Zampini Input Parameters: 483*a5801f52SStefano Zampini + cr - The DMPlexCellRefiner 484*a5801f52SStefano Zampini . pct - The cell type of the parent, from whom the new cell is being produced 485412e9a14SMatthew G. Knepley . po - The orientation of the parent cell in its enclosing parent 486412e9a14SMatthew G. Knepley . ct - The type being produced 487412e9a14SMatthew G. Knepley . r - The replica number requested for the produced cell type 488412e9a14SMatthew G. Knepley - o - The relative orientation of the replica 489412e9a14SMatthew G. Knepley 490412e9a14SMatthew G. Knepley Output Parameters: 491*a5801f52SStefano Zampini + rnew - The replica number, given the orientation of the parent 492412e9a14SMatthew G. Knepley - onew - The replica orientation, given the orientation of the parent 493412e9a14SMatthew G. Knepley */ 494412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 495412e9a14SMatthew G. Knepley { 496412e9a14SMatthew G. Knepley PetscErrorCode ierr; 497412e9a14SMatthew G. Knepley 498412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 499*a5801f52SStefano Zampini if (!cr->ops->mapsubcells) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]); 500412e9a14SMatthew G. Knepley ierr = (*cr->ops->mapsubcells)(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 501412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 502412e9a14SMatthew G. Knepley } 503412e9a14SMatthew G. Knepley 504cf4091a3SMatthew G. Knepley /* 505cf4091a3SMatthew G. Knepley This is the group multiplication table for the dihedral group of the cell. 506cf4091a3SMatthew G. Knepley */ 507cf4091a3SMatthew G. Knepley static PetscErrorCode ComposeOrientation_Private(PetscInt n, PetscInt o1, PetscInt o2, PetscInt *o) 508cf4091a3SMatthew G. Knepley { 509cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 510cf4091a3SMatthew G. Knepley if (!n) {*o = 0;} 511cf4091a3SMatthew G. Knepley else if (o1 >= 0 && o2 >= 0) {*o = ( o1 + o2) % n;} 512cf4091a3SMatthew G. Knepley else if (o1 < 0 && o2 < 0) {*o = (-o1 - o2) % n;} 513cf4091a3SMatthew G. Knepley else if (o1 < 0) {*o = -((-(o1+1) + o2) % n + 1);} 514cf4091a3SMatthew G. Knepley else if (o2 < 0) {*o = -((-(o2+1) + o1) % n + 1);} 515cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 516cf4091a3SMatthew G. Knepley } 517cf4091a3SMatthew G. Knepley 518cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_None(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 519cf4091a3SMatthew G. Knepley { 520cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 521cf4091a3SMatthew G. Knepley 522cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 523cf4091a3SMatthew G. Knepley *rnew = r; 524cf4091a3SMatthew G. Knepley ierr = ComposeOrientation_Private(DMPolytopeTypeGetConeSize(ct), po, o, onew);CHKERRQ(ierr); 525cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 526cf4091a3SMatthew G. Knepley } 527cf4091a3SMatthew G. Knepley 528412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_Regular(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 529412e9a14SMatthew G. Knepley { 530412e9a14SMatthew G. Knepley /* We shift any input orientation in order to make it non-negative 531412e9a14SMatthew 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) 532412e9a14SMatthew G. Knepley The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 533412e9a14SMatthew G. Knepley Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 534412e9a14SMatthew G. Knepley */ 535412e9a14SMatthew G. Knepley PetscInt tri_seg_o[] = {-2, 0, 536412e9a14SMatthew G. Knepley -2, 0, 537412e9a14SMatthew G. Knepley -2, 0, 538412e9a14SMatthew G. Knepley 0, -2, 539412e9a14SMatthew G. Knepley 0, -2, 540412e9a14SMatthew G. Knepley 0, -2}; 541412e9a14SMatthew G. Knepley PetscInt tri_seg_r[] = {1, 0, 2, 542412e9a14SMatthew G. Knepley 0, 2, 1, 543412e9a14SMatthew G. Knepley 2, 1, 0, 544412e9a14SMatthew G. Knepley 0, 1, 2, 545412e9a14SMatthew G. Knepley 1, 2, 0, 546412e9a14SMatthew G. Knepley 2, 0, 1}; 547412e9a14SMatthew G. Knepley PetscInt tri_tri_o[] = {0, 1, 2, -3, -2, -1, 548412e9a14SMatthew G. Knepley 2, 0, 1, -2, -1, -3, 549412e9a14SMatthew G. Knepley 1, 2, 0, -1, -3, -2, 550412e9a14SMatthew G. Knepley -3, -2, -1, 0, 1, 2, 551412e9a14SMatthew G. Knepley -1, -3, -2, 1, 2, 0, 552412e9a14SMatthew G. Knepley -2, -1, -3, 2, 0, 1}; 553412e9a14SMatthew G. Knepley /* orientation if the replica is the center triangle */ 554412e9a14SMatthew G. Knepley PetscInt tri_tri_o_c[] = {2, 0, 1, -2, -1, -3, 555412e9a14SMatthew G. Knepley 1, 2, 0, -1, -3, -2, 556412e9a14SMatthew G. Knepley 0, 1, 2, -3, -2, -1, 557412e9a14SMatthew G. Knepley -3, -2, -1, 0, 1, 2, 558412e9a14SMatthew G. Knepley -1, -3, -2, 1, 2, 0, 559412e9a14SMatthew G. Knepley -2, -1, -3, 2, 0, 1}; 560412e9a14SMatthew G. Knepley PetscInt tri_tri_r[] = {0, 2, 1, 3, 561412e9a14SMatthew G. Knepley 2, 1, 0, 3, 562412e9a14SMatthew G. Knepley 1, 0, 2, 3, 563412e9a14SMatthew G. Knepley 0, 1, 2, 3, 564412e9a14SMatthew G. Knepley 1, 2, 0, 3, 565412e9a14SMatthew G. Knepley 2, 0, 1, 3}; 566412e9a14SMatthew G. Knepley PetscInt quad_seg_r[] = {3, 2, 1, 0, 567412e9a14SMatthew G. Knepley 2, 1, 0, 3, 568412e9a14SMatthew G. Knepley 1, 0, 3, 2, 569412e9a14SMatthew G. Knepley 0, 3, 2, 1, 570412e9a14SMatthew G. Knepley 0, 1, 2, 3, 571412e9a14SMatthew G. Knepley 1, 2, 3, 0, 572412e9a14SMatthew G. Knepley 2, 3, 0, 1, 573412e9a14SMatthew G. Knepley 3, 0, 1, 2}; 574412e9a14SMatthew G. Knepley PetscInt quad_quad_o[] = { 0, 1, 2, 3, -4, -3, -2, -1, 575412e9a14SMatthew G. Knepley 4, 0, 1, 2, -3, -2, -1, -4, 576412e9a14SMatthew G. Knepley 3, 4, 0, 1, -2, -1, -4, -3, 577412e9a14SMatthew G. Knepley 2, 3, 4, 0, -1, -4, -3, -2, 578412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 579412e9a14SMatthew G. Knepley -1, -4, -3, -2, 1, 2, 3, 0, 580412e9a14SMatthew G. Knepley -2, -1, -4, -3, 2, 3, 0, 1, 581412e9a14SMatthew G. Knepley -3, -2, -1, -4, 3, 0, 1, 2}; 582412e9a14SMatthew G. Knepley PetscInt quad_quad_r[] = {0, 3, 2, 1, 583412e9a14SMatthew G. Knepley 3, 2, 1, 0, 584412e9a14SMatthew G. Knepley 2, 1, 0, 3, 585412e9a14SMatthew G. Knepley 1, 0, 3, 2, 586412e9a14SMatthew G. Knepley 0, 1, 2, 3, 587412e9a14SMatthew G. Knepley 1, 2, 3, 0, 588412e9a14SMatthew G. Knepley 2, 3, 0, 1, 589412e9a14SMatthew G. Knepley 3, 0, 1, 2}; 590412e9a14SMatthew G. Knepley PetscInt tquad_tquad_o[] = { 0, 1, -2, -1, 591412e9a14SMatthew G. Knepley 1, 0, -1, -2, 592412e9a14SMatthew G. Knepley -2, -1, 0, 1, 593412e9a14SMatthew G. Knepley -1, -2, 1, 0}; 594412e9a14SMatthew G. Knepley PetscInt tquad_tquad_r[] = {1, 0, 595412e9a14SMatthew G. Knepley 1, 0, 596412e9a14SMatthew G. Knepley 0, 1, 597412e9a14SMatthew G. Knepley 0, 1}; 598412e9a14SMatthew G. Knepley 599412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 600412e9a14SMatthew G. Knepley /* The default is no transformation */ 601412e9a14SMatthew G. Knepley *rnew = r; 602412e9a14SMatthew G. Knepley *onew = o; 603412e9a14SMatthew G. Knepley switch (pct) { 604412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 605412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_SEGMENT) { 606412e9a14SMatthew G. Knepley if (po == 0 || po == -1) {*rnew = r; *onew = o;} 607412e9a14SMatthew G. Knepley else if (po == 1 || po == -2) {*rnew = (r+1)%2; *onew = (o == 0 || o == -1) ? -2 : 0;} 608412e9a14SMatthew G. Knepley else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid orientation %D for segment", po); 609412e9a14SMatthew G. Knepley } 610412e9a14SMatthew G. Knepley break; 611412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 612412e9a14SMatthew G. Knepley switch (ct) { 613412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 614412e9a14SMatthew G. Knepley if (o == -1) o = 0; 615412e9a14SMatthew G. Knepley if (o == -2) o = 1; 616412e9a14SMatthew G. Knepley *onew = tri_seg_o[(po+3)*2+o]; 617412e9a14SMatthew G. Knepley *rnew = tri_seg_r[(po+3)*3+r]; 618412e9a14SMatthew G. Knepley break; 619412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 620412e9a14SMatthew 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]; 621412e9a14SMatthew G. Knepley *rnew = tri_tri_r[(po+3)*4+r]; 622412e9a14SMatthew G. Knepley break; 623412e9a14SMatthew G. Knepley default: break; 624412e9a14SMatthew G. Knepley } 625412e9a14SMatthew G. Knepley break; 626412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 627412e9a14SMatthew G. Knepley switch (ct) { 628412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 629412e9a14SMatthew G. Knepley *onew = o; 630412e9a14SMatthew G. Knepley *rnew = quad_seg_r[(po+4)*4+r]; 631412e9a14SMatthew G. Knepley break; 632412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 633412e9a14SMatthew G. Knepley *onew = quad_quad_o[(po+4)*8+o+4]; 634412e9a14SMatthew G. Knepley *rnew = quad_quad_r[(po+4)*4+r]; 635412e9a14SMatthew G. Knepley break; 636412e9a14SMatthew G. Knepley default: break; 637412e9a14SMatthew G. Knepley } 638412e9a14SMatthew G. Knepley break; 639412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 640412e9a14SMatthew G. Knepley switch (ct) { 641412e9a14SMatthew G. Knepley /* DM_POLYTOPE_POINT_PRISM_TENSOR does not change */ 642412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 643412e9a14SMatthew G. Knepley *onew = tquad_tquad_o[(po+2)*4+o+2]; 644412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 645412e9a14SMatthew G. Knepley break; 646412e9a14SMatthew G. Knepley default: break; 647412e9a14SMatthew G. Knepley } 648412e9a14SMatthew G. Knepley break; 649412e9a14SMatthew G. Knepley default: break; 650412e9a14SMatthew G. Knepley } 651412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 652412e9a14SMatthew G. Knepley } 653412e9a14SMatthew G. Knepley 65496ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerMapSubcells_ToBox(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 655412e9a14SMatthew G. Knepley { 656412e9a14SMatthew G. Knepley PetscErrorCode ierr; 657412e9a14SMatthew G. Knepley /* We shift any input orientation in order to make it non-negative 658412e9a14SMatthew 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) 659412e9a14SMatthew G. Knepley The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 660412e9a14SMatthew G. Knepley Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 661412e9a14SMatthew G. Knepley */ 662412e9a14SMatthew G. Knepley PetscInt tri_seg_o[] = {0, -2, 663412e9a14SMatthew G. Knepley 0, -2, 664412e9a14SMatthew G. Knepley 0, -2, 665412e9a14SMatthew G. Knepley 0, -2, 666412e9a14SMatthew G. Knepley 0, -2, 667412e9a14SMatthew G. Knepley 0, -2}; 668412e9a14SMatthew G. Knepley PetscInt tri_seg_r[] = {2, 1, 0, 669412e9a14SMatthew G. Knepley 1, 0, 2, 670412e9a14SMatthew G. Knepley 0, 2, 1, 671412e9a14SMatthew G. Knepley 0, 1, 2, 672412e9a14SMatthew G. Knepley 1, 2, 0, 673412e9a14SMatthew G. Knepley 2, 0, 1}; 674412e9a14SMatthew G. Knepley PetscInt tri_tri_o[] = {0, 1, 2, 3, -4, -3, -2, -1, 675412e9a14SMatthew G. Knepley 3, 0, 1, 2, -3, -2, -1, -4, 676412e9a14SMatthew G. Knepley 1, 2, 3, 0, -1, -4, -3, -2, 677412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 678412e9a14SMatthew G. Knepley -1, -4, -3, -2, 1, 2, 3, 0, 679412e9a14SMatthew G. Knepley -3, -2, -1, -4, 3, 0, 1, 2}; 680412e9a14SMatthew G. Knepley PetscInt tri_tri_r[] = {0, 2, 1, 681412e9a14SMatthew G. Knepley 2, 1, 0, 682412e9a14SMatthew G. Knepley 1, 0, 2, 683412e9a14SMatthew G. Knepley 0, 1, 2, 684412e9a14SMatthew G. Knepley 1, 2, 0, 685412e9a14SMatthew G. Knepley 2, 0, 1}; 686412e9a14SMatthew G. Knepley PetscInt tquad_tquad_o[] = { 0, 1, -2, -1, 687412e9a14SMatthew G. Knepley 1, 0, -1, -2, 688412e9a14SMatthew G. Knepley -2, -1, 0, 1, 689412e9a14SMatthew G. Knepley -1, -2, 1, 0}; 690412e9a14SMatthew G. Knepley PetscInt tquad_tquad_r[] = {1, 0, 691412e9a14SMatthew G. Knepley 1, 0, 692412e9a14SMatthew G. Knepley 0, 1, 693412e9a14SMatthew G. Knepley 0, 1}; 694412e9a14SMatthew G. Knepley PetscInt tquad_quad_o[] = {-2, -1, -4, -3, 2, 3, 0, 1, 695412e9a14SMatthew G. Knepley 1, 2, 3, 0, -1, -4, -3, -2, 696412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 697412e9a14SMatthew G. Knepley 1, 0, 3, 2, -3, -4, -1, -2}; 698412e9a14SMatthew G. Knepley 699412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 700412e9a14SMatthew G. Knepley *rnew = r; 701412e9a14SMatthew G. Knepley *onew = o; 702412e9a14SMatthew G. Knepley switch (pct) { 703412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 704412e9a14SMatthew G. Knepley switch (ct) { 705412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 706412e9a14SMatthew G. Knepley if (o == -1) o = 0; 707412e9a14SMatthew G. Knepley if (o == -2) o = 1; 708412e9a14SMatthew G. Knepley *onew = tri_seg_o[(po+3)*2+o]; 709412e9a14SMatthew G. Knepley *rnew = tri_seg_r[(po+3)*3+r]; 710412e9a14SMatthew G. Knepley break; 711412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 712412e9a14SMatthew G. Knepley *onew = tri_tri_o[(po+3)*8+o+4]; 713412e9a14SMatthew G. Knepley /* TODO See sheet, for fixing po == 1 and 2 */ 714412e9a14SMatthew G. Knepley if (po == 2 && r == 2 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+3)%4)+4]; 715412e9a14SMatthew G. Knepley if (po == 2 && r == 2 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+5)%4)]; 716412e9a14SMatthew G. Knepley if (po == 1 && r == 1 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+1)%4)+4]; 717412e9a14SMatthew G. Knepley if (po == 1 && r == 1 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+7)%4)]; 718412e9a14SMatthew G. Knepley if (po == -1 && r == 2 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+3)%4)+4]; 719412e9a14SMatthew G. Knepley if (po == -1 && r == 2 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+5)%4)]; 720412e9a14SMatthew G. Knepley if (po == -2 && r == 1 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+1)%4)+4]; 721412e9a14SMatthew G. Knepley if (po == -2 && r == 1 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+7)%4)]; 722412e9a14SMatthew G. Knepley *rnew = tri_tri_r[(po+3)*3+r]; 723412e9a14SMatthew G. Knepley break; 724412e9a14SMatthew G. Knepley default: break; 725412e9a14SMatthew G. Knepley } 726412e9a14SMatthew G. Knepley break; 727412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 728412e9a14SMatthew G. Knepley switch (ct) { 729412e9a14SMatthew G. Knepley /* DM_POLYTOPE_POINT_PRISM_TENSOR does not change */ 730412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 731412e9a14SMatthew G. Knepley *onew = tquad_tquad_o[(po+2)*4+o+2]; 732412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 733412e9a14SMatthew G. Knepley break; 734412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 735412e9a14SMatthew G. Knepley *onew = tquad_quad_o[(po+2)*8+o+4]; 736412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 737412e9a14SMatthew G. Knepley break; 738412e9a14SMatthew G. Knepley default: break; 739412e9a14SMatthew G. Knepley } 740412e9a14SMatthew G. Knepley break; 741412e9a14SMatthew G. Knepley default: 742412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapSubcells_Regular(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 743412e9a14SMatthew G. Knepley } 744412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 745412e9a14SMatthew G. Knepley } 746412e9a14SMatthew G. Knepley 747412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 748412e9a14SMatthew G. Knepley { 749412e9a14SMatthew G. Knepley return DMPlexCellRefinerMapSubcells_Regular(cr, pct, po, ct, r, o, rnew, onew); 750412e9a14SMatthew G. Knepley } 751412e9a14SMatthew G. Knepley 752412e9a14SMatthew G. Knepley /*@ 753412e9a14SMatthew G. Knepley DMPlexCellRefinerRefine - Return a description of the refinement for a given cell type 754412e9a14SMatthew G. Knepley 755412e9a14SMatthew G. Knepley Input Parameter: 756412e9a14SMatthew G. Knepley . source - The cell type for a source point 757412e9a14SMatthew G. Knepley 758412e9a14SMatthew G. Knepley Output Parameter: 759412e9a14SMatthew G. Knepley + Nt - The number of cell types generated by refinement 760412e9a14SMatthew G. Knepley . target - The cell types generated 761412e9a14SMatthew G. Knepley . size - The number of subcells of each type, ordered by dimension 762412e9a14SMatthew G. Knepley . cone - A list of the faces for each subcell of the same type as source 763412e9a14SMatthew G. Knepley - ornt - A list of the face orientations for each subcell of the same type as source 764412e9a14SMatthew G. Knepley 765*a5801f52SStefano Zampini Note: The cone array gives the cone of each subcell listed by the first three outputs. For each cone point, we 766412e9a14SMatthew G. Knepley need the cell type, point identifier, and orientation within the subcell. The orientation is with respect to the canonical 767412e9a14SMatthew G. Knepley division (described in these outputs) of the cell in the original mesh. The point identifier is given by 768412e9a14SMatthew G. Knepley $ the number of cones to be taken, or 0 for the current cell 769412e9a14SMatthew G. Knepley $ the cell cone point number at each level from which it is subdivided 770412e9a14SMatthew G. Knepley $ the replica number r of the subdivision. 771412e9a14SMatthew G. Knepley The orientation is with respect to the canonical cone orientation. For example, the prescription for edge division is 772412e9a14SMatthew G. Knepley $ Nt = 2 773412e9a14SMatthew G. Knepley $ target = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT} 774412e9a14SMatthew G. Knepley $ size = {1, 2} 775412e9a14SMatthew 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} 776412e9a14SMatthew G. Knepley $ ornt = { 0, 0, 0, 0} 777412e9a14SMatthew G. Knepley 778412e9a14SMatthew G. Knepley Level: developer 779412e9a14SMatthew G. Knepley 78096ca5757SLisandro Dalcin .seealso: DMPlexCellRefinerCreate(), DMPlexRefineUniform() 781412e9a14SMatthew G. Knepley @*/ 782412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerRefine(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 783412e9a14SMatthew G. Knepley { 784412e9a14SMatthew G. Knepley PetscErrorCode ierr; 785412e9a14SMatthew G. Knepley 786412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 787*a5801f52SStefano Zampini if (!cr->ops->refine) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]); 788412e9a14SMatthew G. Knepley ierr = (*cr->ops->refine)(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 789412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 790412e9a14SMatthew G. Knepley } 791412e9a14SMatthew G. Knepley 792cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_None(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 793cf4091a3SMatthew G. Knepley { 794cf4091a3SMatthew G. Knepley static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT}; 795cf4091a3SMatthew G. Knepley static PetscInt vertexS[] = {1}; 796cf4091a3SMatthew G. Knepley static PetscInt vertexC[] = {0}; 797cf4091a3SMatthew G. Knepley static PetscInt vertexO[] = {0}; 798cf4091a3SMatthew G. Knepley static DMPolytopeType edgeT[] = {DM_POLYTOPE_SEGMENT}; 799cf4091a3SMatthew G. Knepley static PetscInt edgeS[] = {1}; 800cf4091a3SMatthew G. Knepley static PetscInt edgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 801cf4091a3SMatthew G. Knepley static PetscInt edgeO[] = {0, 0}; 802cf4091a3SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR}; 803cf4091a3SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 804cf4091a3SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 805cf4091a3SMatthew G. Knepley static PetscInt tedgeO[] = {0, 0}; 806cf4091a3SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_TRIANGLE}; 807cf4091a3SMatthew G. Knepley static PetscInt triS[] = {1}; 808cf4091a3SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0}; 809cf4091a3SMatthew G. Knepley static PetscInt triO[] = {0, 0, 0}; 810cf4091a3SMatthew G. Knepley static DMPolytopeType quadT[] = {DM_POLYTOPE_QUADRILATERAL}; 811cf4091a3SMatthew G. Knepley static PetscInt quadS[] = {1}; 812cf4091a3SMatthew 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}; 813cf4091a3SMatthew G. Knepley static PetscInt quadO[] = {0, 0, 0, 0}; 814cf4091a3SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_SEG_PRISM_TENSOR}; 815cf4091a3SMatthew G. Knepley static PetscInt tquadS[] = {1}; 816cf4091a3SMatthew 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}; 817cf4091a3SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 0, 0}; 818cf4091a3SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_TETRAHEDRON}; 819cf4091a3SMatthew G. Knepley static PetscInt tetS[] = {1}; 820cf4091a3SMatthew 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}; 821cf4091a3SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 0, 0}; 822cf4091a3SMatthew G. Knepley static DMPolytopeType hexT[] = {DM_POLYTOPE_HEXAHEDRON}; 823cf4091a3SMatthew G. Knepley static PetscInt hexS[] = {1}; 824cf4091a3SMatthew G. Knepley static PetscInt hexC[] = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, 825cf4091a3SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0, DM_POLYTOPE_QUADRILATERAL, 1, 5, 0}; 826cf4091a3SMatthew G. Knepley static PetscInt hexO[] = {0, 0, 0, 0, 0, 0}; 827cf4091a3SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_TRI_PRISM}; 828cf4091a3SMatthew G. Knepley static PetscInt tripS[] = {1}; 829cf4091a3SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, 830cf4091a3SMatthew G. Knepley DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0}; 831cf4091a3SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 0, 0, 0}; 832cf4091a3SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_TRI_PRISM_TENSOR}; 833cf4091a3SMatthew G. Knepley static PetscInt ttripS[] = {1}; 834cf4091a3SMatthew G. Knepley static PetscInt ttripC[] = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, 835cf4091a3SMatthew 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}; 836cf4091a3SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 0, 0, 0}; 837cf4091a3SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_QUAD_PRISM_TENSOR}; 838cf4091a3SMatthew G. Knepley static PetscInt tquadpS[] = {1}; 839cf4091a3SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, 840cf4091a3SMatthew 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}; 841cf4091a3SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 0, 0, 0, 0}; 842cf4091a3SMatthew G. Knepley 843cf4091a3SMatthew G. Knepley PetscFunctionBegin; 844cf4091a3SMatthew G. Knepley switch (source) { 845cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT: *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break; 846cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nt = 1; *target = edgeT; *size = edgeS; *cone = edgeC; *ornt = edgeO; break; 847cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 848cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 1; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 849cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nt = 1; *target = quadT; *size = quadS; *cone = quadC; *ornt = quadO; break; 850cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 1; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 851cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 1; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 852cf4091a3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nt = 1; *target = hexT; *size = hexS; *cone = hexC; *ornt = hexO; break; 853cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 1; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 854cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 1; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 855cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 1; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 856cf4091a3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 857cf4091a3SMatthew G. Knepley } 858cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 859cf4091a3SMatthew G. Knepley } 860cf4091a3SMatthew G. Knepley 861412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Regular(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 862412e9a14SMatthew G. Knepley { 863412e9a14SMatthew G. Knepley /* All vertices remain in the refined mesh */ 864412e9a14SMatthew G. Knepley static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT}; 865412e9a14SMatthew G. Knepley static PetscInt vertexS[] = {1}; 866412e9a14SMatthew G. Knepley static PetscInt vertexC[] = {0}; 867412e9a14SMatthew G. Knepley static PetscInt vertexO[] = {0}; 868412e9a14SMatthew G. Knepley /* Split all edges with a new vertex, making two new 2 edges 869412e9a14SMatthew G. Knepley 0--0--0--1--1 870412e9a14SMatthew G. Knepley */ 871412e9a14SMatthew G. Knepley static DMPolytopeType edgeT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT}; 872412e9a14SMatthew G. Knepley static PetscInt edgeS[] = {1, 2}; 873412e9a14SMatthew 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}; 874412e9a14SMatthew G. Knepley static PetscInt edgeO[] = { 0, 0, 0, 0}; 875412e9a14SMatthew G. Knepley /* Do not split tensor edges */ 876412e9a14SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR}; 877412e9a14SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 878412e9a14SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 879412e9a14SMatthew G. Knepley static PetscInt tedgeO[] = { 0, 0}; 880412e9a14SMatthew G. Knepley /* Add 3 edges inside every triangle, making 4 new triangles. 88175d3a19aSMatthew G. Knepley 2 88275d3a19aSMatthew G. Knepley |\ 88375d3a19aSMatthew G. Knepley | \ 88475d3a19aSMatthew G. Knepley | \ 885412e9a14SMatthew G. Knepley 0 1 88675d3a19aSMatthew G. Knepley | C \ 88775d3a19aSMatthew G. Knepley | \ 88875d3a19aSMatthew G. Knepley | \ 88975d3a19aSMatthew G. Knepley 2---1---1 89075d3a19aSMatthew G. Knepley |\ D / \ 891412e9a14SMatthew G. Knepley 1 2 0 0 89275d3a19aSMatthew G. Knepley |A \ / B \ 893412e9a14SMatthew G. Knepley 0-0-0---1---1 89475d3a19aSMatthew G. Knepley */ 895412e9a14SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE}; 896412e9a14SMatthew G. Knepley static PetscInt triS[] = {3, 4}; 897412e9a14SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 898412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 1, 2, 0, 899412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 0, 0, 900412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 901412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 0, 902412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, 903412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2}; 904412e9a14SMatthew G. Knepley static PetscInt triO[] = {0, 0, 905412e9a14SMatthew G. Knepley 0, 0, 906412e9a14SMatthew G. Knepley 0, 0, 907412e9a14SMatthew G. Knepley 0, -2, 0, 908412e9a14SMatthew G. Knepley 0, 0, -2, 909412e9a14SMatthew G. Knepley -2, 0, 0, 910412e9a14SMatthew G. Knepley 0, 0, 0}; 911412e9a14SMatthew G. Knepley /* Add a vertex in the center of each quadrilateral, and 4 edges inside, making 4 new quads. 912412e9a14SMatthew G. Knepley 3----1----2----0----2 913412e9a14SMatthew G. Knepley | | | 914412e9a14SMatthew G. Knepley 0 D 2 C 1 915412e9a14SMatthew G. Knepley | | | 916412e9a14SMatthew G. Knepley 3----3----0----1----1 917412e9a14SMatthew G. Knepley | | | 918412e9a14SMatthew G. Knepley 1 A 0 B 0 919412e9a14SMatthew G. Knepley | | | 920412e9a14SMatthew G. Knepley 0----0----0----1----1 921412e9a14SMatthew G. Knepley */ 922412e9a14SMatthew G. Knepley static DMPolytopeType quadT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 923412e9a14SMatthew G. Knepley static PetscInt quadS[] = {1, 4, 4}; 924412e9a14SMatthew G. Knepley static PetscInt quadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 925412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 926412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 927412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 928412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, 929412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 930412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, 931412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0}; 932412e9a14SMatthew G. Knepley static PetscInt quadO[] = {0, 0, 933412e9a14SMatthew G. Knepley 0, 0, 934412e9a14SMatthew G. Knepley 0, 0, 935412e9a14SMatthew G. Knepley 0, 0, 936412e9a14SMatthew G. Knepley 0, 0, -2, 0, 937412e9a14SMatthew G. Knepley 0, 0, 0, -2, 938412e9a14SMatthew G. Knepley -2, 0, 0, 0, 939412e9a14SMatthew G. Knepley 0, -2, 0, 0}; 940412e9a14SMatthew G. Knepley /* Add 1 edge inside every tensor quad, making 2 new tensor quads 941412e9a14SMatthew G. Knepley 2----2----1----3----3 942412e9a14SMatthew G. Knepley | | | 943412e9a14SMatthew G. Knepley | | | 944412e9a14SMatthew G. Knepley | | | 945412e9a14SMatthew G. Knepley 4 A 6 B 5 946412e9a14SMatthew G. Knepley | | | 947412e9a14SMatthew G. Knepley | | | 948412e9a14SMatthew G. Knepley | | | 949412e9a14SMatthew G. Knepley 0----0----0----1----1 950412e9a14SMatthew G. Knepley */ 951412e9a14SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR}; 952412e9a14SMatthew G. Knepley static PetscInt tquadS[] = {1, 2}; 953412e9a14SMatthew G. Knepley static PetscInt tquadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 954412e9a14SMatthew 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, 955412e9a14SMatthew 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}; 956412e9a14SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 957412e9a14SMatthew G. Knepley 0, 0, 0, 0, 958412e9a14SMatthew G. Knepley 0, 0, 0, 0}; 959412e9a14SMatthew G. Knepley /* Add 1 edge and 8 triangles inside every cell, making 8 new tets 960412e9a14SMatthew 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 961412e9a14SMatthew 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] 962412e9a14SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 963412e9a14SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 964412e9a14SMatthew G. Knepley The first four tets just cut off the corners, using the replica notation for new vertices, 965412e9a14SMatthew G. Knepley [v0, (e0, 0), (e2, 0), (e3, 0)] 966412e9a14SMatthew G. Knepley [(e0, 0), v1, (e1, 0), (e4, 0)] 967412e9a14SMatthew G. Knepley [(e2, 0), (e1, 0), v2, (e5, 0)] 968412e9a14SMatthew G. Knepley [(e3, 0), (e4, 0), (e5, 0), v3 ] 969412e9a14SMatthew G. Knepley The next four tets match a vertex to the newly created faces from cutting off those first tets. 970412e9a14SMatthew G. Knepley [(e2, 0), (e3, 0), (e0, 0), (e5, 0)] 971412e9a14SMatthew G. Knepley [(e4, 0), (e1, 0), (e0, 0), (e5, 0)] 972412e9a14SMatthew G. Knepley [(e5, 0), (e0, 0), (e2, 0), (e1, 0)] 973412e9a14SMatthew G. Knepley [(e5, 0), (e0, 0), (e4, 0), (e3, 0)] 974412e9a14SMatthew 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 975412e9a14SMatthew G. Knepley [(e2, 0), (e0, 0), (e3, 0)] 976412e9a14SMatthew G. Knepley [(e0, 0), (e1, 0), (e4, 0)] 977412e9a14SMatthew G. Knepley [(e2, 0), (e5, 0), (e1, 0)] 978412e9a14SMatthew G. Knepley [(e3, 0), (e4, 0), (e5, 0)] 979412e9a14SMatthew G. Knepley The next four, from the second group of tets, are 980412e9a14SMatthew G. Knepley [(e2, 0), (e0, 0), (e5, 0)] 981412e9a14SMatthew G. Knepley [(e4, 0), (e0, 0), (e5, 0)] 982412e9a14SMatthew G. Knepley [(e0, 0), (e1, 0), (e5, 0)] 983412e9a14SMatthew G. Knepley [(e5, 0), (e3, 0), (e0, 0)] 984412e9a14SMatthew G. Knepley I could write a program to generate these orientations by comparing the faces from GetRawFaces() with my existing table. 985412e9a14SMatthew G. Knepley */ 986412e9a14SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON}; 987412e9a14SMatthew G. Knepley static PetscInt tetS[] = {1, 8, 8}; 988412e9a14SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 2, 2, 1, 0, 989412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 2, 2, 990412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 1, 1, 991412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 1, 0, 1, 992412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 2, 1, 993412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0, 994412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, 995412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 0, 996412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0, 0, 997412e9a14SMatthew 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, 998412e9a14SMatthew 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, 999412e9a14SMatthew 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, 1000412e9a14SMatthew 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, 1001412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 2, 3, DM_POLYTOPE_TRIANGLE, 0, 4, DM_POLYTOPE_TRIANGLE, 0, 7, 1002412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 1, 3, 3, DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 6, 1003412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 4, DM_POLYTOPE_TRIANGLE, 0, 6, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 1, 0, 3, 1004412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 7, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 1, 1, 3}; 1005412e9a14SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 1006412e9a14SMatthew G. Knepley 0, 0, 0, 1007412e9a14SMatthew G. Knepley 0, 0, 0, 1008412e9a14SMatthew G. Knepley 0, 0, 0, 1009412e9a14SMatthew G. Knepley 0, 0, 0, 1010412e9a14SMatthew G. Knepley 0, 0, -2, 1011412e9a14SMatthew G. Knepley 0, 0, -2, 1012412e9a14SMatthew G. Knepley 0, -2, -2, 1013412e9a14SMatthew G. Knepley 0, -2, 0, 1014412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1015412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1016412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1017412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1018412e9a14SMatthew G. Knepley -3, 0, 0, -2, 1019412e9a14SMatthew G. Knepley -2, 1, 0, 0, 1020412e9a14SMatthew G. Knepley -2, -2, -1, 2, 1021412e9a14SMatthew G. Knepley -2, 0, -2, 1}; 1022412e9a14SMatthew G. Knepley /* Add a vertex in the center of each cell, add 6 edges and 12 quads inside every cell, making 8 new hexes 1023412e9a14SMatthew 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 1024412e9a14SMatthew G. Knepley [v0, v1, v2, v3] f0 bottom 1025412e9a14SMatthew G. Knepley [v4, v5, v6, v7] f1 top 1026412e9a14SMatthew G. Knepley [v0, v3, v5, v4] f2 front 1027412e9a14SMatthew G. Knepley [v2, v1, v7, v6] f3 back 1028412e9a14SMatthew G. Knepley [v3, v2, v6, v5] f4 right 1029412e9a14SMatthew G. Knepley [v0, v4, v7, v1] f5 left 1030412e9a14SMatthew G. Knepley The eight hexes are divided into four on the bottom, and four on the top, 1031412e9a14SMatthew G. Knepley [v0, (e0, 0), (f0, 0), (e3, 0), (e9, 0), (f2, 0), (c0, 0), (f5, 0)] 1032412e9a14SMatthew G. Knepley [(e0, 0), v1, (e1, 0), (f0, 0), (f5, 0), (c0, 0), (f3, 0), (e10, 0)] 1033412e9a14SMatthew G. Knepley [(f0, 0), (e1, 0), v2, (e2, 0), (c0, 0), (f4, 0), (e11, 0), (f3, 0)] 1034412e9a14SMatthew G. Knepley [(e3, 0), (f0, 0), (e2, 0), v3, (f2, 0), (e8, 0), (f4, 0), (c0, 0)] 1035412e9a14SMatthew G. Knepley [(e9, 0), (f5, 0), (c0, 0), (f2, 0), v4, (e4, 0), (f1, 0), (e7, 0)] 1036412e9a14SMatthew G. Knepley [(f2, 0), (c0, 0), (f4, 0), (e8, 0), (e4, 0), v5, (e5, 0), (f1, 0)] 1037412e9a14SMatthew G. Knepley [(c0, 0), (f3, 0), (e11, 0), (f4, 0), (f1, 0), (e5, 0), v6, (e6, 0)] 1038412e9a14SMatthew G. Knepley [(f5, 0), (e10, 0), (f3, 0), (c0, 0), (e7, 0), (f1, 0), (e6, 0), v7] 1039412e9a14SMatthew 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, 1040412e9a14SMatthew G. Knepley [(e9, 0), (f2, 0), (c0, 0), (f5, 0)] 1041412e9a14SMatthew G. Knepley [(f5, 0), (c0, 0), (f3, 0), (e10, 0)] 1042412e9a14SMatthew G. Knepley [(c0, 0), (f4, 0), (e11, 0), (f3, 0)] 1043412e9a14SMatthew G. Knepley [(f2, 0), (e8, 0), (f4, 0), (c0, 0)] 1044412e9a14SMatthew G. Knepley and on the x-z plane, 1045412e9a14SMatthew G. Knepley [(f0, 0), (e0, 0), (f5, 0), (c0, 0)] 1046412e9a14SMatthew G. Knepley [(c0, 0), (f5, 0), (e7, 0), (f1, 0)] 1047412e9a14SMatthew G. Knepley [(f4, 0), (c0, 0), (f1, 0), (e5, 0)] 1048412e9a14SMatthew G. Knepley [(e2, 0), (f0, 0), (c0, 0), (f4, 0)] 1049412e9a14SMatthew G. Knepley and on the y-z plane, 1050412e9a14SMatthew G. Knepley [(e3, 0), (f2, 0), (c0, 0), (f0, 0)] 1051412e9a14SMatthew G. Knepley [(f2, 0), (e4, 0), (f1, 0), (c0, 0)] 1052412e9a14SMatthew G. Knepley [(c0, 0), (f1, 0), (e6, 0), (f3, 0)] 1053412e9a14SMatthew G. Knepley [(f0, 0), (c0, 0), (f3, 0), (e1, 0)] 1054412e9a14SMatthew G. Knepley */ 1055412e9a14SMatthew G. Knepley static DMPolytopeType hexT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1056412e9a14SMatthew G. Knepley static PetscInt hexS[] = {1, 6, 12, 8}; 1057412e9a14SMatthew G. Knepley static PetscInt hexC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1058412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1059412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1060412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1061412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0, 1062412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 5, 0, DM_POLYTOPE_POINT, 0, 0, 1063412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 1, 5, 0, 1064412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 5, 2, 1065412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 3, 1066412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 2, 1067412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 5, 3, DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 0, 0, 1068412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 1, 5, 1, DM_POLYTOPE_SEGMENT, 1, 1, 3, DM_POLYTOPE_SEGMENT, 0, 1, 1069412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 4, 2, 1070412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 0, 1071412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 0, 3, 1072412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 1073412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 3, 1074412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1, 1075412e9a14SMatthew 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, 1076412e9a14SMatthew 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, 1077412e9a14SMatthew 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, 1078412e9a14SMatthew 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, 1079412e9a14SMatthew 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, 1080412e9a14SMatthew 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, 1081412e9a14SMatthew 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, 1082412e9a14SMatthew 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}; 1083412e9a14SMatthew G. Knepley static PetscInt hexO[] = {0, 0, 1084412e9a14SMatthew G. Knepley 0, 0, 1085412e9a14SMatthew G. Knepley 0, 0, 1086412e9a14SMatthew G. Knepley 0, 0, 1087412e9a14SMatthew G. Knepley 0, 0, 1088412e9a14SMatthew G. Knepley 0, 0, 1089412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1090412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1091412e9a14SMatthew G. Knepley -2, -2, 0, 0, 1092412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1093412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1094412e9a14SMatthew G. Knepley -2, -2, 0, 0, 1095412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1096412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1097412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1098412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1099412e9a14SMatthew G. Knepley -2, -2, 0, 0, 1100412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1101412e9a14SMatthew G. Knepley 0, 0, 0, 0, -4, 0, 1102412e9a14SMatthew G. Knepley 0, 0, -1, 0, -4, 0, 1103412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1104412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 1105412e9a14SMatthew G. Knepley -4, 0, 0, 0, -4, 0, 1106412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, 0, 1107412e9a14SMatthew G. Knepley -4, 0, -1, 0, 0, 0, 1108412e9a14SMatthew G. Knepley -4, 0, -1, 0, -4, 0}; 1109412e9a14SMatthew G. Knepley /* Add 3 quads inside every triangular prism, making 4 new prisms. */ 1110412e9a14SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_TRI_PRISM}; 1111412e9a14SMatthew G. Knepley static PetscInt tripS[] = {3, 4, 6, 8}; 1112412e9a14SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 3, 0, 1113412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 1, 4, 0, 1114412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 1, 2, 0, 1115412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 4, 1, 1116412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 0, 1117412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, 1118412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 1119412e9a14SMatthew 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, 1120412e9a14SMatthew 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, 1121412e9a14SMatthew 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, 1122412e9a14SMatthew 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, 1123412e9a14SMatthew 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, 1124412e9a14SMatthew 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, 1125412e9a14SMatthew 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, 1126412e9a14SMatthew 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, 1127412e9a14SMatthew 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, 1128412e9a14SMatthew 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, 1129412e9a14SMatthew 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, 1130412e9a14SMatthew 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, 1131412e9a14SMatthew 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, 1132412e9a14SMatthew 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}; 1133412e9a14SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 1134412e9a14SMatthew G. Knepley 0, 0, 1135412e9a14SMatthew G. Knepley 0, 0, 1136412e9a14SMatthew G. Knepley 0, -2, -2, 1137412e9a14SMatthew G. Knepley -2, 0, -2, 1138412e9a14SMatthew G. Knepley -2, -2, 0, 1139412e9a14SMatthew G. Knepley 0, 0, 0, 1140412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1141412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1142412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1143412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1144412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1145412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1146412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1147412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1148412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 1149412e9a14SMatthew G. Knepley 2, 0, 0, 0, 0, 1150412e9a14SMatthew G. Knepley -3, 0, 0, -1, 0, 1151412e9a14SMatthew G. Knepley -3, 0, 0, 0, -1, 1152412e9a14SMatthew G. Knepley -3, 0, -1, 0, 0, 1153412e9a14SMatthew G. Knepley -3, 0, 0, 0, 0}; 1154412e9a14SMatthew G. Knepley /* Add 3 tensor quads inside every tensor triangular prism, making 4 new prisms. 1155412e9a14SMatthew G. Knepley 2 1156412e9a14SMatthew G. Knepley |\ 1157412e9a14SMatthew G. Knepley | \ 1158412e9a14SMatthew G. Knepley | \ 1159412e9a14SMatthew G. Knepley 0---1 116075d3a19aSMatthew G. Knepley 1161412e9a14SMatthew G. Knepley 2 116275d3a19aSMatthew G. Knepley 1163412e9a14SMatthew G. Knepley 0 1 116475d3a19aSMatthew G. Knepley 1165412e9a14SMatthew G. Knepley 2 1166412e9a14SMatthew G. Knepley |\ 1167412e9a14SMatthew G. Knepley | \ 1168412e9a14SMatthew G. Knepley | \ 1169412e9a14SMatthew G. Knepley 0---1 1170412e9a14SMatthew G. Knepley */ 1171412e9a14SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_TRI_PRISM_TENSOR}; 1172412e9a14SMatthew G. Knepley static PetscInt ttripS[] = {3, 4}; 1173412e9a14SMatthew 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, 1174412e9a14SMatthew 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, 1175412e9a14SMatthew 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, 1176412e9a14SMatthew 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, 1177412e9a14SMatthew 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, 1178412e9a14SMatthew 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, 1179412e9a14SMatthew 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}; 1180412e9a14SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 0, 0, 1181412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1182412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1183412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1184412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1185412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 1186412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0}; 1187412e9a14SMatthew G. Knepley /* Add 1 edge and 4 tensor quads inside every tensor quad prism, making 4 new prisms. */ 1188412e9a14SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1189412e9a14SMatthew G. Knepley static PetscInt tquadpS[] = {1, 4, 4}; 1190412e9a14SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1191412e9a14SMatthew 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, 1192412e9a14SMatthew 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, 1193412e9a14SMatthew 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, 1194412e9a14SMatthew 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, 1195412e9a14SMatthew 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, 1196412e9a14SMatthew 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, 1197412e9a14SMatthew 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, 1198412e9a14SMatthew 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}; 1199412e9a14SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 1200412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1201412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1202412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1203412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1204412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1205412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1206412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1207412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 120875d3a19aSMatthew G. Knepley 1209412e9a14SMatthew G. Knepley PetscFunctionBegin; 1210412e9a14SMatthew G. Knepley switch (source) { 1211412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break; 1212412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nt = 2; *target = edgeT; *size = edgeS; *cone = edgeC; *ornt = edgeO; break; 1213412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 1214412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 2; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1215412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nt = 3; *target = quadT; *size = quadS; *cone = quadC; *ornt = quadO; break; 1216412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 2; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 1217412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 3; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1218412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nt = 4; *target = hexT; *size = hexS; *cone = hexC; *ornt = hexO; break; 1219412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1220412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 2; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 1221412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 1222412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1223412e9a14SMatthew G. Knepley } 1224412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1225412e9a14SMatthew G. Knepley } 122675d3a19aSMatthew G. Knepley 122796ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerRefine_ToBox(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1228412e9a14SMatthew G. Knepley { 1229412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1230412e9a14SMatthew G. Knepley /* Change tensor edges to segments */ 1231412e9a14SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_SEGMENT}; 1232412e9a14SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 1233412e9a14SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 1234412e9a14SMatthew G. Knepley static PetscInt tedgeO[] = { 0, 0}; 1235412e9a14SMatthew G. Knepley /* Add 1 vertex, 3 edges inside every triangle, making 3 new quadrilaterals. 1236e5337592SStefano Zampini 2 1237e5337592SStefano Zampini |\ 1238e5337592SStefano Zampini | \ 1239e5337592SStefano Zampini | \ 1240e5337592SStefano Zampini | \ 1241412e9a14SMatthew G. Knepley 0 1 1242412e9a14SMatthew G. Knepley | \ 1243e5337592SStefano Zampini | \ 1244e5337592SStefano Zampini 2 1 1245e5337592SStefano Zampini |\ / \ 1246e5337592SStefano Zampini | 2 1 \ 1247e5337592SStefano Zampini | \ / \ 1248412e9a14SMatthew G. Knepley 1 | 0 1249e5337592SStefano Zampini | 0 \ 1250e5337592SStefano Zampini | | \ 1251412e9a14SMatthew G. Knepley | | \ 1252412e9a14SMatthew G. Knepley 0-0-0-----1-----1 1253e5337592SStefano Zampini */ 1254412e9a14SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 1255412e9a14SMatthew G. Knepley static PetscInt triS[] = {1, 3, 3}; 1256412e9a14SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1257412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1258412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1259412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 1260412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1261412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0}; 1262412e9a14SMatthew G. Knepley static PetscInt triO[] = {0, 0, 1263412e9a14SMatthew G. Knepley 0, 0, 1264412e9a14SMatthew G. Knepley 0, 0, 1265412e9a14SMatthew G. Knepley 0, 0, -2, 0, 1266412e9a14SMatthew G. Knepley 0, 0, 0, -2, 1267412e9a14SMatthew G. Knepley 0, -2, 0, 0}; 1268412e9a14SMatthew G. Knepley /* Add 1 edge inside every tensor quad, making 2 new quadrilaterals 1269412e9a14SMatthew G. Knepley 2----2----1----3----3 12704330a3fcSStefano Zampini | | | 12714330a3fcSStefano Zampini | | | 12724330a3fcSStefano Zampini | | | 1273412e9a14SMatthew G. Knepley 4 A 6 B 5 12744330a3fcSStefano Zampini | | | 1275412e9a14SMatthew G. Knepley | | | 1276412e9a14SMatthew G. Knepley | | | 1277412e9a14SMatthew G. Knepley 0----0----0----1----1 12784330a3fcSStefano Zampini */ 1279412e9a14SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 1280412e9a14SMatthew G. Knepley static PetscInt tquadS[] = {1, 2}; 1281412e9a14SMatthew G. Knepley static PetscInt tquadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1282412e9a14SMatthew G. Knepley /* TODO Fix these */ 1283412e9a14SMatthew 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, 1284412e9a14SMatthew 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}; 1285412e9a14SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 1286412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1287412e9a14SMatthew G. Knepley 0, 0, -2, -2}; 1288412e9a14SMatthew G. Knepley /* Add 6 triangles inside every cell, making 4 new hexs 1289412e9a14SMatthew G. Knepley TODO: Need different SubcellMap(). Need to make a struct with the function pointers in it 1290412e9a14SMatthew 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 1291412e9a14SMatthew 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] 1292412e9a14SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 1293412e9a14SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 1294412e9a14SMatthew G. Knepley We make a new hex in each corner 1295412e9a14SMatthew G. Knepley [v0, (e0, 0), (f0, 0), (e2, 0), (e3, 0), (f2, 0), (c0, 0), (f1, 0)] 1296412e9a14SMatthew G. Knepley [v1, (e4, 0), (f3, 0), (e1, 0), (e0, 0), (f0, 0), (c0, 0), (f1, 0)] 1297412e9a14SMatthew G. Knepley [v2, (e1, 0), (f3, 0), (e5, 0), (e2, 0), (f2, 0), (c0, 0), (f0, 0)] 1298412e9a14SMatthew G. Knepley [v3, (e4, 0), (f1, 0), (e3, 0), (e5, 0), (f2, 0), (c0, 0), (f3, 0)] 1299412e9a14SMatthew G. Knepley We create a new face for each edge 1300412e9a14SMatthew G. Knepley [(e3, 0), (f2, 0), (c0, 0), (f1, 0)] 1301412e9a14SMatthew G. Knepley [(f0, 0), (e0, 0), (f1, 0), (c0, 0)] 1302412e9a14SMatthew G. Knepley [(e2, 0), (f0, 0), (c0, 0), (f2, 0)] 1303412e9a14SMatthew G. Knepley [(f3, 0), (e4, 0), (f1, 0), (c0, 0)] 1304412e9a14SMatthew G. Knepley [(e1, 0), (f3, 0), (c0, 0), (f0, 0)] 1305412e9a14SMatthew G. Knepley [(e5, 0), (f3, 0), (c0, 0), (f2, 0)] 1306412e9a14SMatthew 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. 130775d3a19aSMatthew G. Knepley */ 1308412e9a14SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1309412e9a14SMatthew G. Knepley static PetscInt tetS[] = {1, 4, 6, 4}; 1310412e9a14SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1311412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1312412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1313412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1314412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, 1315412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1316412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1317412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 3, 1318412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1, 1319412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 1320412e9a14SMatthew 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, 1321412e9a14SMatthew 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, 1322412e9a14SMatthew 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, 1323412e9a14SMatthew 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}; 1324412e9a14SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 1325412e9a14SMatthew G. Knepley 0, 0, 1326412e9a14SMatthew G. Knepley 0, 0, 1327412e9a14SMatthew G. Knepley 0, 0, 1328412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1329412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1330412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1331412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1332412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1333412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1334412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 1335412e9a14SMatthew G. Knepley 1, -1, 1, 0, 0, 3, 1336412e9a14SMatthew G. Knepley 0, -4, 1, -1, 0, 3, 1337412e9a14SMatthew G. Knepley 1, -4, 3, -2, -4, 3}; 1338412e9a14SMatthew G. Knepley /* Add 3 quads inside every triangular prism, making 4 new prisms. */ 1339412e9a14SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1340412e9a14SMatthew G. Knepley static PetscInt tripS[] = {1, 5, 9, 6}; 1341412e9a14SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1342412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1343412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1344412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1345412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0, 1346412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 1, 1347412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, 1348412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, 1349412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1350412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 0, 1351412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 0, 1352412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 2, 1353412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 3, 2, 1354412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 4, 2, 1355412e9a14SMatthew 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, 1356412e9a14SMatthew 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, 1357412e9a14SMatthew 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, 1358412e9a14SMatthew 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, 1359412e9a14SMatthew 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, 1360412e9a14SMatthew 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}; 1361412e9a14SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 1362412e9a14SMatthew G. Knepley 0, 0, 1363412e9a14SMatthew G. Knepley 0, 0, 1364412e9a14SMatthew G. Knepley 0, 0, 1365412e9a14SMatthew G. Knepley 0, 0, 1366412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1367412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1368412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1369412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1370412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1371412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1372412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1373412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1374412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1375412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1, 1376412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -4, 1377412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1, 1378412e9a14SMatthew G. Knepley -4, 0, 0, -1, 0, 1, 1379412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, -4, 1380412e9a14SMatthew G. Knepley -4, 0, 0, 0, -1, 1}; 1381412e9a14SMatthew G. Knepley /* Add 3 tensor quads inside every tensor triangular prism, making 4 new tensor triangular prisms. 1382412e9a14SMatthew G. Knepley 2 1383412e9a14SMatthew G. Knepley |\ 1384412e9a14SMatthew G. Knepley | \ 1385412e9a14SMatthew G. Knepley | \ 1386412e9a14SMatthew G. Knepley 0---1 138775d3a19aSMatthew G. Knepley 1388412e9a14SMatthew G. Knepley 2 138975d3a19aSMatthew G. Knepley 1390412e9a14SMatthew G. Knepley 0 1 139175d3a19aSMatthew G. Knepley 1392412e9a14SMatthew G. Knepley 2 1393412e9a14SMatthew G. Knepley |\ 1394412e9a14SMatthew G. Knepley | \ 1395412e9a14SMatthew G. Knepley | \ 1396412e9a14SMatthew G. Knepley 0---1 139775d3a19aSMatthew G. Knepley */ 1398412e9a14SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1399412e9a14SMatthew G. Knepley static PetscInt ttripS[] = {1, 3, 3}; 1400412e9a14SMatthew G. Knepley static PetscInt ttripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1401412e9a14SMatthew 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, 1402412e9a14SMatthew 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, 1403412e9a14SMatthew 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, 1404412e9a14SMatthew 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, 1405412e9a14SMatthew 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, 1406412e9a14SMatthew 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}; 1407412e9a14SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 1408412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1409412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1410412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1411412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1412412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1413412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 1414412e9a14SMatthew G. Knepley /* TODO Add 3 quads inside every tensor triangular prism, making 4 new triangular prisms. 1415412e9a14SMatthew G. Knepley 2 1416412e9a14SMatthew G. Knepley |\ 1417412e9a14SMatthew G. Knepley | \ 1418412e9a14SMatthew G. Knepley | \ 1419412e9a14SMatthew G. Knepley 0---1 142075d3a19aSMatthew G. Knepley 1421412e9a14SMatthew G. Knepley 2 142275d3a19aSMatthew G. Knepley 1423412e9a14SMatthew G. Knepley 0 1 142475d3a19aSMatthew G. Knepley 1425412e9a14SMatthew G. Knepley 2 1426412e9a14SMatthew G. Knepley |\ 1427412e9a14SMatthew G. Knepley | \ 1428412e9a14SMatthew G. Knepley | \ 1429412e9a14SMatthew G. Knepley 0---1 1430a97b51b8SMatthew G. Knepley */ 1431412e9a14SMatthew G. Knepley static DMPolytopeType ctripT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1432412e9a14SMatthew G. Knepley static PetscInt ctripS[] = {1, 3, 3}; 1433412e9a14SMatthew G. Knepley static PetscInt ctripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1434412e9a14SMatthew 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, 1435412e9a14SMatthew 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, 1436412e9a14SMatthew 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, 1437412e9a14SMatthew 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, 1438412e9a14SMatthew 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, 1439412e9a14SMatthew 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}; 1440412e9a14SMatthew G. Knepley static PetscInt ctripO[] = {0, 0, 1441412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1442412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1443412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1444412e9a14SMatthew G. Knepley -4, 0, 0, -1, 0, 1, 1445412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, -4, 1446412e9a14SMatthew G. Knepley -4, 0, 0, 0, -1, 1}; 1447412e9a14SMatthew G. Knepley /* Add 1 edge and 4 quads inside every tensor quad prism, making 4 new hexahedra. */ 1448412e9a14SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1449412e9a14SMatthew G. Knepley static PetscInt tquadpS[] = {1, 4, 4}; 1450412e9a14SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1451412e9a14SMatthew 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, 1452412e9a14SMatthew 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, 1453412e9a14SMatthew 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, 1454412e9a14SMatthew 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, 1455412e9a14SMatthew 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, 1456412e9a14SMatthew 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, 1457412e9a14SMatthew 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, 1458412e9a14SMatthew 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}; 1459412e9a14SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 1460412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1461412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1462412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1463412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1464412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1465412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1466412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1467412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 1468412e9a14SMatthew G. Knepley PetscBool convertTensor = PETSC_TRUE; 1469a97b51b8SMatthew G. Knepley 1470412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 1471412e9a14SMatthew G. Knepley if (convertTensor) { 1472412e9a14SMatthew G. Knepley switch (source) { 1473412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1474412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1475412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1476412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1477412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1478a97b51b8SMatthew G. Knepley break; 1479412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 1480412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 2; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 1481412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 3; *target = ctripT; *size = ctripS; *cone = ctripC; *ornt = ctripO; break; 1482412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 1483412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1484412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1485412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1486412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1487b5da9499SMatthew G. Knepley } 1488b5da9499SMatthew G. Knepley } else { 1489412e9a14SMatthew G. Knepley switch (source) { 1490412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1491412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1492412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1493412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1494412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1495412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1496412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1497412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1498b5da9499SMatthew G. Knepley break; 1499412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1500412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1501412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1502412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 3; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 1503412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 150427fcede3SMatthew G. Knepley } 150575d3a19aSMatthew G. Knepley } 150675d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 150775d3a19aSMatthew G. Knepley } 150875d3a19aSMatthew G. Knepley 1509412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 151075d3a19aSMatthew G. Knepley { 1511412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1512412e9a14SMatthew G. Knepley 1513412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 1514412e9a14SMatthew G. Knepley switch (source) { 1515412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1516412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1517412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1518412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1519412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 1520412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1521412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 1522412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1523412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1524412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1525412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1526412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1527412e9a14SMatthew G. Knepley break; 1528412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1529412e9a14SMatthew G. Knepley } 1530412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1531412e9a14SMatthew G. Knepley } 1532412e9a14SMatthew G. Knepley 1533cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Alfeld2D(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1534cf4091a3SMatthew G. Knepley { 1535cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 1536cf4091a3SMatthew G. Knepley /* Add 1 vertex, 3 edges inside every triangle, making 3 new triangles. 1537cf4091a3SMatthew G. Knepley 2 1538cf4091a3SMatthew G. Knepley |\ 1539cf4091a3SMatthew G. Knepley |\\ 1540cf4091a3SMatthew G. Knepley | |\ 1541cf4091a3SMatthew G. Knepley | \ \ 1542cf4091a3SMatthew G. Knepley | | \ 1543cf4091a3SMatthew G. Knepley | \ \ 1544cf4091a3SMatthew G. Knepley | | \ 1545cf4091a3SMatthew G. Knepley 2 \ \ 1546cf4091a3SMatthew G. Knepley | | 1 1547cf4091a3SMatthew G. Knepley | 2 \ 1548cf4091a3SMatthew G. Knepley | | \ 1549cf4091a3SMatthew G. Knepley | /\ \ 1550cf4091a3SMatthew G. Knepley | 0 1 | 1551cf4091a3SMatthew G. Knepley | / \ | 1552cf4091a3SMatthew G. Knepley |/ \| 1553cf4091a3SMatthew G. Knepley 0---0----1 1554cf4091a3SMatthew G. Knepley */ 1555cf4091a3SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE}; 1556cf4091a3SMatthew G. Knepley static PetscInt triS[] = {1, 3, 3}; 1557cf4091a3SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1558cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 2, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1559cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 2, 2, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1560cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1561cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, 1562cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2}; 1563cf4091a3SMatthew G. Knepley static PetscInt triO[] = {0, 0, 1564cf4091a3SMatthew G. Knepley 0, 0, 1565cf4091a3SMatthew G. Knepley 0, 0, 1566cf4091a3SMatthew G. Knepley 0, 0, -2, 1567cf4091a3SMatthew G. Knepley 0, 0, -2, 1568cf4091a3SMatthew G. Knepley 0, 0, -2}; 1569cf4091a3SMatthew G. Knepley 1570cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 1571cf4091a3SMatthew G. Knepley switch (source) { 1572cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT: 1573cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1574cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1575cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1576cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1577cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 1578cf4091a3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1579cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1580cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 1581cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1582cf4091a3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1583cf4091a3SMatthew G. Knepley break; 1584cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1585cf4091a3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1586cf4091a3SMatthew G. Knepley } 1587cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 1588cf4091a3SMatthew G. Knepley } 1589cf4091a3SMatthew G. Knepley 1590cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Alfeld3D(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1591cf4091a3SMatthew G. Knepley { 1592cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 1593cf4091a3SMatthew G. Knepley /* Add 6 triangles inside every cell, making 4 new tets 1594cf4091a3SMatthew 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 1595cf4091a3SMatthew 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] 1596cf4091a3SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 1597cf4091a3SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 1598cf4091a3SMatthew G. Knepley We make a new tet on each face 1599cf4091a3SMatthew G. Knepley [v0, v1, v2, (c0, 0)] 1600cf4091a3SMatthew G. Knepley [v0, v3, v1, (c0, 0)] 1601cf4091a3SMatthew G. Knepley [v0, v2, v3, (c0, 0)] 1602cf4091a3SMatthew G. Knepley [v2, v1, v3, (c0, 0)] 1603cf4091a3SMatthew G. Knepley We create a new face for each edge 1604cf4091a3SMatthew G. Knepley [v0, (c0, 0), v1 ] 1605cf4091a3SMatthew G. Knepley [v0, v2, (c0, 0)] 1606cf4091a3SMatthew G. Knepley [v2, v1, (c0, 0)] 1607cf4091a3SMatthew G. Knepley [v0, (c0, 0), v3 ] 1608cf4091a3SMatthew G. Knepley [v1, v3, (c0, 0)] 1609cf4091a3SMatthew G. Knepley [v3, v2, (c0, 0)] 1610cf4091a3SMatthew G. Knepley */ 1611cf4091a3SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON}; 1612cf4091a3SMatthew G. Knepley static PetscInt tetS[] = {1, 4, 6, 4}; 1613cf4091a3SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 3, 0, 0, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1614cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 3, 0, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1615cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 3, 0, 2, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1616cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 3, 1, 0, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1617cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 2, 0, 0, 0, 1618cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 0, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, 1619cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 0, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 1620cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 2, 1, 0, 0, 1621cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 1, 1622cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 2, 1, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 3, 1623cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 2, 1624cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 4, 1625cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 5, 1626cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 3, 0, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 4}; 1627cf4091a3SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 1628cf4091a3SMatthew G. Knepley 0, 0, 1629cf4091a3SMatthew G. Knepley 0, 0, 1630cf4091a3SMatthew G. Knepley 0, 0, 1631cf4091a3SMatthew G. Knepley 0, -2, -2, 1632cf4091a3SMatthew G. Knepley -2, 0, -2, 1633cf4091a3SMatthew G. Knepley -2, 0, -2, 1634cf4091a3SMatthew G. Knepley 0, -2, -2, 1635cf4091a3SMatthew G. Knepley -2, 0, -2, 1636cf4091a3SMatthew G. Knepley -2, 0, -2, 1637cf4091a3SMatthew G. Knepley 0, 0, 0, 0, 1638cf4091a3SMatthew G. Knepley 0, 0, -3, 0, 1639cf4091a3SMatthew G. Knepley 0, -3, -3, 0, 1640cf4091a3SMatthew G. Knepley 0, -3, -1, -1}; 1641cf4091a3SMatthew G. Knepley 1642cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 1643cf4091a3SMatthew G. Knepley switch (source) { 1644cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT: 1645cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1646cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1647cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1648cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1649cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1650cf4091a3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1651cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1652cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 1653cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1654cf4091a3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1655cf4091a3SMatthew G. Knepley break; 1656cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1657cf4091a3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1658cf4091a3SMatthew G. Knepley } 1659cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 1660cf4091a3SMatthew G. Knepley } 1661cf4091a3SMatthew G. Knepley 1662*a5801f52SStefano Zampini typedef struct { 1663*a5801f52SStefano Zampini PetscInt n; 1664*a5801f52SStefano Zampini PetscReal r; 1665*a5801f52SStefano Zampini PetscScalar *h; 1666*a5801f52SStefano Zampini PetscInt *Nt; 1667*a5801f52SStefano Zampini DMPolytopeType **target; 1668*a5801f52SStefano Zampini PetscInt **size; 1669*a5801f52SStefano Zampini PetscInt **cone; 1670*a5801f52SStefano Zampini PetscInt **ornt; 1671*a5801f52SStefano Zampini } PlexRefiner_BL; 1672*a5801f52SStefano Zampini 1673*a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerSetUp_BL(DMPlexCellRefiner cr) 1674*a5801f52SStefano Zampini { 1675*a5801f52SStefano Zampini PlexRefiner_BL *crbl; 1676*a5801f52SStefano Zampini PetscErrorCode ierr; 1677*a5801f52SStefano Zampini PetscInt i,n; 1678*a5801f52SStefano Zampini PetscReal r; 1679*a5801f52SStefano Zampini PetscInt c1,c2,o1,o2; 1680*a5801f52SStefano Zampini 1681*a5801f52SStefano Zampini PetscFunctionBegin; 1682*a5801f52SStefano Zampini ierr = PetscNew(&crbl);CHKERRQ(ierr); 1683*a5801f52SStefano Zampini cr->data = crbl; 1684*a5801f52SStefano Zampini crbl->n = 1; /* 1 split -> 2 new cells */ 1685*a5801f52SStefano Zampini crbl->r = 1; /* linear progression */ 1686*a5801f52SStefano Zampini 1687*a5801f52SStefano Zampini /* TODO: add setfromoptions to the refiners? */ 1688*a5801f52SStefano Zampini ierr = PetscOptionsGetInt(((PetscObject) cr->dm)->options,((PetscObject) cr->dm)->prefix, "-dm_plex_refine_boundarylayer_splits", &crbl->n, NULL);CHKERRQ(ierr); 1689*a5801f52SStefano Zampini if (crbl->n < 1) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Number of splits %D must be positive",crbl->n); 1690*a5801f52SStefano Zampini ierr = PetscOptionsGetReal(((PetscObject) cr->dm)->options,((PetscObject) cr->dm)->prefix, "-dm_plex_refine_boundarylayer_progression", &crbl->r, NULL);CHKERRQ(ierr); 1691*a5801f52SStefano Zampini n = crbl->n; 1692*a5801f52SStefano Zampini r = crbl->r; 1693*a5801f52SStefano Zampini 1694*a5801f52SStefano 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 */ 1695*a5801f52SStefano Zampini ierr = PetscMalloc5(4,&crbl->Nt,4,&crbl->target,4,&crbl->size,4,&crbl->cone,4,&crbl->ornt);CHKERRQ(ierr); 1696*a5801f52SStefano Zampini 1697*a5801f52SStefano Zampini /* progression */ 1698*a5801f52SStefano Zampini ierr = PetscMalloc1(n,&crbl->h);CHKERRQ(ierr); 1699*a5801f52SStefano Zampini if (r > 1) { 1700*a5801f52SStefano Zampini PetscReal d = (r-1.)/(PetscPowRealInt(r,n+1)-1.); 1701*a5801f52SStefano Zampini 1702*a5801f52SStefano Zampini crbl->h[0] = d; 1703*a5801f52SStefano Zampini for (i = 1; i < n; i++) { 1704*a5801f52SStefano Zampini d *= r; 1705*a5801f52SStefano Zampini crbl->h[i] = crbl->h[i-1] + d; 1706*a5801f52SStefano Zampini } 1707*a5801f52SStefano Zampini } else { /* linear */ 1708*a5801f52SStefano Zampini for (i = 0; i < n; i++) crbl->h[i] = (i + 1.)/(n+1); /* linear */ 1709*a5801f52SStefano Zampini } 1710*a5801f52SStefano Zampini 1711*a5801f52SStefano Zampini /* DM_POLYTOPE_POINT_PRISM_TENSOR produces n points and n+1 tensor segments */ 1712*a5801f52SStefano Zampini c1 = 14+6*(n-1); 1713*a5801f52SStefano Zampini o1 = 2*(n+1); 1714*a5801f52SStefano Zampini crbl->Nt[0] = 2; 1715*a5801f52SStefano Zampini 1716*a5801f52SStefano 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); 1717*a5801f52SStefano Zampini 1718*a5801f52SStefano Zampini crbl->target[0][0] = DM_POLYTOPE_POINT; 1719*a5801f52SStefano Zampini crbl->target[0][1] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1720*a5801f52SStefano Zampini 1721*a5801f52SStefano Zampini crbl->size[0][0] = n; 1722*a5801f52SStefano Zampini crbl->size[0][1] = n+1; 1723*a5801f52SStefano Zampini 1724*a5801f52SStefano Zampini /* the tensor segments */ 1725*a5801f52SStefano Zampini crbl->cone[0][0] = DM_POLYTOPE_POINT; 1726*a5801f52SStefano Zampini crbl->cone[0][1] = 1; 1727*a5801f52SStefano Zampini crbl->cone[0][2] = 0; 1728*a5801f52SStefano Zampini crbl->cone[0][3] = 0; 1729*a5801f52SStefano Zampini crbl->cone[0][4] = DM_POLYTOPE_POINT; 1730*a5801f52SStefano Zampini crbl->cone[0][5] = 0; 1731*a5801f52SStefano Zampini crbl->cone[0][6] = 0; 1732*a5801f52SStefano Zampini for (i = 0; i < n-1; i++) { 1733*a5801f52SStefano Zampini crbl->cone[0][7+6*i+0] = DM_POLYTOPE_POINT; 1734*a5801f52SStefano Zampini crbl->cone[0][7+6*i+1] = 0; 1735*a5801f52SStefano Zampini crbl->cone[0][7+6*i+2] = i; 1736*a5801f52SStefano Zampini crbl->cone[0][7+6*i+3] = DM_POLYTOPE_POINT; 1737*a5801f52SStefano Zampini crbl->cone[0][7+6*i+4] = 0; 1738*a5801f52SStefano Zampini crbl->cone[0][7+6*i+5] = i+1; 1739*a5801f52SStefano Zampini } 1740*a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+0] = DM_POLYTOPE_POINT; 1741*a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+1] = 0; 1742*a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+2] = n-1; 1743*a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+3] = DM_POLYTOPE_POINT; 1744*a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+4] = 1; 1745*a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+5] = 1; 1746*a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+6] = 0; 1747*a5801f52SStefano Zampini for (i = 0; i < o1; i++) crbl->ornt[0][i] = 0; 1748*a5801f52SStefano Zampini 1749*a5801f52SStefano Zampini /* DM_POLYTOPE_SEG_PRISM_TENSOR produces n segments and n+1 tensor quads */ 1750*a5801f52SStefano Zampini c1 = 8*n; 1751*a5801f52SStefano Zampini c2 = 30+14*(n-1); 1752*a5801f52SStefano Zampini o1 = 2*n; 1753*a5801f52SStefano Zampini o2 = 4*(n+1); 1754*a5801f52SStefano Zampini crbl->Nt[1] = 2; 1755*a5801f52SStefano Zampini 1756*a5801f52SStefano 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); 1757*a5801f52SStefano Zampini 1758*a5801f52SStefano Zampini crbl->target[1][0] = DM_POLYTOPE_SEGMENT; 1759*a5801f52SStefano Zampini crbl->target[1][1] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1760*a5801f52SStefano Zampini 1761*a5801f52SStefano Zampini crbl->size[1][0] = n; 1762*a5801f52SStefano Zampini crbl->size[1][1] = n+1; 1763*a5801f52SStefano Zampini 1764*a5801f52SStefano Zampini /* the segments */ 1765*a5801f52SStefano Zampini for (i = 0; i < n; i++) { 1766*a5801f52SStefano Zampini crbl->cone[1][8*i+0] = DM_POLYTOPE_POINT; 1767*a5801f52SStefano Zampini crbl->cone[1][8*i+1] = 1; 1768*a5801f52SStefano Zampini crbl->cone[1][8*i+2] = 2; 1769*a5801f52SStefano Zampini crbl->cone[1][8*i+3] = i; 1770*a5801f52SStefano Zampini crbl->cone[1][8*i+4] = DM_POLYTOPE_POINT; 1771*a5801f52SStefano Zampini crbl->cone[1][8*i+5] = 1; 1772*a5801f52SStefano Zampini crbl->cone[1][8*i+6] = 3; 1773*a5801f52SStefano Zampini crbl->cone[1][8*i+7] = i; 1774*a5801f52SStefano Zampini } 1775*a5801f52SStefano Zampini 1776*a5801f52SStefano Zampini /* the tensor quads */ 1777*a5801f52SStefano Zampini crbl->cone[1][c1+ 0] = DM_POLYTOPE_SEGMENT; 1778*a5801f52SStefano Zampini crbl->cone[1][c1+ 1] = 1; 1779*a5801f52SStefano Zampini crbl->cone[1][c1+ 2] = 0; 1780*a5801f52SStefano Zampini crbl->cone[1][c1+ 3] = 0; 1781*a5801f52SStefano Zampini crbl->cone[1][c1+ 4] = DM_POLYTOPE_SEGMENT; 1782*a5801f52SStefano Zampini crbl->cone[1][c1+ 5] = 0; 1783*a5801f52SStefano Zampini crbl->cone[1][c1+ 6] = 0; 1784*a5801f52SStefano Zampini crbl->cone[1][c1+ 7] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1785*a5801f52SStefano Zampini crbl->cone[1][c1+ 8] = 1; 1786*a5801f52SStefano Zampini crbl->cone[1][c1+ 9] = 2; 1787*a5801f52SStefano Zampini crbl->cone[1][c1+10] = 0; 1788*a5801f52SStefano Zampini crbl->cone[1][c1+11] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1789*a5801f52SStefano Zampini crbl->cone[1][c1+12] = 1; 1790*a5801f52SStefano Zampini crbl->cone[1][c1+13] = 3; 1791*a5801f52SStefano Zampini crbl->cone[1][c1+14] = 0; 1792*a5801f52SStefano Zampini for (i = 0; i < n-1; i++) { 1793*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 0] = DM_POLYTOPE_SEGMENT; 1794*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 1] = 0; 1795*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 2] = i; 1796*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 3] = DM_POLYTOPE_SEGMENT; 1797*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 4] = 0; 1798*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 5] = i+1; 1799*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 6] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1800*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 7] = 1; 1801*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 8] = 2; 1802*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 9] = i+1; 1803*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+10] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1804*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+11] = 1; 1805*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+12] = 3; 1806*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+13] = i+1; 1807*a5801f52SStefano Zampini } 1808*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 0] = DM_POLYTOPE_SEGMENT; 1809*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 1] = 0; 1810*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 2] = n-1; 1811*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 3] = DM_POLYTOPE_SEGMENT; 1812*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 4] = 1; 1813*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 5] = 1; 1814*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 6] = 0; 1815*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 7] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1816*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 8] = 1; 1817*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 9] = 2; 1818*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+10] = n; 1819*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+11] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1820*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+12] = 1; 1821*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+13] = 3; 1822*a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+14] = n; 1823*a5801f52SStefano Zampini for (i = 0; i < o1+o2; i++) crbl->ornt[1][i] = 0; 1824*a5801f52SStefano Zampini 1825*a5801f52SStefano Zampini /* DM_POLYTOPE_TRI_PRISM_TENSOR produces n triangles and n+1 tensor triangular prisms */ 1826*a5801f52SStefano Zampini c1 = 12*n; 1827*a5801f52SStefano Zampini c2 = 38+18*(n-1); 1828*a5801f52SStefano Zampini o1 = 3*n; 1829*a5801f52SStefano Zampini o2 = 5*(n+1); 1830*a5801f52SStefano Zampini crbl->Nt[2] = 2; 1831*a5801f52SStefano Zampini 1832*a5801f52SStefano 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); 1833*a5801f52SStefano Zampini 1834*a5801f52SStefano Zampini crbl->target[2][0] = DM_POLYTOPE_TRIANGLE; 1835*a5801f52SStefano Zampini crbl->target[2][1] = DM_POLYTOPE_TRI_PRISM_TENSOR; 1836*a5801f52SStefano Zampini 1837*a5801f52SStefano Zampini crbl->size[2][0] = n; 1838*a5801f52SStefano Zampini crbl->size[2][1] = n+1; 1839*a5801f52SStefano Zampini 1840*a5801f52SStefano Zampini /* the triangles */ 1841*a5801f52SStefano Zampini for (i = 0; i < n; i++) { 1842*a5801f52SStefano Zampini crbl->cone[2][12*i+ 0] = DM_POLYTOPE_SEGMENT; 1843*a5801f52SStefano Zampini crbl->cone[2][12*i+ 1] = 1; 1844*a5801f52SStefano Zampini crbl->cone[2][12*i+ 2] = 2; 1845*a5801f52SStefano Zampini crbl->cone[2][12*i+ 3] = i; 1846*a5801f52SStefano Zampini crbl->cone[2][12*i+ 4] = DM_POLYTOPE_SEGMENT; 1847*a5801f52SStefano Zampini crbl->cone[2][12*i+ 5] = 1; 1848*a5801f52SStefano Zampini crbl->cone[2][12*i+ 6] = 3; 1849*a5801f52SStefano Zampini crbl->cone[2][12*i+ 7] = i; 1850*a5801f52SStefano Zampini crbl->cone[2][12*i+ 8] = DM_POLYTOPE_SEGMENT; 1851*a5801f52SStefano Zampini crbl->cone[2][12*i+ 9] = 1; 1852*a5801f52SStefano Zampini crbl->cone[2][12*i+10] = 4; 1853*a5801f52SStefano Zampini crbl->cone[2][12*i+11] = i; 1854*a5801f52SStefano Zampini } 1855*a5801f52SStefano Zampini 1856*a5801f52SStefano Zampini /* the triangular prisms */ 1857*a5801f52SStefano Zampini crbl->cone[2][c1+ 0] = DM_POLYTOPE_TRIANGLE; 1858*a5801f52SStefano Zampini crbl->cone[2][c1+ 1] = 1; 1859*a5801f52SStefano Zampini crbl->cone[2][c1+ 2] = 0; 1860*a5801f52SStefano Zampini crbl->cone[2][c1+ 3] = 0; 1861*a5801f52SStefano Zampini crbl->cone[2][c1+ 4] = DM_POLYTOPE_TRIANGLE; 1862*a5801f52SStefano Zampini crbl->cone[2][c1+ 5] = 0; 1863*a5801f52SStefano Zampini crbl->cone[2][c1+ 6] = 0; 1864*a5801f52SStefano Zampini crbl->cone[2][c1+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1865*a5801f52SStefano Zampini crbl->cone[2][c1+ 8] = 1; 1866*a5801f52SStefano Zampini crbl->cone[2][c1+ 9] = 2; 1867*a5801f52SStefano Zampini crbl->cone[2][c1+10] = 0; 1868*a5801f52SStefano Zampini crbl->cone[2][c1+11] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1869*a5801f52SStefano Zampini crbl->cone[2][c1+12] = 1; 1870*a5801f52SStefano Zampini crbl->cone[2][c1+13] = 3; 1871*a5801f52SStefano Zampini crbl->cone[2][c1+14] = 0; 1872*a5801f52SStefano Zampini crbl->cone[2][c1+15] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1873*a5801f52SStefano Zampini crbl->cone[2][c1+16] = 1; 1874*a5801f52SStefano Zampini crbl->cone[2][c1+17] = 4; 1875*a5801f52SStefano Zampini crbl->cone[2][c1+18] = 0; 1876*a5801f52SStefano Zampini for (i = 0; i < n-1; i++) { 1877*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 0] = DM_POLYTOPE_TRIANGLE; 1878*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 1] = 0; 1879*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 2] = i; 1880*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 3] = DM_POLYTOPE_TRIANGLE; 1881*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 4] = 0; 1882*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 5] = i+1; 1883*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 6] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1884*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 7] = 1; 1885*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 8] = 2; 1886*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 9] = i+1; 1887*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+10] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1888*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+11] = 1; 1889*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+12] = 3; 1890*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+13] = i+1; 1891*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+14] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1892*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+15] = 1; 1893*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+16] = 4; 1894*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+17] = i+1; 1895*a5801f52SStefano Zampini } 1896*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 0] = DM_POLYTOPE_TRIANGLE; 1897*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 1] = 0; 1898*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 2] = n-1; 1899*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 3] = DM_POLYTOPE_TRIANGLE; 1900*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 4] = 1; 1901*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 5] = 1; 1902*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 6] = 0; 1903*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1904*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 8] = 1; 1905*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 9] = 2; 1906*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+10] = n; 1907*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+11] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1908*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+12] = 1; 1909*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+13] = 3; 1910*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+14] = n; 1911*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+15] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1912*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+16] = 1; 1913*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+17] = 4; 1914*a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+18] = n; 1915*a5801f52SStefano Zampini for (i = 0; i < o1+o2; i++) crbl->ornt[2][i] = 0; 1916*a5801f52SStefano Zampini 1917*a5801f52SStefano Zampini /* DM_POLYTOPE_QUAD_PRISM_TENSOR produces n quads and n+1 tensor quad prisms */ 1918*a5801f52SStefano Zampini c1 = 16*n; 1919*a5801f52SStefano Zampini c2 = 46+22*(n-1); 1920*a5801f52SStefano Zampini o1 = 4*n; 1921*a5801f52SStefano Zampini o2 = 6*(n+1); 1922*a5801f52SStefano Zampini crbl->Nt[3] = 2; 1923*a5801f52SStefano Zampini 1924*a5801f52SStefano 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); 1925*a5801f52SStefano Zampini 1926*a5801f52SStefano Zampini crbl->target[3][0] = DM_POLYTOPE_QUADRILATERAL; 1927*a5801f52SStefano Zampini crbl->target[3][1] = DM_POLYTOPE_QUAD_PRISM_TENSOR; 1928*a5801f52SStefano Zampini 1929*a5801f52SStefano Zampini crbl->size[3][0] = n; 1930*a5801f52SStefano Zampini crbl->size[3][1] = n+1; 1931*a5801f52SStefano Zampini 1932*a5801f52SStefano Zampini /* the quads */ 1933*a5801f52SStefano Zampini for (i = 0; i < n; i++) { 1934*a5801f52SStefano Zampini crbl->cone[3][16*i+ 0] = DM_POLYTOPE_SEGMENT; 1935*a5801f52SStefano Zampini crbl->cone[3][16*i+ 1] = 1; 1936*a5801f52SStefano Zampini crbl->cone[3][16*i+ 2] = 2; 1937*a5801f52SStefano Zampini crbl->cone[3][16*i+ 3] = i; 1938*a5801f52SStefano Zampini crbl->cone[3][16*i+ 4] = DM_POLYTOPE_SEGMENT; 1939*a5801f52SStefano Zampini crbl->cone[3][16*i+ 5] = 1; 1940*a5801f52SStefano Zampini crbl->cone[3][16*i+ 6] = 3; 1941*a5801f52SStefano Zampini crbl->cone[3][16*i+ 7] = i; 1942*a5801f52SStefano Zampini crbl->cone[3][16*i+ 8] = DM_POLYTOPE_SEGMENT; 1943*a5801f52SStefano Zampini crbl->cone[3][16*i+ 9] = 1; 1944*a5801f52SStefano Zampini crbl->cone[3][16*i+10] = 4; 1945*a5801f52SStefano Zampini crbl->cone[3][16*i+11] = i; 1946*a5801f52SStefano Zampini crbl->cone[3][16*i+12] = DM_POLYTOPE_SEGMENT; 1947*a5801f52SStefano Zampini crbl->cone[3][16*i+13] = 1; 1948*a5801f52SStefano Zampini crbl->cone[3][16*i+14] = 5; 1949*a5801f52SStefano Zampini crbl->cone[3][16*i+15] = i; 1950*a5801f52SStefano Zampini } 1951*a5801f52SStefano Zampini 1952*a5801f52SStefano Zampini /* the quad prisms */ 1953*a5801f52SStefano Zampini crbl->cone[3][c1+ 0] = DM_POLYTOPE_QUADRILATERAL; 1954*a5801f52SStefano Zampini crbl->cone[3][c1+ 1] = 1; 1955*a5801f52SStefano Zampini crbl->cone[3][c1+ 2] = 0; 1956*a5801f52SStefano Zampini crbl->cone[3][c1+ 3] = 0; 1957*a5801f52SStefano Zampini crbl->cone[3][c1+ 4] = DM_POLYTOPE_QUADRILATERAL; 1958*a5801f52SStefano Zampini crbl->cone[3][c1+ 5] = 0; 1959*a5801f52SStefano Zampini crbl->cone[3][c1+ 6] = 0; 1960*a5801f52SStefano Zampini crbl->cone[3][c1+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1961*a5801f52SStefano Zampini crbl->cone[3][c1+ 8] = 1; 1962*a5801f52SStefano Zampini crbl->cone[3][c1+ 9] = 2; 1963*a5801f52SStefano Zampini crbl->cone[3][c1+10] = 0; 1964*a5801f52SStefano Zampini crbl->cone[3][c1+11] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1965*a5801f52SStefano Zampini crbl->cone[3][c1+12] = 1; 1966*a5801f52SStefano Zampini crbl->cone[3][c1+13] = 3; 1967*a5801f52SStefano Zampini crbl->cone[3][c1+14] = 0; 1968*a5801f52SStefano Zampini crbl->cone[3][c1+15] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1969*a5801f52SStefano Zampini crbl->cone[3][c1+16] = 1; 1970*a5801f52SStefano Zampini crbl->cone[3][c1+17] = 4; 1971*a5801f52SStefano Zampini crbl->cone[3][c1+18] = 0; 1972*a5801f52SStefano Zampini crbl->cone[3][c1+19] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1973*a5801f52SStefano Zampini crbl->cone[3][c1+20] = 1; 1974*a5801f52SStefano Zampini crbl->cone[3][c1+21] = 5; 1975*a5801f52SStefano Zampini crbl->cone[3][c1+22] = 0; 1976*a5801f52SStefano Zampini for (i = 0; i < n-1; i++) { 1977*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 0] = DM_POLYTOPE_QUADRILATERAL; 1978*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 1] = 0; 1979*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 2] = i; 1980*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 3] = DM_POLYTOPE_QUADRILATERAL; 1981*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 4] = 0; 1982*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 5] = i+1; 1983*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 6] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1984*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 7] = 1; 1985*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 8] = 2; 1986*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 9] = i+1; 1987*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+10] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1988*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+11] = 1; 1989*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+12] = 3; 1990*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+13] = i+1; 1991*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+14] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1992*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+15] = 1; 1993*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+16] = 4; 1994*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+17] = i+1; 1995*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+18] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1996*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+19] = 1; 1997*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+20] = 5; 1998*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+21] = i+1; 1999*a5801f52SStefano Zampini } 2000*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 0] = DM_POLYTOPE_QUADRILATERAL; 2001*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 1] = 0; 2002*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 2] = n-1; 2003*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 3] = DM_POLYTOPE_QUADRILATERAL; 2004*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 4] = 1; 2005*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 5] = 1; 2006*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 6] = 0; 2007*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2008*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 8] = 1; 2009*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 9] = 2; 2010*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+10] = n; 2011*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+11] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2012*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+12] = 1; 2013*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+13] = 3; 2014*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+14] = n; 2015*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+15] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2016*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+16] = 1; 2017*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+17] = 4; 2018*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+18] = n; 2019*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+19] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2020*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+20] = 1; 2021*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+21] = 5; 2022*a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+22] = n; 2023*a5801f52SStefano Zampini for (i = 0; i < o1+o2; i++) crbl->ornt[3][i] = 0; 2024*a5801f52SStefano Zampini PetscFunctionReturn(0); 2025*a5801f52SStefano Zampini } 2026*a5801f52SStefano Zampini 2027*a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerDestroy_BL(DMPlexCellRefiner cr) 2028*a5801f52SStefano Zampini { 2029*a5801f52SStefano Zampini PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data; 2030*a5801f52SStefano Zampini PetscErrorCode ierr; 2031*a5801f52SStefano Zampini 2032*a5801f52SStefano Zampini PetscFunctionBegin; 2033*a5801f52SStefano Zampini ierr = PetscFree4(crbl->target[0],crbl->size[0],crbl->cone[0],crbl->ornt[0]);CHKERRQ(ierr); 2034*a5801f52SStefano Zampini ierr = PetscFree4(crbl->target[1],crbl->size[1],crbl->cone[1],crbl->ornt[1]);CHKERRQ(ierr); 2035*a5801f52SStefano Zampini ierr = PetscFree4(crbl->target[2],crbl->size[2],crbl->cone[2],crbl->ornt[2]);CHKERRQ(ierr); 2036*a5801f52SStefano Zampini ierr = PetscFree4(crbl->target[3],crbl->size[3],crbl->cone[3],crbl->ornt[3]);CHKERRQ(ierr); 2037*a5801f52SStefano Zampini ierr = PetscFree5(crbl->Nt,crbl->target,crbl->size,crbl->cone,crbl->ornt);CHKERRQ(ierr); 2038*a5801f52SStefano Zampini ierr = PetscFree(crbl->h);CHKERRQ(ierr); 2039*a5801f52SStefano Zampini ierr = PetscFree(cr->data);CHKERRQ(ierr); 2040*a5801f52SStefano Zampini PetscFunctionReturn(0); 2041*a5801f52SStefano Zampini } 2042*a5801f52SStefano Zampini 2043cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_BL(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 2044cf4091a3SMatthew G. Knepley { 2045*a5801f52SStefano Zampini PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data; 2046cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 2047cf4091a3SMatthew G. Knepley 2048cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 2049cf4091a3SMatthew G. Knepley switch (source) { 2050*a5801f52SStefano Zampini case DM_POLYTOPE_POINT_PRISM_TENSOR: 2051*a5801f52SStefano Zampini *Nt = crbl->Nt[0]; 2052*a5801f52SStefano Zampini *target = crbl->target[0]; 2053*a5801f52SStefano Zampini *size = crbl->size[0]; 2054*a5801f52SStefano Zampini *cone = crbl->cone[0]; 2055*a5801f52SStefano Zampini *ornt = crbl->ornt[0]; 2056cf4091a3SMatthew G. Knepley break; 2057*a5801f52SStefano Zampini case DM_POLYTOPE_SEG_PRISM_TENSOR: 2058*a5801f52SStefano Zampini *Nt = crbl->Nt[1]; 2059*a5801f52SStefano Zampini *target = crbl->target[1]; 2060*a5801f52SStefano Zampini *size = crbl->size[1]; 2061*a5801f52SStefano Zampini *cone = crbl->cone[1]; 2062*a5801f52SStefano Zampini *ornt = crbl->ornt[1]; 2063*a5801f52SStefano Zampini break; 2064*a5801f52SStefano Zampini case DM_POLYTOPE_TRI_PRISM_TENSOR: 2065*a5801f52SStefano Zampini *Nt = crbl->Nt[2]; 2066*a5801f52SStefano Zampini *target = crbl->target[2]; 2067*a5801f52SStefano Zampini *size = crbl->size[2]; 2068*a5801f52SStefano Zampini *cone = crbl->cone[2]; 2069*a5801f52SStefano Zampini *ornt = crbl->ornt[2]; 2070*a5801f52SStefano Zampini break; 2071*a5801f52SStefano Zampini case DM_POLYTOPE_QUAD_PRISM_TENSOR: 2072*a5801f52SStefano Zampini *Nt = crbl->Nt[3]; 2073*a5801f52SStefano Zampini *target = crbl->target[3]; 2074*a5801f52SStefano Zampini *size = crbl->size[3]; 2075*a5801f52SStefano Zampini *cone = crbl->cone[3]; 2076*a5801f52SStefano Zampini *ornt = crbl->ornt[3]; 2077*a5801f52SStefano Zampini break; 2078*a5801f52SStefano Zampini default: 2079*a5801f52SStefano Zampini ierr = DMPlexCellRefinerRefine_None(cr,source,Nt,target,size,cone,ornt);CHKERRQ(ierr); 2080*a5801f52SStefano Zampini } 2081*a5801f52SStefano Zampini PetscFunctionReturn(0); 2082*a5801f52SStefano Zampini } 2083*a5801f52SStefano Zampini 2084*a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapSubcells_BL(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 2085*a5801f52SStefano Zampini { 2086*a5801f52SStefano Zampini /* We shift any input orientation in order to make it non-negative 2087*a5801f52SStefano 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) 2088*a5801f52SStefano Zampini The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 2089*a5801f52SStefano Zampini Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 2090*a5801f52SStefano Zampini */ 2091*a5801f52SStefano Zampini PetscInt tquad_seg_o[] = { 0, 1, -2, -1, 2092*a5801f52SStefano Zampini 0, 1, -2, -1, 2093*a5801f52SStefano Zampini -2, -1, 0, 1, 2094*a5801f52SStefano Zampini -2, -1, 0, 1}; 2095*a5801f52SStefano Zampini PetscInt tquad_tquad_o[] = { 0, 1, -2, -1, 2096*a5801f52SStefano Zampini 1, 0, -1, -2, 2097*a5801f52SStefano Zampini -2, -1, 0, 1, 2098*a5801f52SStefano Zampini -1, -2, 1, 0}; 2099*a5801f52SStefano Zampini PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data; 2100*a5801f52SStefano Zampini const PetscInt n = crbl->n; 2101*a5801f52SStefano Zampini PetscErrorCode ierr; 2102*a5801f52SStefano Zampini 2103*a5801f52SStefano Zampini PetscFunctionBeginHot; 2104*a5801f52SStefano Zampini *rnew = r; 2105*a5801f52SStefano Zampini *onew = o; 2106*a5801f52SStefano Zampini switch (pct) { 2107*a5801f52SStefano Zampini case DM_POLYTOPE_POINT_PRISM_TENSOR: 2108*a5801f52SStefano Zampini if (ct == DM_POLYTOPE_POINT_PRISM_TENSOR) { 2109*a5801f52SStefano Zampini if (po == 0 || po == -1) {*rnew = r; *onew = o;} 2110*a5801f52SStefano Zampini else if (po == 1 || po == -2) {*rnew = n - r; *onew = (o == 0 || o == -1) ? -2 : 0;} 2111*a5801f52SStefano Zampini else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid orientation %D for tensor segment", po); 2112*a5801f52SStefano Zampini } 2113*a5801f52SStefano Zampini break; 2114*a5801f52SStefano Zampini case DM_POLYTOPE_SEG_PRISM_TENSOR: 2115*a5801f52SStefano Zampini switch (ct) { 2116*a5801f52SStefano Zampini case DM_POLYTOPE_SEGMENT: 2117*a5801f52SStefano Zampini *onew = tquad_seg_o[(po+2)*4+o+2]; 2118*a5801f52SStefano Zampini *rnew = r; 2119*a5801f52SStefano Zampini break; 2120*a5801f52SStefano Zampini case DM_POLYTOPE_SEG_PRISM_TENSOR: 2121*a5801f52SStefano Zampini *onew = tquad_tquad_o[(po+2)*4+o+2]; 2122*a5801f52SStefano Zampini *rnew = r; 2123*a5801f52SStefano Zampini break; 2124*a5801f52SStefano Zampini default: break; 2125*a5801f52SStefano Zampini } 2126*a5801f52SStefano Zampini break; 2127*a5801f52SStefano Zampini default: 2128*a5801f52SStefano Zampini ierr = DMPlexCellRefinerMapSubcells_None(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 2129*a5801f52SStefano Zampini } 2130*a5801f52SStefano Zampini PetscFunctionReturn(0); 2131*a5801f52SStefano Zampini } 2132*a5801f52SStefano Zampini 2133*a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapCoordinates_BL(DMPlexCellRefiner cr, DMPolytopeType pct, DMPolytopeType ct, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[]) 2134*a5801f52SStefano Zampini { 2135*a5801f52SStefano Zampini PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data; 2136*a5801f52SStefano Zampini PetscInt d; 2137*a5801f52SStefano Zampini PetscErrorCode ierr; 2138*a5801f52SStefano Zampini 2139*a5801f52SStefano Zampini PetscFunctionBeginHot; 2140*a5801f52SStefano Zampini switch (pct) { 2141*a5801f52SStefano Zampini case DM_POLYTOPE_POINT_PRISM_TENSOR: 2142*a5801f52SStefano Zampini if (ct != DM_POLYTOPE_POINT) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for refined point type %s",DMPolytopeTypes[ct]); 2143*a5801f52SStefano Zampini if (Nv != 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for parent vertices %D",Nv); 2144*a5801f52SStefano 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); 2145*a5801f52SStefano Zampini for (d = 0; d < dE; d++) out[d] = in[d] + crbl->h[r] * (in[d + dE] - in[d]); 2146*a5801f52SStefano Zampini break; 2147*a5801f52SStefano Zampini default: 2148*a5801f52SStefano Zampini ierr = DMPlexCellRefinerMapCoordinates_Barycenter(cr,pct,ct,r,Nv,dE,in,out);CHKERRQ(ierr); 2149cf4091a3SMatthew G. Knepley } 2150cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 2151cf4091a3SMatthew G. Knepley } 2152cf4091a3SMatthew G. Knepley 2153412e9a14SMatthew G. Knepley static PetscErrorCode CellRefinerCreateOffset_Internal(DMPlexCellRefiner cr, PetscInt ctOrder[], PetscInt ctStart[], PetscInt **offset) 2154412e9a14SMatthew G. Knepley { 2155412e9a14SMatthew G. Knepley PetscInt c, cN, *off; 215675d3a19aSMatthew G. Knepley PetscErrorCode ierr; 215775d3a19aSMatthew G. Knepley 215875d3a19aSMatthew G. Knepley PetscFunctionBegin; 2159412e9a14SMatthew G. Knepley ierr = PetscCalloc1(DM_NUM_POLYTOPES*DM_NUM_POLYTOPES, &off);CHKERRQ(ierr); 2160412e9a14SMatthew G. Knepley for (c = DM_POLYTOPE_POINT; c < DM_NUM_POLYTOPES; ++c) { 2161412e9a14SMatthew G. Knepley const DMPolytopeType ct = (DMPolytopeType) c; 2162412e9a14SMatthew G. Knepley for (cN = DM_POLYTOPE_POINT; cN < DM_NUM_POLYTOPES; ++cN) { 2163412e9a14SMatthew G. Knepley const DMPolytopeType ctNew = (DMPolytopeType) cN; 2164412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2165412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 2166412e9a14SMatthew G. Knepley PetscInt Nct, n, i; 2167412e9a14SMatthew G. Knepley 2168412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ct) < 0 || DMPolytopeTypeGetDim(ctNew) < 0) {off[ct*DM_NUM_POLYTOPES+ctNew] = -1; break;} 2169412e9a14SMatthew G. Knepley off[ct*DM_NUM_POLYTOPES+ctNew] = 0; 2170412e9a14SMatthew G. Knepley for (i = DM_POLYTOPE_POINT; i < DM_NUM_POLYTOPES; ++i) { 2171412e9a14SMatthew G. Knepley const DMPolytopeType ict = (DMPolytopeType) ctOrder[i]; 2172412e9a14SMatthew G. Knepley const DMPolytopeType ictn = (DMPolytopeType) ctOrder[i+1]; 2173412e9a14SMatthew G. Knepley 2174412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ict, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 2175412e9a14SMatthew G. Knepley if (ict == ct) { 2176412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) break; 2177412e9a14SMatthew G. Knepley if (n == Nct) off[ct*DM_NUM_POLYTOPES+ctNew] = -1; 2178412e9a14SMatthew G. Knepley break; 2179412e9a14SMatthew G. Knepley } 2180412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) off[ct*DM_NUM_POLYTOPES+ctNew] += (ctStart[ictn]-ctStart[ict]) * rsize[n]; 2181412e9a14SMatthew G. Knepley } 2182412e9a14SMatthew G. Knepley } 2183412e9a14SMatthew G. Knepley } 2184412e9a14SMatthew G. Knepley *offset = off; 2185412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2186412e9a14SMatthew G. Knepley } 2187412e9a14SMatthew G. Knepley 2188412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetStarts(DMPlexCellRefiner cr, const PetscInt ctStart[], const PetscInt ctStartNew[]) 2189412e9a14SMatthew G. Knepley { 2190412e9a14SMatthew G. Knepley const PetscInt ctSize = DM_NUM_POLYTOPES+1; 2191412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2192412e9a14SMatthew G. Knepley 2193412e9a14SMatthew G. Knepley PetscFunctionBegin; 2194412e9a14SMatthew G. Knepley if (cr->setupcalled) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_ARG_WRONGSTATE, "Must call this function before DMPlexCellRefinerSetUp()"); 2195412e9a14SMatthew G. Knepley ierr = PetscCalloc2(ctSize, &cr->ctStart, ctSize, &cr->ctStartNew);CHKERRQ(ierr); 2196412e9a14SMatthew G. Knepley ierr = PetscArraycpy(cr->ctStart, ctStart, ctSize);CHKERRQ(ierr); 2197412e9a14SMatthew G. Knepley ierr = PetscArraycpy(cr->ctStartNew, ctStartNew, ctSize);CHKERRQ(ierr); 2198412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2199412e9a14SMatthew G. Knepley } 2200412e9a14SMatthew G. Knepley 2201412e9a14SMatthew G. Knepley /* Construct cell type order since we must loop over cell types in depth order */ 2202412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCreateCellTypeOrder_Internal(DMPolytopeType ctCell, PetscInt *ctOrder[], PetscInt *ctOrderInv[]) 2203412e9a14SMatthew G. Knepley { 2204412e9a14SMatthew G. Knepley PetscInt *ctO, *ctOInv; 2205412e9a14SMatthew G. Knepley PetscInt c, d, off = 0; 2206412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2207412e9a14SMatthew G. Knepley 2208412e9a14SMatthew G. Knepley PetscFunctionBegin; 2209412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctO, DM_NUM_POLYTOPES+1, &ctOInv);CHKERRQ(ierr); 2210412e9a14SMatthew G. Knepley for (d = 3; d >= DMPolytopeTypeGetDim(ctCell); --d) { 2211412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 2212412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue; 2213412e9a14SMatthew G. Knepley ctO[off++] = c; 2214412e9a14SMatthew G. Knepley } 2215412e9a14SMatthew G. Knepley } 2216412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ctCell) != 0) { 2217412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 2218412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != 0) continue; 2219412e9a14SMatthew G. Knepley ctO[off++] = c; 2220412e9a14SMatthew G. Knepley } 2221412e9a14SMatthew G. Knepley } 2222412e9a14SMatthew G. Knepley for (d = DMPolytopeTypeGetDim(ctCell)-1; d > 0; --d) { 2223412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 2224412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue; 2225412e9a14SMatthew G. Knepley ctO[off++] = c; 2226412e9a14SMatthew G. Knepley } 2227412e9a14SMatthew G. Knepley } 2228412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 2229412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) >= 0) continue; 2230412e9a14SMatthew G. Knepley ctO[off++] = c; 2231412e9a14SMatthew G. Knepley } 2232412e9a14SMatthew G. Knepley if (off != DM_NUM_POLYTOPES+1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid offset %D for cell type order", off); 2233412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 2234412e9a14SMatthew G. Knepley ctOInv[ctO[c]] = c; 2235412e9a14SMatthew G. Knepley } 2236412e9a14SMatthew G. Knepley *ctOrder = ctO; 2237412e9a14SMatthew G. Knepley *ctOrderInv = ctOInv; 2238412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2239412e9a14SMatthew G. Knepley } 2240412e9a14SMatthew G. Knepley 2241412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerSetUp(DMPlexCellRefiner cr) 2242412e9a14SMatthew G. Knepley { 2243412e9a14SMatthew G. Knepley DM dm = cr->dm; 2244412e9a14SMatthew G. Knepley DMPolytopeType ctCell; 2245412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p, c; 2246412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2247412e9a14SMatthew G. Knepley 2248412e9a14SMatthew G. Knepley PetscFunctionBegin; 2249412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 2250412e9a14SMatthew G. Knepley if (cr->setupcalled) PetscFunctionReturn(0); 2251*a5801f52SStefano Zampini if (cr->ops->setup) { 2252*a5801f52SStefano Zampini ierr = (*cr->ops->setup)(cr);CHKERRQ(ierr); 2253*a5801f52SStefano Zampini } 2254412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2255*a5801f52SStefano Zampini if (pEnd > pStart) { 2256*a5801f52SStefano Zampini ierr = DMPlexGetCellType(dm, 0, &ctCell);CHKERRQ(ierr); 2257*a5801f52SStefano Zampini } else { 2258412e9a14SMatthew G. Knepley PetscInt dim; 2259a57030b0SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 2260412e9a14SMatthew G. Knepley switch (dim) { 2261412e9a14SMatthew G. Knepley case 0: ctCell = DM_POLYTOPE_POINT;break; 2262412e9a14SMatthew G. Knepley case 1: ctCell = DM_POLYTOPE_SEGMENT;break; 2263412e9a14SMatthew G. Knepley case 2: ctCell = DM_POLYTOPE_TRIANGLE;break; 2264412e9a14SMatthew G. Knepley case 3: ctCell = DM_POLYTOPE_TETRAHEDRON;break; 2265*a5801f52SStefano Zampini default: ctCell = DM_POLYTOPE_UNKNOWN; 2266412e9a14SMatthew G. Knepley } 2267412e9a14SMatthew G. Knepley } 2268412e9a14SMatthew G. Knepley ierr = DMPlexCreateCellTypeOrder_Internal(ctCell, &cr->ctOrder, &cr->ctOrderInv);CHKERRQ(ierr); 2269412e9a14SMatthew G. Knepley /* Construct sizes and offsets for each cell type */ 2270412e9a14SMatthew G. Knepley if (!cr->ctStart) { 2271412e9a14SMatthew G. Knepley PetscInt *ctS, *ctSN, *ctC, *ctCN; 2272412e9a14SMatthew G. Knepley 2273412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctS, DM_NUM_POLYTOPES+1, &ctSN);CHKERRQ(ierr); 2274412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctC, DM_NUM_POLYTOPES+1, &ctCN);CHKERRQ(ierr); 2275412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2276412e9a14SMatthew G. Knepley DMPolytopeType ct; 2277412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2278412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 2279412e9a14SMatthew G. Knepley PetscInt Nct, n; 2280412e9a14SMatthew G. Knepley 2281412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2282412e9a14SMatthew G. Knepley if ((PetscInt) ct < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No cell type for point %D", p); 2283412e9a14SMatthew G. Knepley ++ctC[ct]; 2284412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 2285412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) ctCN[rct[n]] += rsize[n]; 2286412e9a14SMatthew G. Knepley } 2287412e9a14SMatthew G. Knepley for (c = 0; c < DM_NUM_POLYTOPES; ++c) { 2288412e9a14SMatthew G. Knepley const PetscInt ct = cr->ctOrder[c]; 2289412e9a14SMatthew G. Knepley const PetscInt ctn = cr->ctOrder[c+1]; 2290412e9a14SMatthew G. Knepley 2291412e9a14SMatthew G. Knepley ctS[ctn] = ctS[ct] + ctC[ct]; 2292412e9a14SMatthew G. Knepley ctSN[ctn] = ctSN[ct] + ctCN[ct]; 2293412e9a14SMatthew G. Knepley } 2294412e9a14SMatthew G. Knepley ierr = PetscFree2(ctC, ctCN);CHKERRQ(ierr); 2295412e9a14SMatthew G. Knepley cr->ctStart = ctS; 2296412e9a14SMatthew G. Knepley cr->ctStartNew = ctSN; 2297412e9a14SMatthew G. Knepley } 2298412e9a14SMatthew G. Knepley ierr = CellRefinerCreateOffset_Internal(cr, cr->ctOrder, cr->ctStart, &cr->offset);CHKERRQ(ierr); 2299412e9a14SMatthew G. Knepley cr->setupcalled = PETSC_TRUE; 2300412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2301412e9a14SMatthew G. Knepley } 2302412e9a14SMatthew G. Knepley 2303412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView_Ascii(DMPlexCellRefiner cr, PetscViewer v) 2304412e9a14SMatthew G. Knepley { 2305412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2306412e9a14SMatthew G. Knepley 2307412e9a14SMatthew G. Knepley PetscFunctionBegin; 2308412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(v, "Cell Refiner: %s\n", DMPlexCellRefinerTypes[cr->type]);CHKERRQ(ierr); 2309412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2310412e9a14SMatthew G. Knepley } 2311412e9a14SMatthew G. Knepley 2312412e9a14SMatthew G. Knepley /* 2313412e9a14SMatthew G. Knepley DMPlexCellRefinerView - Views a DMPlexCellRefiner object 2314412e9a14SMatthew G. Knepley 2315412e9a14SMatthew G. Knepley Collective on cr 2316412e9a14SMatthew G. Knepley 2317412e9a14SMatthew G. Knepley Input Parameters: 2318412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 2319412e9a14SMatthew G. Knepley - viewer - The PetscViewer object 2320412e9a14SMatthew G. Knepley 2321412e9a14SMatthew G. Knepley Level: beginner 2322412e9a14SMatthew G. Knepley 2323412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerCreate() 2324412e9a14SMatthew G. Knepley */ 2325412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView(DMPlexCellRefiner cr, PetscViewer viewer) 2326412e9a14SMatthew G. Knepley { 2327412e9a14SMatthew G. Knepley PetscBool iascii; 2328412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2329412e9a14SMatthew G. Knepley 2330412e9a14SMatthew G. Knepley PetscFunctionBegin; 2331412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 2332412e9a14SMatthew G. Knepley if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2333412e9a14SMatthew G. Knepley if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) cr), &viewer);CHKERRQ(ierr);} 2334412e9a14SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 2335412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2336412e9a14SMatthew G. Knepley if (iascii) {ierr = DMPlexCellRefinerView_Ascii(cr, viewer);CHKERRQ(ierr);} 2337412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2338412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2339412e9a14SMatthew G. Knepley } 2340412e9a14SMatthew G. Knepley 2341412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerDestroy(DMPlexCellRefiner *cr) 2342412e9a14SMatthew G. Knepley { 2343412e9a14SMatthew G. Knepley PetscInt c; 2344412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2345412e9a14SMatthew G. Knepley 2346412e9a14SMatthew G. Knepley PetscFunctionBegin; 2347412e9a14SMatthew G. Knepley if (!*cr) PetscFunctionReturn(0); 2348412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(*cr, DM_CLASSID, 1); 2349*a5801f52SStefano Zampini if ((*cr)->ops->destroy) { 2350*a5801f52SStefano Zampini ierr = ((*cr)->ops->destroy)(*cr);CHKERRQ(ierr); 2351*a5801f52SStefano Zampini } 2352412e9a14SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) (*cr)->dm);CHKERRQ(ierr); 2353412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->ctOrder, (*cr)->ctOrderInv);CHKERRQ(ierr); 2354412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->ctStart, (*cr)->ctStartNew);CHKERRQ(ierr); 2355412e9a14SMatthew G. Knepley ierr = PetscFree((*cr)->offset);CHKERRQ(ierr); 2356412e9a14SMatthew G. Knepley for (c = 0; c < DM_NUM_POLYTOPES; ++c) { 2357412e9a14SMatthew G. Knepley ierr = PetscFEDestroy(&(*cr)->coordFE[c]);CHKERRQ(ierr); 2358412e9a14SMatthew G. Knepley ierr = PetscFEGeomDestroy(&(*cr)->refGeom[c]);CHKERRQ(ierr); 2359412e9a14SMatthew G. Knepley } 2360412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->coordFE, (*cr)->refGeom);CHKERRQ(ierr); 2361412e9a14SMatthew G. Knepley ierr = PetscHeaderDestroy(cr);CHKERRQ(ierr); 2362412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2363412e9a14SMatthew G. Knepley } 2364412e9a14SMatthew G. Knepley 2365412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerCreate(DM dm, DMPlexCellRefiner *cr) 2366412e9a14SMatthew G. Knepley { 2367412e9a14SMatthew G. Knepley DMPlexCellRefiner tmp; 2368412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2369412e9a14SMatthew G. Knepley 2370412e9a14SMatthew G. Knepley PetscFunctionBegin; 2371412e9a14SMatthew G. Knepley PetscValidPointer(cr, 2); 2372412e9a14SMatthew G. Knepley *cr = NULL; 2373412e9a14SMatthew G. Knepley ierr = PetscHeaderCreate(tmp, DM_CLASSID, "DMPlexCellRefiner", "Cell Refiner", "DMPlexCellRefiner", PETSC_COMM_SELF, DMPlexCellRefinerDestroy, DMPlexCellRefinerView);CHKERRQ(ierr); 2374412e9a14SMatthew G. Knepley tmp->setupcalled = PETSC_FALSE; 2375412e9a14SMatthew G. Knepley 2376412e9a14SMatthew G. Knepley tmp->dm = dm; 2377412e9a14SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); 2378412e9a14SMatthew G. Knepley ierr = DMPlexGetCellRefinerType(dm, &tmp->type);CHKERRQ(ierr); 2379412e9a14SMatthew G. Knepley switch (tmp->type) { 238096ca5757SLisandro Dalcin case DM_REFINER_REGULAR: 2381412e9a14SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_Regular; 2382412e9a14SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_Regular; 2383412e9a14SMatthew G. Knepley tmp->ops->getcellvertices = DMPlexCellRefinerGetCellVertices_Regular; 2384412e9a14SMatthew G. Knepley tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_Regular; 2385*a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 2386412e9a14SMatthew G. Knepley tmp->ops->getaffinetransforms = DMPlexCellRefinerGetAffineTransforms_Regular; 2387412e9a14SMatthew G. Knepley tmp->ops->getaffinefacetransforms = DMPlexCellRefinerGetAffineFaceTransforms_Regular; 2388412e9a14SMatthew G. Knepley break; 238996ca5757SLisandro Dalcin case DM_REFINER_TO_BOX: 239096ca5757SLisandro Dalcin tmp->ops->refine = DMPlexCellRefinerRefine_ToBox; 239196ca5757SLisandro Dalcin tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToBox; 239296ca5757SLisandro Dalcin tmp->ops->getcellvertices = DMPlexCellRefinerGetCellVertices_ToBox; 239396ca5757SLisandro Dalcin tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_ToBox; 2394*a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 2395412e9a14SMatthew G. Knepley break; 239696ca5757SLisandro Dalcin case DM_REFINER_TO_SIMPLEX: 2397412e9a14SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_ToSimplex; 2398412e9a14SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToSimplex; 2399*a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 2400412e9a14SMatthew G. Knepley break; 2401cf4091a3SMatthew G. Knepley case DM_REFINER_ALFELD2D: 2402cf4091a3SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_Alfeld2D; 2403cf4091a3SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_None; 2404*a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 2405cf4091a3SMatthew G. Knepley break; 2406cf4091a3SMatthew G. Knepley case DM_REFINER_ALFELD3D: 2407cf4091a3SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_Alfeld3D; 2408cf4091a3SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_None; 2409*a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 2410cf4091a3SMatthew G. Knepley break; 2411*a5801f52SStefano Zampini case DM_REFINER_BOUNDARYLAYER: 2412*a5801f52SStefano Zampini tmp->ops->setup = DMPlexCellRefinerSetUp_BL; 2413*a5801f52SStefano Zampini tmp->ops->destroy = DMPlexCellRefinerDestroy_BL; 2414cf4091a3SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_BL; 2415cf4091a3SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_BL; 2416*a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_BL; 2417cf4091a3SMatthew G. Knepley break; 2418412e9a14SMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Invalid cell refiner type %s", DMPlexCellRefinerTypes[tmp->type]); 2419412e9a14SMatthew G. Knepley } 2420412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES, &tmp->coordFE, DM_NUM_POLYTOPES, &tmp->refGeom);CHKERRQ(ierr); 2421412e9a14SMatthew G. Knepley *cr = tmp; 2422412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2423412e9a14SMatthew G. Knepley } 2424412e9a14SMatthew G. Knepley 2425412e9a14SMatthew G. Knepley /*@ 2426412e9a14SMatthew G. Knepley DMPlexCellRefinerGetAffineTransforms - Gets the affine map from the reference cell to each subcell 2427412e9a14SMatthew G. Knepley 2428412e9a14SMatthew G. Knepley Input Parameters: 2429412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 2430412e9a14SMatthew G. Knepley - ct - The cell type 2431412e9a14SMatthew G. Knepley 2432412e9a14SMatthew G. Knepley Output Parameters: 2433412e9a14SMatthew G. Knepley + Nc - The number of subcells produced from this cell type 2434412e9a14SMatthew G. Knepley . v0 - The translation of the first vertex for each subcell 2435412e9a14SMatthew G. Knepley . J - The Jacobian for each subcell (map from reference cell to subcell) 2436412e9a14SMatthew G. Knepley - invJ - The inverse Jacobian for each subcell 2437412e9a14SMatthew G. Knepley 2438412e9a14SMatthew G. Knepley Level: developer 2439412e9a14SMatthew G. Knepley 2440412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineFaceTransforms(), Create() 2441412e9a14SMatthew G. Knepley @*/ 2442412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[]) 2443412e9a14SMatthew G. Knepley { 2444412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2445412e9a14SMatthew G. Knepley 2446412e9a14SMatthew G. Knepley PetscFunctionBegin; 2447412e9a14SMatthew G. Knepley if (!cr->ops->getaffinetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine transforms from this refiner"); 2448412e9a14SMatthew G. Knepley ierr = (*cr->ops->getaffinetransforms)(cr, ct, Nc, v0, J, invJ);CHKERRQ(ierr); 2449412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2450412e9a14SMatthew G. Knepley } 2451412e9a14SMatthew G. Knepley 2452412e9a14SMatthew G. Knepley /*@ 2453412e9a14SMatthew G. Knepley DMPlexCellRefinerGetAffineFaceTransforms - Gets the affine map from the reference face cell to each face in the given cell 2454412e9a14SMatthew G. Knepley 2455412e9a14SMatthew G. Knepley Input Parameters: 2456412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 2457412e9a14SMatthew G. Knepley - ct - The cell type 2458412e9a14SMatthew G. Knepley 2459412e9a14SMatthew G. Knepley Output Parameters: 2460412e9a14SMatthew G. Knepley + Nf - The number of faces for this cell type 2461412e9a14SMatthew G. Knepley . v0 - The translation of the first vertex for each face 2462412e9a14SMatthew G. Knepley . J - The Jacobian for each face (map from original cell to subcell) 2463412e9a14SMatthew G. Knepley . invJ - The inverse Jacobian for each face 2464412e9a14SMatthew G. Knepley - detJ - The determinant of the Jacobian for each face 2465412e9a14SMatthew G. Knepley 2466412e9a14SMatthew G. Knepley Note: The Jacobian and inverse Jacboian will be rectangular, and the inverse is really a generalized inverse. 2467412e9a14SMatthew G. Knepley 2468412e9a14SMatthew G. Knepley Level: developer 2469412e9a14SMatthew G. Knepley 2470412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineTransforms(), Create() 2471412e9a14SMatthew G. Knepley @*/ 2472412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[]) 2473412e9a14SMatthew G. Knepley { 2474412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2475412e9a14SMatthew G. Knepley 2476412e9a14SMatthew G. Knepley PetscFunctionBegin; 2477412e9a14SMatthew G. Knepley if (!cr->ops->getaffinefacetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine face transforms from this refiner"); 2478412e9a14SMatthew G. Knepley ierr = (*cr->ops->getaffinefacetransforms)(cr, ct, Nf, v0, J, invJ, detJ);CHKERRQ(ierr); 2479412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2480412e9a14SMatthew G. Knepley } 2481412e9a14SMatthew G. Knepley 2482412e9a14SMatthew G. Knepley /* Numbering regularly refined meshes 2483412e9a14SMatthew G. Knepley 2484412e9a14SMatthew G. Knepley We want the numbering of the new mesh to respect the same depth stratification as the old mesh. We first compute 2485412e9a14SMatthew G. Knepley the number of new points at each depth. This means that offsets for each depth can be computed, making no assumptions 2486412e9a14SMatthew G. Knepley about the order of different cell types. 2487412e9a14SMatthew G. Knepley 2488412e9a14SMatthew G. Knepley However, when we want to order different depth strata, it will be very useful to make assumptions about contiguous 2489412e9a14SMatthew G. Knepley numbering of different cell types, especially if we want to compute new numberings without communication. Therefore, we 2490412e9a14SMatthew G. Knepley will require that cells are numbering contiguously for each cell type, and that those blocks come in the same order as 2491412e9a14SMatthew G. Knepley the cell type enumeration within a given depth stratum. 2492412e9a14SMatthew G. Knepley 2493412e9a14SMatthew 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 2494412e9a14SMatthew G. Knepley start at the new depth offset, run through all prior cell types incrementing by the total addition from that type, then 2495412e9a14SMatthew G. Knepley offset by the old cell type number and replica number for the insertion. 2496412e9a14SMatthew G. Knepley */ 2497412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetNewPoint(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType ctNew, PetscInt p, PetscInt r, PetscInt *pNew) 2498412e9a14SMatthew G. Knepley { 2499412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2500412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 2501412e9a14SMatthew G. Knepley PetscInt Nct, n; 2502412e9a14SMatthew G. Knepley PetscInt off = cr->offset[ct*DM_NUM_POLYTOPES+ctNew]; 2503412e9a14SMatthew G. Knepley PetscInt ctS = cr->ctStart[ct], ctE = cr->ctStart[cr->ctOrder[cr->ctOrderInv[ct]+1]]; 2504412e9a14SMatthew G. Knepley PetscInt ctSN = cr->ctStartNew[ctNew], ctEN = cr->ctStartNew[cr->ctOrder[cr->ctOrderInv[ctNew]+1]]; 2505412e9a14SMatthew G. Knepley PetscInt newp = ctSN; 2506412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2507412e9a14SMatthew G. Knepley 2508412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 2509412e9a14SMatthew 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); 2510412e9a14SMatthew G. Knepley if (off < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell type %s does not produce type %s", DMPolytopeTypes[ct], DMPolytopeTypes[ctNew]); 2511412e9a14SMatthew G. Knepley 2512412e9a14SMatthew G. Knepley newp += off; 2513412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 2514412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2515412e9a14SMatthew G. Knepley if (rct[n] == ctNew) { 2516412e9a14SMatthew G. Knepley if (rsize[n] && r >= rsize[n]) 2517412e9a14SMatthew 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]); 2518412e9a14SMatthew G. Knepley newp += (p - ctS) * rsize[n] + r; 2519412e9a14SMatthew G. Knepley break; 2520412e9a14SMatthew G. Knepley } 2521412e9a14SMatthew G. Knepley } 2522412e9a14SMatthew G. Knepley 2523412e9a14SMatthew 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); 2524412e9a14SMatthew G. Knepley *pNew = newp; 2525412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2526412e9a14SMatthew G. Knepley } 2527412e9a14SMatthew G. Knepley 2528412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetConeSizes(DMPlexCellRefiner cr, DM rdm) 2529412e9a14SMatthew G. Knepley { 2530412e9a14SMatthew G. Knepley DM dm = cr->dm; 2531412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p, pNew; 2532412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2533412e9a14SMatthew G. Knepley 2534412e9a14SMatthew G. Knepley PetscFunctionBegin; 2535412e9a14SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 2536412e9a14SMatthew G. Knepley ierr = DMCreateLabel(rdm, "celltype");CHKERRQ(ierr); 2537412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2538412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2539412e9a14SMatthew G. Knepley DMPolytopeType ct; 2540412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2541412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2542412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2543412e9a14SMatthew G. Knepley 2544412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2545412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2546412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2547412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2548412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 2549412e9a14SMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, pNew, DMPolytopeTypeGetConeSize(rct[n]));CHKERRQ(ierr); 2550412e9a14SMatthew G. Knepley ierr = DMPlexSetCellType(rdm, pNew, rct[n]);CHKERRQ(ierr); 2551412e9a14SMatthew G. Knepley } 2552412e9a14SMatthew G. Knepley } 2553412e9a14SMatthew G. Knepley } 2554412e9a14SMatthew G. Knepley { 2555412e9a14SMatthew G. Knepley DMLabel ctLabel; 2556412e9a14SMatthew G. Knepley DM_Plex *plex = (DM_Plex *) rdm->data; 2557412e9a14SMatthew G. Knepley 2558412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(rdm, &ctLabel);CHKERRQ(ierr); 2559412e9a14SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) ctLabel, &plex->celltypeState);CHKERRQ(ierr); 2560412e9a14SMatthew G. Knepley } 2561412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2562412e9a14SMatthew G. Knepley } 2563412e9a14SMatthew G. Knepley 2564412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCones(DMPlexCellRefiner cr, DM rdm) 2565412e9a14SMatthew G. Knepley { 2566412e9a14SMatthew G. Knepley DM dm = cr->dm; 2567412e9a14SMatthew G. Knepley DMPolytopeType ct; 2568412e9a14SMatthew G. Knepley PetscInt *coneNew, *orntNew; 2569412e9a14SMatthew G. Knepley PetscInt maxConeSize = 0, pStart, pEnd, p, pNew; 2570412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2571412e9a14SMatthew G. Knepley 2572412e9a14SMatthew G. Knepley PetscFunctionBegin; 2573412e9a14SMatthew G. Knepley for (p = 0; p < DM_NUM_POLYTOPES; ++p) maxConeSize = PetscMax(maxConeSize, DMPolytopeTypeGetConeSize((DMPolytopeType) p)); 2574412e9a14SMatthew G. Knepley ierr = PetscMalloc2(maxConeSize, &coneNew, maxConeSize, &orntNew);CHKERRQ(ierr); 2575412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2576412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2577412e9a14SMatthew G. Knepley const PetscInt *cone, *ornt; 2578412e9a14SMatthew G. Knepley PetscInt coff, ooff, c; 2579412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2580412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2581412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2582412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2583412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 2584412e9a14SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &ornt);CHKERRQ(ierr); 2585412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2586412e9a14SMatthew G. Knepley for (n = 0, coff = 0, ooff = 0; n < Nct; ++n) { 2587412e9a14SMatthew G. Knepley const DMPolytopeType ctNew = rct[n]; 2588412e9a14SMatthew G. Knepley const PetscInt csizeNew = DMPolytopeTypeGetConeSize(ctNew); 2589412e9a14SMatthew G. Knepley 2590412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2591412e9a14SMatthew G. Knepley /* pNew is a subcell produced by subdividing p */ 2592412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 2593412e9a14SMatthew G. Knepley for (c = 0; c < csizeNew; ++c) { 2594412e9a14SMatthew G. Knepley PetscInt ppp = -1; /* Parent Parent point: Parent of point pp */ 2595412e9a14SMatthew G. Knepley PetscInt pp = p; /* Parent point: Point in the original mesh producing new cone point */ 2596412e9a14SMatthew G. Knepley PetscInt po = 0; /* Orientation of parent point pp in parent parent point ppp */ 2597412e9a14SMatthew G. Knepley DMPolytopeType pct = ct; /* Parent type: Cell type for parent of new cone point */ 2598412e9a14SMatthew G. Knepley const PetscInt *pcone = cone; /* Parent cone: Cone of parent point pp */ 2599412e9a14SMatthew G. Knepley PetscInt pr = -1; /* Replica number of pp that produces new cone point */ 2600412e9a14SMatthew G. Knepley const DMPolytopeType ft = (DMPolytopeType) rcone[coff++]; /* Cell type for new cone point of pNew */ 2601412e9a14SMatthew G. Knepley const PetscInt fn = rcone[coff++]; /* Number of cones of p that need to be taken when producing new cone point */ 2602412e9a14SMatthew G. Knepley PetscInt fo = rornt[ooff++]; /* Orientation of new cone point in pNew */ 2603412e9a14SMatthew G. Knepley PetscInt lc; 2604412e9a14SMatthew G. Knepley 2605412e9a14SMatthew G. Knepley /* Get the type (pct) and point number (pp) of the parent point in the original mesh which produces this cone point */ 2606412e9a14SMatthew G. Knepley for (lc = 0; lc < fn; ++lc) { 2607412e9a14SMatthew G. Knepley const PetscInt *ppornt; 2608412e9a14SMatthew G. Knepley PetscInt pcp; 2609412e9a14SMatthew G. Knepley 2610412e9a14SMatthew G. Knepley ierr = DMPolytopeMapCell(pct, po, rcone[coff++], &pcp);CHKERRQ(ierr); 2611412e9a14SMatthew G. Knepley ppp = pp; 2612412e9a14SMatthew G. Knepley pp = pcone[pcp]; 2613412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, pp, &pct);CHKERRQ(ierr); 2614412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, pp, &pcone);CHKERRQ(ierr); 2615412e9a14SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, ppp, &ppornt);CHKERRQ(ierr); 2616cf4091a3SMatthew G. Knepley if (po < 0 && pct != DM_POLYTOPE_POINT) { 2617cf4091a3SMatthew G. Knepley const PetscInt pornt = ppornt[pcp]; 2618cf4091a3SMatthew G. Knepley const PetscInt pcsize = DMPolytopeTypeGetConeSize(pct); 2619cf4091a3SMatthew G. Knepley const PetscInt pcstart = pornt < 0 ? -(pornt+1) : pornt; 2620cf4091a3SMatthew G. Knepley const PetscInt rcstart = (pcstart+pcsize-1)%pcsize; 2621cf4091a3SMatthew G. Knepley po = pornt < 0 ? -(rcstart+1) : rcstart; 2622cf4091a3SMatthew G. Knepley } else { 2623412e9a14SMatthew G. Knepley po = ppornt[pcp]; 2624412e9a14SMatthew G. Knepley } 2625cf4091a3SMatthew G. Knepley } 2626412e9a14SMatthew G. Knepley pr = rcone[coff++]; 2627412e9a14SMatthew G. Knepley /* Orientation po of pp maps (pr, fo) -> (pr', fo') */ 2628412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapSubcells(cr, pct, po, ft, pr, fo, &pr, &fo);CHKERRQ(ierr); 2629412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, pct, ft, pp, pr, &coneNew[c]);CHKERRQ(ierr); 2630412e9a14SMatthew G. Knepley orntNew[c] = fo; 2631412e9a14SMatthew G. Knepley } 2632412e9a14SMatthew G. Knepley ierr = DMPlexSetCone(rdm, pNew, coneNew);CHKERRQ(ierr); 2633412e9a14SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, pNew, orntNew);CHKERRQ(ierr); 2634412e9a14SMatthew G. Knepley } 2635412e9a14SMatthew G. Knepley } 2636412e9a14SMatthew G. Knepley } 2637412e9a14SMatthew G. Knepley ierr = PetscFree2(coneNew, orntNew);CHKERRQ(ierr); 2638412e9a14SMatthew G. Knepley ierr = DMPlexSymmetrize(rdm);CHKERRQ(ierr); 2639412e9a14SMatthew G. Knepley ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 2640412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2641412e9a14SMatthew G. Knepley } 2642412e9a14SMatthew G. Knepley 2643412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCoordinateFE(DMPlexCellRefiner cr, DMPolytopeType ct, PetscFE *fe) 2644412e9a14SMatthew G. Knepley { 2645412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2646412e9a14SMatthew G. Knepley 2647412e9a14SMatthew G. Knepley PetscFunctionBegin; 2648412e9a14SMatthew G. Knepley if (!cr->coordFE[ct]) { 2649412e9a14SMatthew G. Knepley PetscInt dim, cdim; 2650412e9a14SMatthew G. Knepley PetscBool isSimplex; 2651412e9a14SMatthew G. Knepley 2652412e9a14SMatthew G. Knepley switch (ct) { 2653412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: dim = 1; isSimplex = PETSC_TRUE; break; 2654412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: dim = 2; isSimplex = PETSC_TRUE; break; 2655412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: dim = 2; isSimplex = PETSC_FALSE; break; 2656412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: dim = 3; isSimplex = PETSC_TRUE; break; 2657412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: dim = 3; isSimplex = PETSC_FALSE; break; 2658412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No coordinate FE for cell type %s", DMPolytopeTypes[ct]); 2659412e9a14SMatthew G. Knepley } 2660412e9a14SMatthew G. Knepley ierr = DMGetCoordinateDim(cr->dm, &cdim);CHKERRQ(ierr); 2661412e9a14SMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, cdim, isSimplex, 1, PETSC_DETERMINE, &cr->coordFE[ct]);CHKERRQ(ierr); 2662412e9a14SMatthew G. Knepley { 2663412e9a14SMatthew G. Knepley PetscDualSpace dsp; 2664412e9a14SMatthew G. Knepley PetscQuadrature quad; 2665412e9a14SMatthew G. Knepley DM K; 2666412e9a14SMatthew G. Knepley PetscFEGeom *cg; 2667412e9a14SMatthew G. Knepley PetscReal *Xq, *xq, *wq; 2668412e9a14SMatthew G. Knepley PetscInt Nq, q; 2669412e9a14SMatthew G. Knepley 2670412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCellVertices(cr, ct, &Nq, &Xq);CHKERRQ(ierr); 2671412e9a14SMatthew G. Knepley ierr = PetscMalloc1(Nq*cdim, &xq);CHKERRQ(ierr); 2672412e9a14SMatthew G. Knepley for (q = 0; q < Nq*cdim; ++q) xq[q] = Xq[q]; 2673412e9a14SMatthew G. Knepley ierr = PetscMalloc1(Nq, &wq);CHKERRQ(ierr); 2674412e9a14SMatthew G. Knepley for (q = 0; q < Nq; ++q) wq[q] = 1.0; 2675412e9a14SMatthew G. Knepley ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &quad);CHKERRQ(ierr); 2676412e9a14SMatthew G. Knepley ierr = PetscQuadratureSetData(quad, dim, 1, Nq, xq, wq);CHKERRQ(ierr); 2677412e9a14SMatthew G. Knepley ierr = PetscFESetQuadrature(cr->coordFE[ct], quad);CHKERRQ(ierr); 2678412e9a14SMatthew G. Knepley 2679412e9a14SMatthew G. Knepley ierr = PetscFEGetDualSpace(cr->coordFE[ct], &dsp);CHKERRQ(ierr); 2680412e9a14SMatthew G. Knepley ierr = PetscDualSpaceGetDM(dsp, &K);CHKERRQ(ierr); 2681412e9a14SMatthew G. Knepley ierr = PetscFEGeomCreate(quad, 1, cdim, PETSC_FALSE, &cr->refGeom[ct]);CHKERRQ(ierr); 2682412e9a14SMatthew G. Knepley cg = cr->refGeom[ct]; 2683412e9a14SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(K, 0, NULL, cg->v, cg->J, cg->invJ, cg->detJ);CHKERRQ(ierr); 2684412e9a14SMatthew G. Knepley ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr); 2685412e9a14SMatthew G. Knepley } 2686412e9a14SMatthew G. Knepley } 2687412e9a14SMatthew G. Knepley *fe = cr->coordFE[ct]; 2688412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2689412e9a14SMatthew G. Knepley } 2690412e9a14SMatthew G. Knepley 2691412e9a14SMatthew G. Knepley /* 2692412e9a14SMatthew G. Knepley DMPlexCellRefinerMapLocalizedCoordinates - Given a cell of type ct with localized coordinates x, we generate localized coordinates xr for subcell r of type rct. 2693412e9a14SMatthew G. Knepley 2694412e9a14SMatthew G. Knepley Not collective 2695412e9a14SMatthew G. Knepley 2696412e9a14SMatthew G. Knepley Input Parameters: 2697412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner 2698412e9a14SMatthew G. Knepley . ct - The type of the parent cell 2699412e9a14SMatthew G. Knepley . rct - The type of the produced cell 2700412e9a14SMatthew G. Knepley . r - The index of the produced cell 2701412e9a14SMatthew G. Knepley - x - The localized coordinates for the parent cell 2702412e9a14SMatthew G. Knepley 2703412e9a14SMatthew G. Knepley Output Parameter: 2704412e9a14SMatthew G. Knepley . xr - The localized coordinates for the produced cell 2705412e9a14SMatthew G. Knepley 2706412e9a14SMatthew G. Knepley Level: developer 2707412e9a14SMatthew G. Knepley 2708412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerSetCoordinates() 2709412e9a14SMatthew G. Knepley */ 2710412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapLocalizedCoordinates(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, const PetscScalar x[], PetscScalar xr[]) 2711412e9a14SMatthew G. Knepley { 2712412e9a14SMatthew G. Knepley PetscFE fe = NULL; 2713412e9a14SMatthew G. Knepley PetscInt cdim, Nv, v, *subcellV; 2714412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2715412e9a14SMatthew G. Knepley 2716412e9a14SMatthew G. Knepley PetscFunctionBegin; 2717412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCoordinateFE(cr, ct, &fe);CHKERRQ(ierr); 2718412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetSubcellVertices(cr, ct, rct, r, &Nv, &subcellV);CHKERRQ(ierr); 2719412e9a14SMatthew G. Knepley ierr = PetscFEGetNumComponents(fe, &cdim);CHKERRQ(ierr); 2720412e9a14SMatthew G. Knepley for (v = 0; v < Nv; ++v) { 2721412e9a14SMatthew G. Knepley ierr = PetscFEInterpolate_Static(fe, x, cr->refGeom[ct], subcellV[v], &xr[v*cdim]);CHKERRQ(ierr); 2722412e9a14SMatthew G. Knepley } 2723412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2724412e9a14SMatthew G. Knepley } 2725412e9a14SMatthew G. Knepley 2726412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCoordinates(DMPlexCellRefiner cr, DM rdm) 2727412e9a14SMatthew G. Knepley { 2728412e9a14SMatthew G. Knepley DM dm = cr->dm, cdm; 2729412e9a14SMatthew G. Knepley PetscSection coordSection, coordSectionNew; 2730412e9a14SMatthew G. Knepley Vec coordsLocal, coordsLocalNew; 2731412e9a14SMatthew G. Knepley const PetscScalar *coords; 2732412e9a14SMatthew G. Knepley PetscScalar *coordsNew; 2733412e9a14SMatthew G. Knepley const DMBoundaryType *bd; 2734412e9a14SMatthew G. Knepley const PetscReal *maxCell, *L; 2735412e9a14SMatthew G. Knepley PetscBool isperiodic, localizeVertices = PETSC_FALSE, localizeCells = PETSC_FALSE; 2736412e9a14SMatthew G. Knepley PetscInt dE, d, cStart, cEnd, c, vStartNew, vEndNew, v, pStart, pEnd, p, ocStart, ocEnd; 2737412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2738412e9a14SMatthew G. Knepley 2739412e9a14SMatthew G. Knepley PetscFunctionBegin; 2740412e9a14SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 274190b157c4SStefano Zampini ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 274290b157c4SStefano Zampini /* Determine if we need to localize coordinates when generating them */ 2743b9ccc978SStefano Zampini if (isperiodic) { 2744412e9a14SMatthew G. Knepley localizeVertices = PETSC_TRUE; 2745412e9a14SMatthew G. Knepley if (!maxCell) { 2746412e9a14SMatthew G. Knepley PetscBool localized; 2747412e9a14SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 2748412e9a14SMatthew G. Knepley if (!localized) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Cannot refine a periodic mesh if coordinates have not been localized"); 2749412e9a14SMatthew G. Knepley localizeCells = PETSC_TRUE; 2750b9ccc978SStefano Zampini } 2751b9ccc978SStefano Zampini } 2752b9ccc978SStefano Zampini 2753b9ccc978SStefano Zampini ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 2754412e9a14SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &dE);CHKERRQ(ierr); 2755412e9a14SMatthew G. Knepley if (maxCell) { 2756412e9a14SMatthew G. Knepley PetscReal maxCellNew[3]; 2757412e9a14SMatthew G. Knepley 2758412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) maxCellNew[d] = maxCell[d]/2.0; 2759412e9a14SMatthew G. Knepley ierr = DMSetPeriodicity(rdm, isperiodic, maxCellNew, L, bd);CHKERRQ(ierr); 2760412e9a14SMatthew G. Knepley } else { 2761412e9a14SMatthew G. Knepley ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 2762412e9a14SMatthew G. Knepley } 2763b9ccc978SStefano Zampini ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &coordSectionNew);CHKERRQ(ierr); 2764b9ccc978SStefano Zampini ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 2765412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dE);CHKERRQ(ierr); 2766412e9a14SMatthew G. Knepley ierr = DMPlexGetDepthStratum(rdm, 0, &vStartNew, &vEndNew);CHKERRQ(ierr); 2767412e9a14SMatthew G. Knepley if (localizeCells) {ierr = PetscSectionSetChart(coordSectionNew, 0, vEndNew);CHKERRQ(ierr);} 2768412e9a14SMatthew G. Knepley else {ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vEndNew);CHKERRQ(ierr);} 2769b9ccc978SStefano Zampini 2770412e9a14SMatthew G. Knepley /* Localization should be inherited */ 2771412e9a14SMatthew G. Knepley /* Stefano calculates parent cells for each new cell for localization */ 2772412e9a14SMatthew G. Knepley /* Localized cells need coordinates of closure */ 2773412e9a14SMatthew G. Knepley for (v = vStartNew; v < vEndNew; ++v) { 2774412e9a14SMatthew G. Knepley ierr = PetscSectionSetDof(coordSectionNew, v, dE);CHKERRQ(ierr); 2775412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dE);CHKERRQ(ierr); 2776412e9a14SMatthew G. Knepley } 2777412e9a14SMatthew G. Knepley if (localizeCells) { 2778412e9a14SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 2779412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 2780412e9a14SMatthew G. Knepley PetscInt dof; 278190b157c4SStefano Zampini 2782412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, c, &dof); CHKERRQ(ierr); 2783412e9a14SMatthew G. Knepley if (dof) { 2784412e9a14SMatthew G. Knepley DMPolytopeType ct; 2785412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2786412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2787412e9a14SMatthew G. Knepley PetscInt dim, cNew, Nct, n, r; 278890b157c4SStefano Zampini 2789412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 2790412e9a14SMatthew G. Knepley dim = DMPolytopeTypeGetDim(ct); 2791412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2792412e9a14SMatthew G. Knepley /* This allows for different cell types */ 2793412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2794412e9a14SMatthew G. Knepley if (dim != DMPolytopeTypeGetDim(rct[n])) continue; 2795412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2796412e9a14SMatthew G. Knepley PetscInt *closure = NULL; 2797412e9a14SMatthew G. Knepley PetscInt clSize, cl, Nv = 0; 279890b157c4SStefano Zampini 2799412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], c, r, &cNew);CHKERRQ(ierr); 2800412e9a14SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 2801412e9a14SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) {if ((closure[cl] >= vStartNew) && (closure[cl] < vEndNew)) ++Nv;} 2802412e9a14SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 2803412e9a14SMatthew G. Knepley ierr = PetscSectionSetDof(coordSectionNew, cNew, Nv * dE);CHKERRQ(ierr); 2804412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSectionNew, cNew, 0, Nv * dE);CHKERRQ(ierr); 28059fc2a3f3SStefano Zampini } 280690b157c4SStefano Zampini } 280790b157c4SStefano Zampini } 2808412e9a14SMatthew G. Knepley } 280975d3a19aSMatthew G. Knepley } 281075d3a19aSMatthew G. Knepley ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 2811412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-coarse_dm_view");CHKERRQ(ierr); 281246e270d4SMatthew G. Knepley ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 2813412e9a14SMatthew G. Knepley { 2814412e9a14SMatthew G. Knepley VecType vtype; 2815412e9a14SMatthew G. Knepley PetscInt coordSizeNew, bs; 2816412e9a14SMatthew G. Knepley const char *name; 2817412e9a14SMatthew G. Knepley 2818412e9a14SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); 2819412e9a14SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordsLocalNew);CHKERRQ(ierr); 282075d3a19aSMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 2821412e9a14SMatthew G. Knepley ierr = VecSetSizes(coordsLocalNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 2822412e9a14SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) coordsLocal, &name);CHKERRQ(ierr); 2823412e9a14SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordsLocalNew, name);CHKERRQ(ierr); 2824412e9a14SMatthew G. Knepley ierr = VecGetBlockSize(coordsLocal, &bs);CHKERRQ(ierr); 2825412e9a14SMatthew G. Knepley ierr = VecSetBlockSize(coordsLocalNew, bs);CHKERRQ(ierr); 2826412e9a14SMatthew G. Knepley ierr = VecGetType(coordsLocal, &vtype);CHKERRQ(ierr); 2827412e9a14SMatthew G. Knepley ierr = VecSetType(coordsLocalNew, vtype);CHKERRQ(ierr); 2828b5da9499SMatthew G. Knepley } 2829412e9a14SMatthew G. Knepley ierr = VecGetArrayRead(coordsLocal, &coords);CHKERRQ(ierr); 2830412e9a14SMatthew G. Knepley ierr = VecGetArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr); 2831412e9a14SMatthew G. Knepley ierr = PetscSectionGetChart(coordSection, &ocStart, &ocEnd);CHKERRQ(ierr); 2832412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2833412e9a14SMatthew G. Knepley /* First set coordinates for vertices*/ 2834412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2835412e9a14SMatthew G. Knepley DMPolytopeType ct; 2836412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2837412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2838412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2839412e9a14SMatthew G. Knepley PetscBool hasVertex = PETSC_FALSE, isLocalized = PETSC_FALSE; 284090b157c4SStefano Zampini 2841412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2842412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2843412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2844412e9a14SMatthew G. Knepley if (rct[n] == DM_POLYTOPE_POINT) {hasVertex = PETSC_TRUE; break;} 2845412e9a14SMatthew G. Knepley } 2846412e9a14SMatthew G. Knepley if (localizeVertices && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) { 2847412e9a14SMatthew G. Knepley PetscInt dof; 2848412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, p, &dof); CHKERRQ(ierr); 2849412e9a14SMatthew G. Knepley if (dof) isLocalized = PETSC_TRUE; 2850412e9a14SMatthew G. Knepley } 2851412e9a14SMatthew G. Knepley if (hasVertex) { 2852*a5801f52SStefano Zampini const PetscScalar *icoords = NULL; 2853412e9a14SMatthew G. Knepley PetscScalar *pcoords = NULL; 2854412e9a14SMatthew G. Knepley PetscInt Nc, Nv, v, d; 285590b157c4SStefano Zampini 2856412e9a14SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr); 2857*a5801f52SStefano Zampini 2858*a5801f52SStefano Zampini icoords = pcoords; 2859*a5801f52SStefano Zampini Nv = Nc/dE; 2860*a5801f52SStefano Zampini if (ct != DM_POLYTOPE_POINT) { 2861412e9a14SMatthew G. Knepley if (localizeVertices) { 2862412e9a14SMatthew G. Knepley PetscScalar anchor[3]; 286390b157c4SStefano Zampini 2864412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) anchor[d] = pcoords[d]; 2865412e9a14SMatthew G. Knepley if (!isLocalized) { 2866*a5801f52SStefano Zampini for (v = 0; v < Nv; ++v) {ierr = DMLocalizeCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], &pcoords[v*dE]);CHKERRQ(ierr);} 2867412e9a14SMatthew G. Knepley } else { 2868412e9a14SMatthew G. Knepley Nv = Nc/(2*dE); 2869*a5801f52SStefano Zampini icoords = pcoords + Nv*dE; 2870*a5801f52SStefano Zampini for (v = Nv; v < Nv*2; ++v) {ierr = DMLocalizeCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], &pcoords[v*dE]);CHKERRQ(ierr);} 287190b157c4SStefano Zampini } 2872b5da9499SMatthew G. Knepley } 287390b157c4SStefano Zampini } 2874412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2875412e9a14SMatthew G. Knepley if (rct[n] != DM_POLYTOPE_POINT) continue; 2876412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2877*a5801f52SStefano Zampini PetscScalar vcoords[3]; 2878412e9a14SMatthew G. Knepley PetscInt vNew, off; 2879b5da9499SMatthew G. Knepley 2880412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &vNew);CHKERRQ(ierr); 2881412e9a14SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, vNew, &off);CHKERRQ(ierr); 2882*a5801f52SStefano Zampini ierr = DMPlexCellRefinerMapCoordinates(cr, ct, rct[n], r, Nv, dE, icoords, vcoords);CHKERRQ(ierr); 2883eac51794SMatthew G. Knepley ierr = DMPlexSnapToGeomModel(dm, p, vcoords, &coordsNew[off]);CHKERRQ(ierr); 2884b5da9499SMatthew G. Knepley } 28859fc2a3f3SStefano Zampini } 2886*a5801f52SStefano Zampini ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr); 2887412e9a14SMatthew G. Knepley } 2888412e9a14SMatthew G. Knepley } 2889412e9a14SMatthew G. Knepley /* Then set coordinates for cells by localizing */ 2890412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2891412e9a14SMatthew G. Knepley DMPolytopeType ct; 2892412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2893412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2894412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2895412e9a14SMatthew G. Knepley PetscBool isLocalized = PETSC_FALSE; 289690b157c4SStefano Zampini 2897412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2898412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2899412e9a14SMatthew G. Knepley if (localizeCells && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) { 2900412e9a14SMatthew G. Knepley PetscInt dof; 2901412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, p, &dof); CHKERRQ(ierr); 2902412e9a14SMatthew G. Knepley if (dof) isLocalized = PETSC_TRUE; 2903b5da9499SMatthew G. Knepley } 2904412e9a14SMatthew G. Knepley if (isLocalized) { 2905412e9a14SMatthew G. Knepley const PetscScalar *pcoords; 29069fc2a3f3SStefano Zampini 2907412e9a14SMatthew G. Knepley ierr = DMPlexPointLocalRead(cdm, p, coords, &pcoords);CHKERRQ(ierr); 2908412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2909412e9a14SMatthew G. Knepley const PetscInt Nr = rsize[n]; 291090b157c4SStefano Zampini 2911412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ct) != DMPolytopeTypeGetDim(rct[n])) continue; 2912412e9a14SMatthew G. Knepley for (r = 0; r < Nr; ++r) { 2913412e9a14SMatthew G. Knepley PetscInt pNew, offNew; 291490b157c4SStefano Zampini 2915412e9a14SMatthew G. Knepley /* It looks like Stefano and Lisandro are allowing localized coordinates without defining the periodic boundary, which means that 2916412e9a14SMatthew G. Knepley DMLocalizeCoordinate_Internal() will not work. Localized coordinates will have to have obtained by the affine map of the larger 2917412e9a14SMatthew G. Knepley cell to the ones it produces. */ 2918412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 2919412e9a14SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, pNew, &offNew);CHKERRQ(ierr); 2920412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapLocalizedCoordinates(cr, ct, rct[n], r, pcoords, &coordsNew[offNew]);CHKERRQ(ierr); 292190b157c4SStefano Zampini } 292290b157c4SStefano Zampini } 292390b157c4SStefano Zampini } 292490b157c4SStefano Zampini } 2925412e9a14SMatthew G. Knepley ierr = VecRestoreArrayRead(coordsLocal, &coords);CHKERRQ(ierr); 2926412e9a14SMatthew G. Knepley ierr = VecRestoreArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr); 2927412e9a14SMatthew G. Knepley ierr = DMSetCoordinatesLocal(rdm, coordsLocalNew);CHKERRQ(ierr); 2928412e9a14SMatthew G. Knepley /* TODO Stefano has a final reduction if some hybrid coordinates cannot be found. (needcoords) Should not be needed. */ 2929412e9a14SMatthew G. Knepley ierr = VecDestroy(&coordsLocalNew);CHKERRQ(ierr); 293075d3a19aSMatthew G. Knepley ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 2931412e9a14SMatthew G. Knepley if (!localizeCells) {ierr = DMLocalizeCoordinates(rdm);CHKERRQ(ierr);} 293275d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 293375d3a19aSMatthew G. Knepley } 293475d3a19aSMatthew G. Knepley 2935963fc26aSMatthew G. Knepley /*@ 2936963fc26aSMatthew G. Knepley DMPlexCreateProcessSF - Create an SF which just has process connectivity 2937963fc26aSMatthew G. Knepley 2938d083f849SBarry Smith Collective on dm 2939963fc26aSMatthew G. Knepley 2940963fc26aSMatthew G. Knepley Input Parameters: 2941963fc26aSMatthew G. Knepley + dm - The DM 2942963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity 2943963fc26aSMatthew G. Knepley 2944963fc26aSMatthew G. Knepley Output Parameters: 2945963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL 2946963fc26aSMatthew G. Knepley - sfProcess - An SF encoding the process connectivity, or NULL 2947963fc26aSMatthew G. Knepley 2948963fc26aSMatthew G. Knepley Level: developer 2949963fc26aSMatthew G. Knepley 2950963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 2951963fc26aSMatthew G. Knepley @*/ 2952963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 295375d3a19aSMatthew G. Knepley { 295475d3a19aSMatthew G. Knepley PetscInt numRoots, numLeaves, l; 295575d3a19aSMatthew G. Knepley const PetscInt *localPoints; 295675d3a19aSMatthew G. Knepley const PetscSFNode *remotePoints; 295775d3a19aSMatthew G. Knepley PetscInt *localPointsNew; 295875d3a19aSMatthew G. Knepley PetscSFNode *remotePointsNew; 295975d3a19aSMatthew G. Knepley PetscInt *ranks, *ranksNew; 29609852e123SBarry Smith PetscMPIInt size; 296175d3a19aSMatthew G. Knepley PetscErrorCode ierr; 296275d3a19aSMatthew G. Knepley 296375d3a19aSMatthew G. Knepley PetscFunctionBegin; 2964963fc26aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2965963fc26aSMatthew G. Knepley PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 2966963fc26aSMatthew G. Knepley if (processRanks) {PetscValidPointer(processRanks, 3);} 2967963fc26aSMatthew G. Knepley if (sfProcess) {PetscValidPointer(sfProcess, 4);} 29689852e123SBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 296975d3a19aSMatthew G. Knepley ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 2970785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 297175d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 297275d3a19aSMatthew G. Knepley ranks[l] = remotePoints[l].rank; 297375d3a19aSMatthew G. Knepley } 297475d3a19aSMatthew G. Knepley ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 2975785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 2976785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 2977785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 297875d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 297975d3a19aSMatthew G. Knepley ranksNew[l] = ranks[l]; 298075d3a19aSMatthew G. Knepley localPointsNew[l] = l; 298175d3a19aSMatthew G. Knepley remotePointsNew[l].index = 0; 298275d3a19aSMatthew G. Knepley remotePointsNew[l].rank = ranksNew[l]; 298375d3a19aSMatthew G. Knepley } 298475d3a19aSMatthew G. Knepley ierr = PetscFree(ranks);CHKERRQ(ierr); 2985963fc26aSMatthew G. Knepley if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 2986963fc26aSMatthew G. Knepley else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 2987963fc26aSMatthew G. Knepley if (sfProcess) { 298875d3a19aSMatthew G. Knepley ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 2989963fc26aSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 299075d3a19aSMatthew G. Knepley ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 29919852e123SBarry Smith ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 2992963fc26aSMatthew G. Knepley } 299375d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 299475d3a19aSMatthew G. Knepley } 299575d3a19aSMatthew G. Knepley 2996412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateSF(DMPlexCellRefiner cr, DM rdm) 299775d3a19aSMatthew G. Knepley { 2998412e9a14SMatthew G. Knepley DM dm = cr->dm; 2999412e9a14SMatthew G. Knepley DMPlexCellRefiner *crRem; 300075d3a19aSMatthew G. Knepley PetscSF sf, sfNew, sfProcess; 300175d3a19aSMatthew G. Knepley IS processRanks; 3002412e9a14SMatthew G. Knepley MPI_Datatype ctType; 300375d3a19aSMatthew G. Knepley PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 300475d3a19aSMatthew G. Knepley const PetscInt *localPoints, *neighbors; 300575d3a19aSMatthew G. Knepley const PetscSFNode *remotePoints; 300675d3a19aSMatthew G. Knepley PetscInt *localPointsNew; 300775d3a19aSMatthew G. Knepley PetscSFNode *remotePointsNew; 3008412e9a14SMatthew G. Knepley PetscInt *ctStartRem, *ctStartNewRem; 3009412e9a14SMatthew G. Knepley PetscInt ctSize = DM_NUM_POLYTOPES+1, numNeighbors, n, pStartNew, pEndNew, pNew, pNewRem; 301075d3a19aSMatthew G. Knepley PetscErrorCode ierr; 301175d3a19aSMatthew G. Knepley 301275d3a19aSMatthew G. Knepley PetscFunctionBegin; 301375d3a19aSMatthew G. Knepley ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 301475d3a19aSMatthew G. Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 301575d3a19aSMatthew G. Knepley ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 3016add09238SMatthew G. Knepley /* Calculate size of new SF */ 301775d3a19aSMatthew G. Knepley ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 301875d3a19aSMatthew G. Knepley if (numRoots < 0) PetscFunctionReturn(0); 301975d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 302075d3a19aSMatthew G. Knepley const PetscInt p = localPoints[l]; 3021412e9a14SMatthew G. Knepley DMPolytopeType ct; 3022412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3023412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 3024412e9a14SMatthew G. Knepley PetscInt Nct, n; 302575d3a19aSMatthew G. Knepley 3026412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 3027412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 3028412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) numLeavesNew += rsize[n]; 30290314a74cSLawrence Mitchell } 3030412e9a14SMatthew G. Knepley /* Communicate ctStart and cStartNew for each remote rank */ 303175d3a19aSMatthew G. Knepley ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 303275d3a19aSMatthew G. Knepley ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 3033412e9a14SMatthew G. Knepley ierr = PetscMalloc2(ctSize*numNeighbors, &ctStartRem, ctSize*numNeighbors, &ctStartNewRem);CHKERRQ(ierr); 3034412e9a14SMatthew G. Knepley ierr = MPI_Type_contiguous(ctSize, MPIU_INT, &ctType);CHKERRQ(ierr); 3035412e9a14SMatthew G. Knepley ierr = MPI_Type_commit(&ctType);CHKERRQ(ierr); 3036412e9a14SMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr); 3037412e9a14SMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr); 3038412e9a14SMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr); 3039412e9a14SMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr); 3040412e9a14SMatthew G. Knepley ierr = MPI_Type_free(&ctType);CHKERRQ(ierr); 304175d3a19aSMatthew G. Knepley ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 3042412e9a14SMatthew G. Knepley ierr = PetscMalloc1(numNeighbors, &crRem);CHKERRQ(ierr); 3043412e9a14SMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) { 3044412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &crRem[n]);CHKERRQ(ierr); 3045412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetStarts(crRem[n], &ctStartRem[n*ctSize], &ctStartNewRem[n*ctSize]); 3046412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(crRem[n]);CHKERRQ(ierr); 3047412e9a14SMatthew G. Knepley } 3048412e9a14SMatthew G. Knepley ierr = PetscFree2(ctStartRem, ctStartNewRem);CHKERRQ(ierr); 304975d3a19aSMatthew G. Knepley /* Calculate new point SF */ 3050785e854fSJed Brown ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 3051785e854fSJed Brown ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 305275d3a19aSMatthew G. Knepley ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 305375d3a19aSMatthew G. Knepley for (l = 0, m = 0; l < numLeaves; ++l) { 305475d3a19aSMatthew G. Knepley PetscInt p = localPoints[l]; 3055412e9a14SMatthew G. Knepley PetscInt pRem = remotePoints[l].index; 3056412e9a14SMatthew G. Knepley PetscMPIInt rankRem = remotePoints[l].rank; 3057412e9a14SMatthew G. Knepley DMPolytopeType ct; 3058412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3059412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 3060412e9a14SMatthew G. Knepley PetscInt neighbor, Nct, n, r; 306175d3a19aSMatthew G. Knepley 3062412e9a14SMatthew G. Knepley ierr = PetscFindInt(rankRem, numNeighbors, neighbors, &neighbor);CHKERRQ(ierr); 3063412e9a14SMatthew G. Knepley if (neighbor < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rankRem); 3064412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 3065412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 3066412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 3067412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 3068412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 3069412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(crRem[neighbor], ct, rct[n], pRem, r, &pNewRem);CHKERRQ(ierr); 3070412e9a14SMatthew G. Knepley localPointsNew[m] = pNew; 3071412e9a14SMatthew G. Knepley remotePointsNew[m].index = pNewRem; 3072412e9a14SMatthew G. Knepley remotePointsNew[m].rank = rankRem; 30730314a74cSLawrence Mitchell ++m; 30740314a74cSLawrence Mitchell } 30756ce3c06aSMatthew G. Knepley } 30766ce3c06aSMatthew G. Knepley } 3077412e9a14SMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) {ierr = DMPlexCellRefinerDestroy(&crRem[n]);CHKERRQ(ierr);} 3078412e9a14SMatthew G. Knepley ierr = PetscFree(crRem);CHKERRQ(ierr); 3079d7eabd03SStefano Zampini if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew); 308075d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 308175d3a19aSMatthew G. Knepley ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 3082ba3c3d50SMatthew G. Knepley { 3083ba3c3d50SMatthew G. Knepley PetscSFNode *rp, *rtmp; 3084ba3c3d50SMatthew G. Knepley PetscInt *lp, *idx, *ltmp, i; 3085ba3c3d50SMatthew G. Knepley 3086ba3c3d50SMatthew G. Knepley /* SF needs sorted leaves to correct calculate Gather */ 3087ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &idx);CHKERRQ(ierr); 3088ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 3089ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 3090c7c54c77SMatthew G. Knepley for (i = 0; i < numLeavesNew; ++i) { 3091d7eabd03SStefano 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); 3092c7c54c77SMatthew G. Knepley idx[i] = i; 3093c7c54c77SMatthew G. Knepley } 3094ba3c3d50SMatthew G. Knepley ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 3095ba3c3d50SMatthew G. Knepley for (i = 0; i < numLeavesNew; ++i) { 3096ba3c3d50SMatthew G. Knepley lp[i] = localPointsNew[idx[i]]; 3097ba3c3d50SMatthew G. Knepley rp[i] = remotePointsNew[idx[i]]; 3098ba3c3d50SMatthew G. Knepley } 3099ba3c3d50SMatthew G. Knepley ltmp = localPointsNew; 3100ba3c3d50SMatthew G. Knepley localPointsNew = lp; 3101ba3c3d50SMatthew G. Knepley rtmp = remotePointsNew; 3102ba3c3d50SMatthew G. Knepley remotePointsNew = rp; 3103ba3c3d50SMatthew G. Knepley ierr = PetscFree(idx);CHKERRQ(ierr); 3104ba3c3d50SMatthew G. Knepley ierr = PetscFree(ltmp);CHKERRQ(ierr); 3105ba3c3d50SMatthew G. Knepley ierr = PetscFree(rtmp);CHKERRQ(ierr); 3106ba3c3d50SMatthew G. Knepley } 310775d3a19aSMatthew G. Knepley ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 310875d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 310975d3a19aSMatthew G. Knepley } 311075d3a19aSMatthew G. Knepley 3111e7887635SMatthew G. Knepley static PetscErrorCode RefineLabel_Internal(DMPlexCellRefiner cr, DMLabel label, DMLabel labelNew) 311275d3a19aSMatthew G. Knepley { 3113412e9a14SMatthew G. Knepley DM dm = cr->dm; 3114e7887635SMatthew G. Knepley IS valueIS; 3115e7887635SMatthew G. Knepley const PetscInt *values; 3116e7887635SMatthew G. Knepley PetscInt defVal, Nv, val; 311775d3a19aSMatthew G. Knepley PetscErrorCode ierr; 311875d3a19aSMatthew G. Knepley 311975d3a19aSMatthew G. Knepley PetscFunctionBegin; 31205aa44df4SToby Isaac ierr = DMLabelGetDefaultValue(label, &defVal);CHKERRQ(ierr); 31215aa44df4SToby Isaac ierr = DMLabelSetDefaultValue(labelNew, defVal);CHKERRQ(ierr); 312275d3a19aSMatthew G. Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 3123e7887635SMatthew G. Knepley ierr = ISGetLocalSize(valueIS, &Nv);CHKERRQ(ierr); 312475d3a19aSMatthew G. Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 3125e7887635SMatthew G. Knepley for (val = 0; val < Nv; ++val) { 312675d3a19aSMatthew G. Knepley IS pointIS; 312775d3a19aSMatthew G. Knepley const PetscInt *points; 3128412e9a14SMatthew G. Knepley PetscInt numPoints, p; 312975d3a19aSMatthew G. Knepley 31302bc5314cSMichael Lange /* Ensure refined label is created with same number of strata as 31312bc5314cSMichael Lange * original (even if no entries here). */ 3132ad8374ffSToby Isaac ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 3133412e9a14SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 3134412e9a14SMatthew G. Knepley ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 3135412e9a14SMatthew G. Knepley ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 3136412e9a14SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 3137412e9a14SMatthew G. Knepley const PetscInt point = points[p]; 3138412e9a14SMatthew G. Knepley DMPolytopeType ct; 3139412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3140412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 3141e7887635SMatthew G. Knepley PetscInt Nct, n, r, pNew; 3142412e9a14SMatthew G. Knepley 3143412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, point, &ct);CHKERRQ(ierr); 3144412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 3145412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 3146412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 3147412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], point, r, &pNew);CHKERRQ(ierr); 3148412e9a14SMatthew G. Knepley ierr = DMLabelSetValue(labelNew, pNew, values[val]);CHKERRQ(ierr); 314927fcede3SMatthew G. Knepley } 315075d3a19aSMatthew G. Knepley } 315175d3a19aSMatthew G. Knepley } 315275d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 315375d3a19aSMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 315475d3a19aSMatthew G. Knepley } 315575d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 315675d3a19aSMatthew G. Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 3157e7887635SMatthew G. Knepley PetscFunctionReturn(0); 3158e7887635SMatthew G. Knepley } 3159e7887635SMatthew G. Knepley 3160e7887635SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateLabels(DMPlexCellRefiner cr, DM rdm) 3161e7887635SMatthew G. Knepley { 3162e7887635SMatthew G. Knepley DM dm = cr->dm; 3163e7887635SMatthew G. Knepley PetscInt numLabels, l; 3164e7887635SMatthew G. Knepley PetscErrorCode ierr; 3165e7887635SMatthew G. Knepley 3166e7887635SMatthew G. Knepley PetscFunctionBegin; 3167e7887635SMatthew G. Knepley ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 3168e7887635SMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 3169e7887635SMatthew G. Knepley DMLabel label, labelNew; 3170e7887635SMatthew G. Knepley const char *lname; 3171e7887635SMatthew G. Knepley PetscBool isDepth, isCellType; 3172e7887635SMatthew G. Knepley 3173e7887635SMatthew G. Knepley ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 3174e7887635SMatthew G. Knepley ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 3175e7887635SMatthew G. Knepley if (isDepth) continue; 3176e7887635SMatthew G. Knepley ierr = PetscStrcmp(lname, "celltype", &isCellType);CHKERRQ(ierr); 3177e7887635SMatthew G. Knepley if (isCellType) continue; 3178e7887635SMatthew G. Knepley ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 3179e7887635SMatthew G. Knepley ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 3180e7887635SMatthew G. Knepley ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 3181e7887635SMatthew G. Knepley ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr); 318275d3a19aSMatthew G. Knepley } 318375d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 318475d3a19aSMatthew G. Knepley } 318575d3a19aSMatthew G. Knepley 318675d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */ 3187412e9a14SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform(DM dm, DMPlexCellRefiner cr, DM *dmRefined) 318875d3a19aSMatthew G. Knepley { 318975d3a19aSMatthew G. Knepley DM rdm; 3190412e9a14SMatthew G. Knepley PetscInt dim, embedDim, depth; 319175d3a19aSMatthew G. Knepley PetscErrorCode ierr; 319275d3a19aSMatthew G. Knepley 319375d3a19aSMatthew G. Knepley PetscFunctionBegin; 3194412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 319575d3a19aSMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 319675d3a19aSMatthew G. Knepley ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 3197c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3198c73cfb54SMatthew G. Knepley ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 31996dcbd917SStefano Zampini ierr = DMGetCoordinateDim(dm, &embedDim);CHKERRQ(ierr); 32006dcbd917SStefano Zampini ierr = DMSetCoordinateDim(rdm, embedDim);CHKERRQ(ierr); 320175d3a19aSMatthew G. Knepley /* Calculate number of new points of each depth */ 320275d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 32031e573d11SMatthew G. Knepley if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 320475d3a19aSMatthew G. Knepley /* Step 1: Set chart */ 3205412e9a14SMatthew G. Knepley ierr = DMPlexSetChart(rdm, 0, cr->ctStartNew[cr->ctOrder[DM_NUM_POLYTOPES]]);CHKERRQ(ierr); 32066d7373e8SToby Isaac /* Step 2: Set cone/support sizes (automatically stratifies) */ 3207412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetConeSizes(cr, rdm);CHKERRQ(ierr); 320875d3a19aSMatthew G. Knepley /* Step 3: Setup refined DM */ 320975d3a19aSMatthew G. Knepley ierr = DMSetUp(rdm);CHKERRQ(ierr); 32106d7373e8SToby Isaac /* Step 4: Set cones and supports (automatically symmetrizes) */ 3211412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetCones(cr, rdm);CHKERRQ(ierr); 32126d7373e8SToby Isaac /* Step 5: Create pointSF */ 3213412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreateSF(cr, rdm);CHKERRQ(ierr); 32146d7373e8SToby Isaac /* Step 6: Create labels */ 3215412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreateLabels(cr, rdm);CHKERRQ(ierr); 32166d7373e8SToby Isaac /* Step 7: Set coordinates */ 3217412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetCoordinates(cr, rdm);CHKERRQ(ierr); 321875d3a19aSMatthew G. Knepley *dmRefined = rdm; 321975d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 322075d3a19aSMatthew G. Knepley } 322175d3a19aSMatthew G. Knepley 32222389894bSMatthew G. Knepley /*@ 32232389894bSMatthew G. Knepley DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 32242389894bSMatthew G. Knepley 32252389894bSMatthew G. Knepley Input Parameter: 32262389894bSMatthew G. Knepley . dm - The coarse DM 32272389894bSMatthew G. Knepley 32282389894bSMatthew G. Knepley Output Parameter: 32292389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh 32302389894bSMatthew G. Knepley 32312389894bSMatthew G. Knepley Level: developer 32322389894bSMatthew G. Knepley 323397d8846cSMatthew Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetSubpointIS() 32342389894bSMatthew G. Knepley @*/ 32352389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 32362389894bSMatthew G. Knepley { 3237412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 3238412e9a14SMatthew G. Knepley PetscInt *fpoints; 3239327c2912SStefano Zampini PetscInt pStart, pEnd, p, vStart, vEnd, v; 32402389894bSMatthew G. Knepley PetscErrorCode ierr; 32412389894bSMatthew G. Knepley 32422389894bSMatthew G. Knepley PetscFunctionBegin; 32432389894bSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 32442389894bSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 3245412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr); 3246412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 32472389894bSMatthew G. Knepley ierr = PetscMalloc1(pEnd-pStart, &fpoints);CHKERRQ(ierr); 32482389894bSMatthew G. Knepley for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 3249412e9a14SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 3250327c2912SStefano Zampini PetscInt vNew = -1; /* silent overzelous may be used uninitialized */ 3251327c2912SStefano Zampini 3252412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, DM_POLYTOPE_POINT, DM_POLYTOPE_POINT, p, 0, &vNew);CHKERRQ(ierr); 3253412e9a14SMatthew G. Knepley fpoints[v-pStart] = vNew; 32542389894bSMatthew G. Knepley } 3255412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 32562389894bSMatthew G. Knepley ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 32572389894bSMatthew G. Knepley PetscFunctionReturn(0); 32582389894bSMatthew G. Knepley } 32592389894bSMatthew G. Knepley 32600e2b6761SMatthew G. Knepley /*@ 32610e2b6761SMatthew G. Knepley DMPlexSetRefinementUniform - Set the flag for uniform refinement 32620e2b6761SMatthew G. Knepley 32630e2b6761SMatthew G. Knepley Input Parameters: 32640e2b6761SMatthew G. Knepley + dm - The DM 32650e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement 32660e2b6761SMatthew G. Knepley 32670e2b6761SMatthew G. Knepley Level: developer 32680e2b6761SMatthew G. Knepley 32690e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 32700e2b6761SMatthew G. Knepley @*/ 327175d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 327275d3a19aSMatthew G. Knepley { 327375d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 327475d3a19aSMatthew G. Knepley 327575d3a19aSMatthew G. Knepley PetscFunctionBegin; 327675d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 327775d3a19aSMatthew G. Knepley mesh->refinementUniform = refinementUniform; 327875d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 327975d3a19aSMatthew G. Knepley } 328075d3a19aSMatthew G. Knepley 32810e2b6761SMatthew G. Knepley /*@ 32820e2b6761SMatthew G. Knepley DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 32830e2b6761SMatthew G. Knepley 32840e2b6761SMatthew G. Knepley Input Parameter: 32850e2b6761SMatthew G. Knepley . dm - The DM 32860e2b6761SMatthew G. Knepley 32870e2b6761SMatthew G. Knepley Output Parameter: 32880e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement 32890e2b6761SMatthew G. Knepley 32900e2b6761SMatthew G. Knepley Level: developer 32910e2b6761SMatthew G. Knepley 32920e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 32930e2b6761SMatthew G. Knepley @*/ 329475d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 329575d3a19aSMatthew G. Knepley { 329675d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 329775d3a19aSMatthew G. Knepley 329875d3a19aSMatthew G. Knepley PetscFunctionBegin; 329975d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 330075d3a19aSMatthew G. Knepley PetscValidPointer(refinementUniform, 2); 330175d3a19aSMatthew G. Knepley *refinementUniform = mesh->refinementUniform; 330275d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 330375d3a19aSMatthew G. Knepley } 330475d3a19aSMatthew G. Knepley 33050e2b6761SMatthew G. Knepley /*@ 33060e2b6761SMatthew G. Knepley DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 33070e2b6761SMatthew G. Knepley 33080e2b6761SMatthew G. Knepley Input Parameters: 33090e2b6761SMatthew G. Knepley + dm - The DM 33100e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh 33110e2b6761SMatthew G. Knepley 33120e2b6761SMatthew G. Knepley Level: developer 33130e2b6761SMatthew G. Knepley 33140e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 33150e2b6761SMatthew G. Knepley @*/ 331675d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 331775d3a19aSMatthew G. Knepley { 331875d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 331975d3a19aSMatthew G. Knepley 332075d3a19aSMatthew G. Knepley PetscFunctionBegin; 332175d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 332275d3a19aSMatthew G. Knepley mesh->refinementLimit = refinementLimit; 332375d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 332475d3a19aSMatthew G. Knepley } 332575d3a19aSMatthew G. Knepley 33260e2b6761SMatthew G. Knepley /*@ 33270e2b6761SMatthew G. Knepley DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 33280e2b6761SMatthew G. Knepley 33290e2b6761SMatthew G. Knepley Input Parameter: 33300e2b6761SMatthew G. Knepley . dm - The DM 33310e2b6761SMatthew G. Knepley 33320e2b6761SMatthew G. Knepley Output Parameter: 33330e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh 33340e2b6761SMatthew G. Knepley 33350e2b6761SMatthew G. Knepley Level: developer 33360e2b6761SMatthew G. Knepley 33370e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 33380e2b6761SMatthew G. Knepley @*/ 333975d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 334075d3a19aSMatthew G. Knepley { 334175d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 334275d3a19aSMatthew G. Knepley 334375d3a19aSMatthew G. Knepley PetscFunctionBegin; 334475d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 334575d3a19aSMatthew G. Knepley PetscValidPointer(refinementLimit, 2); 334675d3a19aSMatthew G. Knepley /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 334775d3a19aSMatthew G. Knepley *refinementLimit = mesh->refinementLimit; 334875d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 334975d3a19aSMatthew G. Knepley } 335075d3a19aSMatthew G. Knepley 3351b28003e6SMatthew G. Knepley /*@ 3352b28003e6SMatthew G. Knepley DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 3353b28003e6SMatthew G. Knepley 3354b28003e6SMatthew G. Knepley Input Parameters: 3355b28003e6SMatthew G. Knepley + dm - The DM 3356b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh 3357b28003e6SMatthew G. Knepley 3358b28003e6SMatthew G. Knepley Note: The calling sequence is refinementFunc(coords, limit) 3359b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid 3360b28003e6SMatthew G. Knepley $ limit - The maximum cell volume for a cell containing this point 3361b28003e6SMatthew G. Knepley 3362b28003e6SMatthew G. Knepley Level: developer 3363b28003e6SMatthew G. Knepley 3364b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 3365b28003e6SMatthew G. Knepley @*/ 3366b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 3367b28003e6SMatthew G. Knepley { 3368b28003e6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 3369b28003e6SMatthew G. Knepley 3370b28003e6SMatthew G. Knepley PetscFunctionBegin; 3371b28003e6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3372b28003e6SMatthew G. Knepley mesh->refinementFunc = refinementFunc; 3373b28003e6SMatthew G. Knepley PetscFunctionReturn(0); 3374b28003e6SMatthew G. Knepley } 3375b28003e6SMatthew G. Knepley 3376b28003e6SMatthew G. Knepley /*@ 3377b28003e6SMatthew G. Knepley DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 3378b28003e6SMatthew G. Knepley 3379b28003e6SMatthew G. Knepley Input Parameter: 3380b28003e6SMatthew G. Knepley . dm - The DM 3381b28003e6SMatthew G. Knepley 3382b28003e6SMatthew G. Knepley Output Parameter: 3383b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh 3384b28003e6SMatthew G. Knepley 3385b28003e6SMatthew G. Knepley Note: The calling sequence is refinementFunc(coords, limit) 3386b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid 3387b28003e6SMatthew G. Knepley $ limit - The maximum cell volume for a cell containing this point 3388b28003e6SMatthew G. Knepley 3389b28003e6SMatthew G. Knepley Level: developer 3390b28003e6SMatthew G. Knepley 3391b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 3392b28003e6SMatthew G. Knepley @*/ 3393b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 3394b28003e6SMatthew G. Knepley { 3395b28003e6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 3396b28003e6SMatthew G. Knepley 3397b28003e6SMatthew G. Knepley PetscFunctionBegin; 3398b28003e6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3399b28003e6SMatthew G. Knepley PetscValidPointer(refinementFunc, 2); 3400b28003e6SMatthew G. Knepley *refinementFunc = mesh->refinementFunc; 3401b28003e6SMatthew G. Knepley PetscFunctionReturn(0); 3402b28003e6SMatthew G. Knepley } 3403b28003e6SMatthew G. Knepley 3404e7887635SMatthew G. Knepley static PetscErrorCode RefineDiscLabels_Internal(DMPlexCellRefiner cr, DM rdm) 3405e7887635SMatthew G. Knepley { 3406e7887635SMatthew G. Knepley DM dm = cr->dm; 3407e7887635SMatthew G. Knepley PetscInt Nf, f, Nds, s; 3408e7887635SMatthew G. Knepley PetscErrorCode ierr; 3409e7887635SMatthew G. Knepley 3410e7887635SMatthew G. Knepley PetscFunctionBegin; 3411e7887635SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 3412e7887635SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 3413e7887635SMatthew G. Knepley DMLabel label, labelNew; 3414e7887635SMatthew G. Knepley PetscObject obj; 3415e7887635SMatthew G. Knepley const char *lname; 3416e7887635SMatthew G. Knepley 3417e7887635SMatthew G. Knepley ierr = DMGetField(rdm, f, &label, &obj);CHKERRQ(ierr); 3418e7887635SMatthew G. Knepley if (!label) continue; 3419e7887635SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 3420e7887635SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew);CHKERRQ(ierr); 3421e7887635SMatthew G. Knepley ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr); 3422e7887635SMatthew G. Knepley ierr = DMSetField_Internal(rdm, f, labelNew, obj);CHKERRQ(ierr); 3423e7887635SMatthew G. Knepley ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr); 3424e7887635SMatthew G. Knepley } 3425e7887635SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 3426e7887635SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 3427e7887635SMatthew G. Knepley DMLabel label, labelNew; 3428e7887635SMatthew G. Knepley const char *lname; 3429e7887635SMatthew G. Knepley 3430e7887635SMatthew G. Knepley ierr = DMGetRegionNumDS(rdm, s, &label, NULL, NULL);CHKERRQ(ierr); 3431e7887635SMatthew G. Knepley if (!label) continue; 3432e7887635SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 3433e7887635SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew);CHKERRQ(ierr); 3434e7887635SMatthew G. Knepley ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr); 3435e7887635SMatthew G. Knepley ierr = DMSetRegionNumDS(rdm, s, labelNew, NULL, NULL);CHKERRQ(ierr); 3436e7887635SMatthew G. Knepley ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr); 3437e7887635SMatthew G. Knepley } 3438e7887635SMatthew G. Knepley PetscFunctionReturn(0); 3439e7887635SMatthew G. Knepley } 3440e7887635SMatthew G. Knepley 34410d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 34420d1cd5e0SMatthew G. Knepley { 3443492b8470SStefano Zampini PetscBool isUniform; 3444412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 34450d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 34460d1cd5e0SMatthew G. Knepley 34470d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 34480d1cd5e0SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 3449412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-initref_dm_view");CHKERRQ(ierr); 34500d1cd5e0SMatthew G. Knepley if (isUniform) { 3451492b8470SStefano Zampini PetscBool localized; 34520d1cd5e0SMatthew G. Knepley 3453412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr); 3454412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 3455492b8470SStefano Zampini ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 3456412e9a14SMatthew G. Knepley ierr = DMPlexRefineUniform(dm, cr, dmRefined);CHKERRQ(ierr); 34579a7e3c0aSMatthew G. Knepley ierr = DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);CHKERRQ(ierr); 3458e7887635SMatthew G. Knepley ierr = DMCopyDisc(dm, *dmRefined);CHKERRQ(ierr); 3459e7887635SMatthew G. Knepley ierr = RefineDiscLabels_Internal(cr, *dmRefined);CHKERRQ(ierr); 34600d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 3461412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 34620d1cd5e0SMatthew G. Knepley } else { 34630d1cd5e0SMatthew G. Knepley ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 34640d1cd5e0SMatthew G. Knepley } 34650d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 34660d1cd5e0SMatthew G. Knepley } 34670d1cd5e0SMatthew G. Knepley 34680d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 34690d1cd5e0SMatthew G. Knepley { 34700d1cd5e0SMatthew G. Knepley DM cdm = dm; 34710d1cd5e0SMatthew G. Knepley PetscInt r; 34720d1cd5e0SMatthew G. Knepley PetscBool isUniform, localized; 34730d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 34740d1cd5e0SMatthew G. Knepley 34750d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 34760d1cd5e0SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 34770d1cd5e0SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 34780d1cd5e0SMatthew G. Knepley if (isUniform) { 34790d1cd5e0SMatthew G. Knepley for (r = 0; r < nlevels; ++r) { 3480412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 34810d1cd5e0SMatthew G. Knepley 3482412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(cdm, &cr);CHKERRQ(ierr); 3483412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 3484412e9a14SMatthew G. Knepley ierr = DMPlexRefineUniform(cdm, cr, &dmRefined[r]);CHKERRQ(ierr); 34859a7e3c0aSMatthew G. Knepley ierr = DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);CHKERRQ(ierr); 34869a7e3c0aSMatthew G. Knepley ierr = DMSetRefineLevel(dmRefined[r], cdm->levelup+1);CHKERRQ(ierr); 3487e7887635SMatthew G. Knepley ierr = DMCopyDisc(cdm, dmRefined[r]);CHKERRQ(ierr); 3488e7887635SMatthew G. Knepley ierr = RefineDiscLabels_Internal(cr, dmRefined[r]);CHKERRQ(ierr); 34890d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 34900d1cd5e0SMatthew G. Knepley ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 34910d1cd5e0SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 34920d1cd5e0SMatthew G. Knepley cdm = dmRefined[r]; 3493412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 34940d1cd5e0SMatthew G. Knepley } 34950d1cd5e0SMatthew G. Knepley } else { 34960d1cd5e0SMatthew G. Knepley for (r = 0; r < nlevels; ++r) { 34970d1cd5e0SMatthew G. Knepley ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 3498e7887635SMatthew G. Knepley ierr = DMCopyDisc(cdm, dmRefined[r]);CHKERRQ(ierr); 34990d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 35000d1cd5e0SMatthew G. Knepley if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 35010d1cd5e0SMatthew G. Knepley ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 35020d1cd5e0SMatthew G. Knepley cdm = dmRefined[r]; 35030d1cd5e0SMatthew G. Knepley } 35040d1cd5e0SMatthew G. Knepley } 35050d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 35060d1cd5e0SMatthew G. Knepley } 3507