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 5ea78f98cSLisandro Dalcin const char * const DMPlexCellRefinerTypes[] = {"Regular", "ToBox", "ToSimplex", "Alfeld2D", "Alfeld3D", "PowellSabin", "BoundaryLayer", "DMPlexCellRefinerTypes", "DM_REFINER_", NULL}; 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 278a5801f52SStefano 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: 282a5801f52SStefano 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; 367a5801f52SStefano 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; 440a5801f52SStefano 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 449a5801f52SStefano Zampini . ct - The type being produced 450a5801f52SStefano Zampini . r - The replica number requested for the produced cell type 451a5801f52SStefano Zampini . Nv - Number of vertices in the closure of the parent cell 452a5801f52SStefano Zampini . dE - Spatial dimension 453a5801f52SStefano Zampini - in - array of size Nv*dE, holding coordinates of the vertices in the closure of the parent cell 454a5801f52SStefano Zampini 455a5801f52SStefano Zampini Output Parameters: 456a5801f52SStefano Zampini . out - The coordinates of the new vertices 457a5801f52SStefano Zampini */ 458a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapCoordinates(DMPlexCellRefiner cr, DMPolytopeType pct, DMPolytopeType ct, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[]) 459a5801f52SStefano Zampini { 460a5801f52SStefano Zampini PetscErrorCode ierr; 461a5801f52SStefano Zampini 462a5801f52SStefano Zampini PetscFunctionBeginHot; 463a5801f52SStefano Zampini if (!cr->ops->mapcoords) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]); 464a5801f52SStefano Zampini ierr = (*cr->ops->mapcoords)(cr, pct, ct, r, Nv, dE, in, out);CHKERRQ(ierr); 465a5801f52SStefano Zampini PetscFunctionReturn(0); 466a5801f52SStefano Zampini } 467a5801f52SStefano Zampini 468a5801f52SStefano Zampini /* Computes new vertex as the barycenter */ 469a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapCoordinates_Barycenter(DMPlexCellRefiner cr, DMPolytopeType pct, DMPolytopeType ct, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[]) 470a5801f52SStefano Zampini { 471a5801f52SStefano Zampini PetscInt v,d; 472a5801f52SStefano Zampini 473a5801f52SStefano Zampini PetscFunctionBeginHot; 474a5801f52SStefano Zampini if (ct != DM_POLYTOPE_POINT) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for refined point type %s",DMPolytopeTypes[ct]); 475a5801f52SStefano Zampini for (d = 0; d < dE; ++d) out[d] = 0.0; 476a5801f52SStefano Zampini for (v = 0; v < Nv; ++v) for (d = 0; d < dE; ++d) out[d] += in[v*dE+d]; 477a5801f52SStefano Zampini for (d = 0; d < dE; ++d) out[d] /= Nv; 478a5801f52SStefano Zampini PetscFunctionReturn(0); 479a5801f52SStefano Zampini } 480a5801f52SStefano Zampini 481a5801f52SStefano Zampini /* 482a5801f52SStefano Zampini Input Parameters: 483a5801f52SStefano Zampini + cr - The DMPlexCellRefiner 484a5801f52SStefano 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: 491a5801f52SStefano 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; 499a5801f52SStefano 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 765a5801f52SStefano 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; 787a5801f52SStefano 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}; 842*da9060c4SMatthew G. Knepley static DMPolytopeType pyrT[] = {DM_POLYTOPE_PYRAMID}; 843*da9060c4SMatthew G. Knepley static PetscInt pyrS[] = {1}; 844*da9060c4SMatthew G. Knepley static PetscInt pyrC[] = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, 845*da9060c4SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 1, 3, 0, DM_POLYTOPE_TRIANGLE, 1, 4, 0}; 846*da9060c4SMatthew G. Knepley static PetscInt pyrO[] = {0, 0, 0, 0, 0}; 847cf4091a3SMatthew G. Knepley 848cf4091a3SMatthew G. Knepley PetscFunctionBegin; 849cf4091a3SMatthew G. Knepley switch (source) { 850cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT: *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break; 851cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nt = 1; *target = edgeT; *size = edgeS; *cone = edgeC; *ornt = edgeO; break; 852cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 853cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 1; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 854cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nt = 1; *target = quadT; *size = quadS; *cone = quadC; *ornt = quadO; break; 855cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 1; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 856cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 1; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 857cf4091a3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nt = 1; *target = hexT; *size = hexS; *cone = hexC; *ornt = hexO; break; 858cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 1; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 859cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 1; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 860cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 1; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 861*da9060c4SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: *Nt = 1; *target = pyrT; *size = pyrS; *cone = pyrC; *ornt = pyrO; break; 862cf4091a3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 863cf4091a3SMatthew G. Knepley } 864cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 865cf4091a3SMatthew G. Knepley } 866cf4091a3SMatthew G. Knepley 867412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Regular(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 868412e9a14SMatthew G. Knepley { 869412e9a14SMatthew G. Knepley /* All vertices remain in the refined mesh */ 870412e9a14SMatthew G. Knepley static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT}; 871412e9a14SMatthew G. Knepley static PetscInt vertexS[] = {1}; 872412e9a14SMatthew G. Knepley static PetscInt vertexC[] = {0}; 873412e9a14SMatthew G. Knepley static PetscInt vertexO[] = {0}; 874412e9a14SMatthew G. Knepley /* Split all edges with a new vertex, making two new 2 edges 875412e9a14SMatthew G. Knepley 0--0--0--1--1 876412e9a14SMatthew G. Knepley */ 877412e9a14SMatthew G. Knepley static DMPolytopeType edgeT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT}; 878412e9a14SMatthew G. Knepley static PetscInt edgeS[] = {1, 2}; 879412e9a14SMatthew 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}; 880412e9a14SMatthew G. Knepley static PetscInt edgeO[] = { 0, 0, 0, 0}; 881412e9a14SMatthew G. Knepley /* Do not split tensor edges */ 882412e9a14SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR}; 883412e9a14SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 884412e9a14SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 885412e9a14SMatthew G. Knepley static PetscInt tedgeO[] = { 0, 0}; 886412e9a14SMatthew G. Knepley /* Add 3 edges inside every triangle, making 4 new triangles. 88775d3a19aSMatthew G. Knepley 2 88875d3a19aSMatthew G. Knepley |\ 88975d3a19aSMatthew G. Knepley | \ 89075d3a19aSMatthew G. Knepley | \ 891412e9a14SMatthew G. Knepley 0 1 89275d3a19aSMatthew G. Knepley | C \ 89375d3a19aSMatthew G. Knepley | \ 89475d3a19aSMatthew G. Knepley | \ 89575d3a19aSMatthew G. Knepley 2---1---1 89675d3a19aSMatthew G. Knepley |\ D / \ 897412e9a14SMatthew G. Knepley 1 2 0 0 89875d3a19aSMatthew G. Knepley |A \ / B \ 899412e9a14SMatthew G. Knepley 0-0-0---1---1 90075d3a19aSMatthew G. Knepley */ 901412e9a14SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE}; 902412e9a14SMatthew G. Knepley static PetscInt triS[] = {3, 4}; 903412e9a14SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 904412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 1, 2, 0, 905412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 0, 0, 906412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 907412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 0, 908412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, 909412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2}; 910412e9a14SMatthew G. Knepley static PetscInt triO[] = {0, 0, 911412e9a14SMatthew G. Knepley 0, 0, 912412e9a14SMatthew G. Knepley 0, 0, 913412e9a14SMatthew G. Knepley 0, -2, 0, 914412e9a14SMatthew G. Knepley 0, 0, -2, 915412e9a14SMatthew G. Knepley -2, 0, 0, 916412e9a14SMatthew G. Knepley 0, 0, 0}; 917412e9a14SMatthew G. Knepley /* Add a vertex in the center of each quadrilateral, and 4 edges inside, making 4 new quads. 918412e9a14SMatthew G. Knepley 3----1----2----0----2 919412e9a14SMatthew G. Knepley | | | 920412e9a14SMatthew G. Knepley 0 D 2 C 1 921412e9a14SMatthew G. Knepley | | | 922412e9a14SMatthew G. Knepley 3----3----0----1----1 923412e9a14SMatthew G. Knepley | | | 924412e9a14SMatthew G. Knepley 1 A 0 B 0 925412e9a14SMatthew G. Knepley | | | 926412e9a14SMatthew G. Knepley 0----0----0----1----1 927412e9a14SMatthew G. Knepley */ 928412e9a14SMatthew G. Knepley static DMPolytopeType quadT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 929412e9a14SMatthew G. Knepley static PetscInt quadS[] = {1, 4, 4}; 930412e9a14SMatthew G. Knepley static PetscInt quadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 931412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 932412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 933412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 934412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, 935412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 936412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, 937412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0}; 938412e9a14SMatthew G. Knepley static PetscInt quadO[] = {0, 0, 939412e9a14SMatthew G. Knepley 0, 0, 940412e9a14SMatthew G. Knepley 0, 0, 941412e9a14SMatthew G. Knepley 0, 0, 942412e9a14SMatthew G. Knepley 0, 0, -2, 0, 943412e9a14SMatthew G. Knepley 0, 0, 0, -2, 944412e9a14SMatthew G. Knepley -2, 0, 0, 0, 945412e9a14SMatthew G. Knepley 0, -2, 0, 0}; 946412e9a14SMatthew G. Knepley /* Add 1 edge inside every tensor quad, making 2 new tensor quads 947412e9a14SMatthew G. Knepley 2----2----1----3----3 948412e9a14SMatthew G. Knepley | | | 949412e9a14SMatthew G. Knepley | | | 950412e9a14SMatthew G. Knepley | | | 951412e9a14SMatthew G. Knepley 4 A 6 B 5 952412e9a14SMatthew G. Knepley | | | 953412e9a14SMatthew G. Knepley | | | 954412e9a14SMatthew G. Knepley | | | 955412e9a14SMatthew G. Knepley 0----0----0----1----1 956412e9a14SMatthew G. Knepley */ 957412e9a14SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR}; 958412e9a14SMatthew G. Knepley static PetscInt tquadS[] = {1, 2}; 959412e9a14SMatthew G. Knepley static PetscInt tquadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 960412e9a14SMatthew 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, 961412e9a14SMatthew 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}; 962412e9a14SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 963412e9a14SMatthew G. Knepley 0, 0, 0, 0, 964412e9a14SMatthew G. Knepley 0, 0, 0, 0}; 965412e9a14SMatthew G. Knepley /* Add 1 edge and 8 triangles inside every cell, making 8 new tets 966412e9a14SMatthew 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 967412e9a14SMatthew 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] 968412e9a14SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 969412e9a14SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 970412e9a14SMatthew G. Knepley The first four tets just cut off the corners, using the replica notation for new vertices, 971412e9a14SMatthew G. Knepley [v0, (e0, 0), (e2, 0), (e3, 0)] 972412e9a14SMatthew G. Knepley [(e0, 0), v1, (e1, 0), (e4, 0)] 973412e9a14SMatthew G. Knepley [(e2, 0), (e1, 0), v2, (e5, 0)] 974412e9a14SMatthew G. Knepley [(e3, 0), (e4, 0), (e5, 0), v3 ] 975412e9a14SMatthew G. Knepley The next four tets match a vertex to the newly created faces from cutting off those first tets. 976412e9a14SMatthew G. Knepley [(e2, 0), (e3, 0), (e0, 0), (e5, 0)] 977412e9a14SMatthew G. Knepley [(e4, 0), (e1, 0), (e0, 0), (e5, 0)] 978412e9a14SMatthew G. Knepley [(e5, 0), (e0, 0), (e2, 0), (e1, 0)] 979412e9a14SMatthew G. Knepley [(e5, 0), (e0, 0), (e4, 0), (e3, 0)] 980412e9a14SMatthew 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 981412e9a14SMatthew G. Knepley [(e2, 0), (e0, 0), (e3, 0)] 982412e9a14SMatthew G. Knepley [(e0, 0), (e1, 0), (e4, 0)] 983412e9a14SMatthew G. Knepley [(e2, 0), (e5, 0), (e1, 0)] 984412e9a14SMatthew G. Knepley [(e3, 0), (e4, 0), (e5, 0)] 985412e9a14SMatthew G. Knepley The next four, from the second group of tets, are 986412e9a14SMatthew G. Knepley [(e2, 0), (e0, 0), (e5, 0)] 987412e9a14SMatthew G. Knepley [(e4, 0), (e0, 0), (e5, 0)] 988412e9a14SMatthew G. Knepley [(e0, 0), (e1, 0), (e5, 0)] 989412e9a14SMatthew G. Knepley [(e5, 0), (e3, 0), (e0, 0)] 990412e9a14SMatthew G. Knepley I could write a program to generate these orientations by comparing the faces from GetRawFaces() with my existing table. 991412e9a14SMatthew G. Knepley */ 992412e9a14SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON}; 993412e9a14SMatthew G. Knepley static PetscInt tetS[] = {1, 8, 8}; 994412e9a14SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 2, 2, 1, 0, 995412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 2, 2, 996412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 1, 1, 997412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 1, 0, 1, 998412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 2, 1, 999412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1000412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, 1001412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 0, 1002412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0, 0, 1003412e9a14SMatthew 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, 1004412e9a14SMatthew 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, 1005412e9a14SMatthew 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, 1006412e9a14SMatthew 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, 1007412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 2, 3, DM_POLYTOPE_TRIANGLE, 0, 4, DM_POLYTOPE_TRIANGLE, 0, 7, 1008412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 1, 3, 3, DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 6, 1009412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 4, DM_POLYTOPE_TRIANGLE, 0, 6, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 1, 0, 3, 1010412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 7, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 1, 1, 3}; 1011412e9a14SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 1012412e9a14SMatthew G. Knepley 0, 0, 0, 1013412e9a14SMatthew G. Knepley 0, 0, 0, 1014412e9a14SMatthew G. Knepley 0, 0, 0, 1015412e9a14SMatthew G. Knepley 0, 0, 0, 1016412e9a14SMatthew G. Knepley 0, 0, -2, 1017412e9a14SMatthew G. Knepley 0, 0, -2, 1018412e9a14SMatthew G. Knepley 0, -2, -2, 1019412e9a14SMatthew G. Knepley 0, -2, 0, 1020412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1021412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1022412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1023412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1024412e9a14SMatthew G. Knepley -3, 0, 0, -2, 1025412e9a14SMatthew G. Knepley -2, 1, 0, 0, 1026412e9a14SMatthew G. Knepley -2, -2, -1, 2, 1027412e9a14SMatthew G. Knepley -2, 0, -2, 1}; 1028412e9a14SMatthew G. Knepley /* Add a vertex in the center of each cell, add 6 edges and 12 quads inside every cell, making 8 new hexes 1029412e9a14SMatthew 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 1030412e9a14SMatthew G. Knepley [v0, v1, v2, v3] f0 bottom 1031412e9a14SMatthew G. Knepley [v4, v5, v6, v7] f1 top 1032412e9a14SMatthew G. Knepley [v0, v3, v5, v4] f2 front 1033412e9a14SMatthew G. Knepley [v2, v1, v7, v6] f3 back 1034412e9a14SMatthew G. Knepley [v3, v2, v6, v5] f4 right 1035412e9a14SMatthew G. Knepley [v0, v4, v7, v1] f5 left 1036412e9a14SMatthew G. Knepley The eight hexes are divided into four on the bottom, and four on the top, 1037412e9a14SMatthew G. Knepley [v0, (e0, 0), (f0, 0), (e3, 0), (e9, 0), (f2, 0), (c0, 0), (f5, 0)] 1038412e9a14SMatthew G. Knepley [(e0, 0), v1, (e1, 0), (f0, 0), (f5, 0), (c0, 0), (f3, 0), (e10, 0)] 1039412e9a14SMatthew G. Knepley [(f0, 0), (e1, 0), v2, (e2, 0), (c0, 0), (f4, 0), (e11, 0), (f3, 0)] 1040412e9a14SMatthew G. Knepley [(e3, 0), (f0, 0), (e2, 0), v3, (f2, 0), (e8, 0), (f4, 0), (c0, 0)] 1041412e9a14SMatthew G. Knepley [(e9, 0), (f5, 0), (c0, 0), (f2, 0), v4, (e4, 0), (f1, 0), (e7, 0)] 1042412e9a14SMatthew G. Knepley [(f2, 0), (c0, 0), (f4, 0), (e8, 0), (e4, 0), v5, (e5, 0), (f1, 0)] 1043412e9a14SMatthew G. Knepley [(c0, 0), (f3, 0), (e11, 0), (f4, 0), (f1, 0), (e5, 0), v6, (e6, 0)] 1044412e9a14SMatthew G. Knepley [(f5, 0), (e10, 0), (f3, 0), (c0, 0), (e7, 0), (f1, 0), (e6, 0), v7] 1045412e9a14SMatthew 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, 1046412e9a14SMatthew G. Knepley [(e9, 0), (f2, 0), (c0, 0), (f5, 0)] 1047412e9a14SMatthew G. Knepley [(f5, 0), (c0, 0), (f3, 0), (e10, 0)] 1048412e9a14SMatthew G. Knepley [(c0, 0), (f4, 0), (e11, 0), (f3, 0)] 1049412e9a14SMatthew G. Knepley [(f2, 0), (e8, 0), (f4, 0), (c0, 0)] 1050412e9a14SMatthew G. Knepley and on the x-z plane, 1051412e9a14SMatthew G. Knepley [(f0, 0), (e0, 0), (f5, 0), (c0, 0)] 1052412e9a14SMatthew G. Knepley [(c0, 0), (f5, 0), (e7, 0), (f1, 0)] 1053412e9a14SMatthew G. Knepley [(f4, 0), (c0, 0), (f1, 0), (e5, 0)] 1054412e9a14SMatthew G. Knepley [(e2, 0), (f0, 0), (c0, 0), (f4, 0)] 1055412e9a14SMatthew G. Knepley and on the y-z plane, 1056412e9a14SMatthew G. Knepley [(e3, 0), (f2, 0), (c0, 0), (f0, 0)] 1057412e9a14SMatthew G. Knepley [(f2, 0), (e4, 0), (f1, 0), (c0, 0)] 1058412e9a14SMatthew G. Knepley [(c0, 0), (f1, 0), (e6, 0), (f3, 0)] 1059412e9a14SMatthew G. Knepley [(f0, 0), (c0, 0), (f3, 0), (e1, 0)] 1060412e9a14SMatthew G. Knepley */ 1061412e9a14SMatthew G. Knepley static DMPolytopeType hexT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1062412e9a14SMatthew G. Knepley static PetscInt hexS[] = {1, 6, 12, 8}; 1063412e9a14SMatthew G. Knepley static PetscInt hexC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1064412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1065412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1066412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1067412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0, 1068412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 5, 0, DM_POLYTOPE_POINT, 0, 0, 1069412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 1, 5, 0, 1070412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 5, 2, 1071412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 3, 1072412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 2, 1073412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 5, 3, DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 0, 0, 1074412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 1, 5, 1, DM_POLYTOPE_SEGMENT, 1, 1, 3, DM_POLYTOPE_SEGMENT, 0, 1, 1075412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 4, 2, 1076412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 0, 1077412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 0, 3, 1078412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 1079412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 3, 1080412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1, 1081412e9a14SMatthew 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, 1082412e9a14SMatthew 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, 1083412e9a14SMatthew 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, 1084412e9a14SMatthew 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, 1085412e9a14SMatthew 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, 1086412e9a14SMatthew 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, 1087412e9a14SMatthew 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, 1088412e9a14SMatthew 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}; 1089412e9a14SMatthew G. Knepley static PetscInt hexO[] = {0, 0, 1090412e9a14SMatthew G. Knepley 0, 0, 1091412e9a14SMatthew G. Knepley 0, 0, 1092412e9a14SMatthew G. Knepley 0, 0, 1093412e9a14SMatthew G. Knepley 0, 0, 1094412e9a14SMatthew G. Knepley 0, 0, 1095412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1096412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1097412e9a14SMatthew G. Knepley -2, -2, 0, 0, 1098412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1099412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1100412e9a14SMatthew G. Knepley -2, -2, 0, 0, 1101412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1102412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1103412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1104412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1105412e9a14SMatthew G. Knepley -2, -2, 0, 0, 1106412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1107412e9a14SMatthew G. Knepley 0, 0, 0, 0, -4, 0, 1108412e9a14SMatthew G. Knepley 0, 0, -1, 0, -4, 0, 1109412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1110412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 1111412e9a14SMatthew G. Knepley -4, 0, 0, 0, -4, 0, 1112412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, 0, 1113412e9a14SMatthew G. Knepley -4, 0, -1, 0, 0, 0, 1114412e9a14SMatthew G. Knepley -4, 0, -1, 0, -4, 0}; 1115412e9a14SMatthew G. Knepley /* Add 3 quads inside every triangular prism, making 4 new prisms. */ 1116412e9a14SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_TRI_PRISM}; 1117412e9a14SMatthew G. Knepley static PetscInt tripS[] = {3, 4, 6, 8}; 1118412e9a14SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 3, 0, 1119412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 1, 4, 0, 1120412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 1, 2, 0, 1121412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 4, 1, 1122412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 0, 1123412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, 1124412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 1125412e9a14SMatthew 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, 1126412e9a14SMatthew 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, 1127412e9a14SMatthew 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, 1128412e9a14SMatthew 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, 1129412e9a14SMatthew 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, 1130412e9a14SMatthew 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, 1131412e9a14SMatthew 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, 1132412e9a14SMatthew 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, 1133412e9a14SMatthew 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, 1134412e9a14SMatthew 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, 1135412e9a14SMatthew 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, 1136412e9a14SMatthew 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, 1137412e9a14SMatthew 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, 1138412e9a14SMatthew 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}; 1139412e9a14SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 1140412e9a14SMatthew G. Knepley 0, 0, 1141412e9a14SMatthew G. Knepley 0, 0, 1142412e9a14SMatthew G. Knepley 0, -2, -2, 1143412e9a14SMatthew G. Knepley -2, 0, -2, 1144412e9a14SMatthew G. Knepley -2, -2, 0, 1145412e9a14SMatthew G. Knepley 0, 0, 0, 1146412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1147412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1148412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1149412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1150412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1151412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1152412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1153412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1154412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 1155412e9a14SMatthew G. Knepley 2, 0, 0, 0, 0, 1156412e9a14SMatthew G. Knepley -3, 0, 0, -1, 0, 1157412e9a14SMatthew G. Knepley -3, 0, 0, 0, -1, 1158412e9a14SMatthew G. Knepley -3, 0, -1, 0, 0, 1159412e9a14SMatthew G. Knepley -3, 0, 0, 0, 0}; 1160412e9a14SMatthew G. Knepley /* Add 3 tensor quads inside every tensor triangular prism, making 4 new prisms. 1161412e9a14SMatthew G. Knepley 2 1162412e9a14SMatthew G. Knepley |\ 1163412e9a14SMatthew G. Knepley | \ 1164412e9a14SMatthew G. Knepley | \ 1165412e9a14SMatthew G. Knepley 0---1 116675d3a19aSMatthew G. Knepley 1167412e9a14SMatthew G. Knepley 2 116875d3a19aSMatthew G. Knepley 1169412e9a14SMatthew G. Knepley 0 1 117075d3a19aSMatthew G. Knepley 1171412e9a14SMatthew G. Knepley 2 1172412e9a14SMatthew G. Knepley |\ 1173412e9a14SMatthew G. Knepley | \ 1174412e9a14SMatthew G. Knepley | \ 1175412e9a14SMatthew G. Knepley 0---1 1176412e9a14SMatthew G. Knepley */ 1177412e9a14SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_TRI_PRISM_TENSOR}; 1178412e9a14SMatthew G. Knepley static PetscInt ttripS[] = {3, 4}; 1179412e9a14SMatthew 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, 1180412e9a14SMatthew 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, 1181412e9a14SMatthew 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, 1182412e9a14SMatthew 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, 1183412e9a14SMatthew 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, 1184412e9a14SMatthew 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, 1185412e9a14SMatthew 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}; 1186412e9a14SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 0, 0, 1187412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1188412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1189412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1190412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1191412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 1192412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0}; 1193412e9a14SMatthew G. Knepley /* Add 1 edge and 4 tensor quads inside every tensor quad prism, making 4 new prisms. */ 1194412e9a14SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1195412e9a14SMatthew G. Knepley static PetscInt tquadpS[] = {1, 4, 4}; 1196412e9a14SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1197412e9a14SMatthew 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, 1198412e9a14SMatthew 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, 1199412e9a14SMatthew 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, 1200412e9a14SMatthew 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, 1201412e9a14SMatthew 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, 1202412e9a14SMatthew 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, 1203412e9a14SMatthew 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, 1204412e9a14SMatthew 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}; 1205412e9a14SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 1206412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1207412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1208412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1209412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1210412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1211412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1212412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1213412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 1214*da9060c4SMatthew G. Knepley PetscErrorCode ierr; 121575d3a19aSMatthew G. Knepley 1216412e9a14SMatthew G. Knepley PetscFunctionBegin; 1217412e9a14SMatthew G. Knepley switch (source) { 1218412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break; 1219412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nt = 2; *target = edgeT; *size = edgeS; *cone = edgeC; *ornt = edgeO; break; 1220412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 1221412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 2; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1222412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nt = 3; *target = quadT; *size = quadS; *cone = quadC; *ornt = quadO; break; 1223412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 2; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 1224412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 3; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1225412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nt = 4; *target = hexT; *size = hexS; *cone = hexC; *ornt = hexO; break; 1226412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1227412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 2; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 1228412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 1229*da9060c4SMatthew G. Knepley /* TODO Fix pyramids: For now, we just ignore them */ 1230*da9060c4SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 1231*da9060c4SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1232*da9060c4SMatthew G. Knepley break; 1233412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1234412e9a14SMatthew G. Knepley } 1235412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1236412e9a14SMatthew G. Knepley } 123775d3a19aSMatthew G. Knepley 123896ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerRefine_ToBox(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1239412e9a14SMatthew G. Knepley { 1240412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1241412e9a14SMatthew G. Knepley /* Change tensor edges to segments */ 1242412e9a14SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_SEGMENT}; 1243412e9a14SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 1244412e9a14SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 1245412e9a14SMatthew G. Knepley static PetscInt tedgeO[] = { 0, 0}; 1246412e9a14SMatthew G. Knepley /* Add 1 vertex, 3 edges inside every triangle, making 3 new quadrilaterals. 1247e5337592SStefano Zampini 2 1248e5337592SStefano Zampini |\ 1249e5337592SStefano Zampini | \ 1250e5337592SStefano Zampini | \ 1251e5337592SStefano Zampini | \ 1252412e9a14SMatthew G. Knepley 0 1 1253412e9a14SMatthew G. Knepley | \ 1254e5337592SStefano Zampini | \ 1255e5337592SStefano Zampini 2 1 1256e5337592SStefano Zampini |\ / \ 1257e5337592SStefano Zampini | 2 1 \ 1258e5337592SStefano Zampini | \ / \ 1259412e9a14SMatthew G. Knepley 1 | 0 1260e5337592SStefano Zampini | 0 \ 1261e5337592SStefano Zampini | | \ 1262412e9a14SMatthew G. Knepley | | \ 1263412e9a14SMatthew G. Knepley 0-0-0-----1-----1 1264e5337592SStefano Zampini */ 1265412e9a14SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 1266412e9a14SMatthew G. Knepley static PetscInt triS[] = {1, 3, 3}; 1267412e9a14SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1268412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1269412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1270412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 1271412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1272412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0}; 1273412e9a14SMatthew G. Knepley static PetscInt triO[] = {0, 0, 1274412e9a14SMatthew G. Knepley 0, 0, 1275412e9a14SMatthew G. Knepley 0, 0, 1276412e9a14SMatthew G. Knepley 0, 0, -2, 0, 1277412e9a14SMatthew G. Knepley 0, 0, 0, -2, 1278412e9a14SMatthew G. Knepley 0, -2, 0, 0}; 1279412e9a14SMatthew G. Knepley /* Add 1 edge inside every tensor quad, making 2 new quadrilaterals 1280412e9a14SMatthew G. Knepley 2----2----1----3----3 12814330a3fcSStefano Zampini | | | 12824330a3fcSStefano Zampini | | | 12834330a3fcSStefano Zampini | | | 1284412e9a14SMatthew G. Knepley 4 A 6 B 5 12854330a3fcSStefano Zampini | | | 1286412e9a14SMatthew G. Knepley | | | 1287412e9a14SMatthew G. Knepley | | | 1288412e9a14SMatthew G. Knepley 0----0----0----1----1 12894330a3fcSStefano Zampini */ 1290412e9a14SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 1291412e9a14SMatthew G. Knepley static PetscInt tquadS[] = {1, 2}; 1292412e9a14SMatthew G. Knepley static PetscInt tquadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1293412e9a14SMatthew G. Knepley /* TODO Fix these */ 1294412e9a14SMatthew 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, 1295412e9a14SMatthew 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}; 1296412e9a14SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 1297412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1298412e9a14SMatthew G. Knepley 0, 0, -2, -2}; 1299412e9a14SMatthew G. Knepley /* Add 6 triangles inside every cell, making 4 new hexs 1300412e9a14SMatthew G. Knepley TODO: Need different SubcellMap(). Need to make a struct with the function pointers in it 1301412e9a14SMatthew 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 1302412e9a14SMatthew 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] 1303412e9a14SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 1304412e9a14SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 1305412e9a14SMatthew G. Knepley We make a new hex in each corner 1306412e9a14SMatthew G. Knepley [v0, (e0, 0), (f0, 0), (e2, 0), (e3, 0), (f2, 0), (c0, 0), (f1, 0)] 1307412e9a14SMatthew G. Knepley [v1, (e4, 0), (f3, 0), (e1, 0), (e0, 0), (f0, 0), (c0, 0), (f1, 0)] 1308412e9a14SMatthew G. Knepley [v2, (e1, 0), (f3, 0), (e5, 0), (e2, 0), (f2, 0), (c0, 0), (f0, 0)] 1309412e9a14SMatthew G. Knepley [v3, (e4, 0), (f1, 0), (e3, 0), (e5, 0), (f2, 0), (c0, 0), (f3, 0)] 1310412e9a14SMatthew G. Knepley We create a new face for each edge 1311412e9a14SMatthew G. Knepley [(e3, 0), (f2, 0), (c0, 0), (f1, 0)] 1312412e9a14SMatthew G. Knepley [(f0, 0), (e0, 0), (f1, 0), (c0, 0)] 1313412e9a14SMatthew G. Knepley [(e2, 0), (f0, 0), (c0, 0), (f2, 0)] 1314412e9a14SMatthew G. Knepley [(f3, 0), (e4, 0), (f1, 0), (c0, 0)] 1315412e9a14SMatthew G. Knepley [(e1, 0), (f3, 0), (c0, 0), (f0, 0)] 1316412e9a14SMatthew G. Knepley [(e5, 0), (f3, 0), (c0, 0), (f2, 0)] 1317412e9a14SMatthew 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. 131875d3a19aSMatthew G. Knepley */ 1319412e9a14SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1320412e9a14SMatthew G. Knepley static PetscInt tetS[] = {1, 4, 6, 4}; 1321412e9a14SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1322412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1323412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1324412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1325412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, 1326412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1327412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1328412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 3, 1329412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1, 1330412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 1331412e9a14SMatthew 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, 1332412e9a14SMatthew 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, 1333412e9a14SMatthew 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, 1334412e9a14SMatthew 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}; 1335412e9a14SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 1336412e9a14SMatthew G. Knepley 0, 0, 1337412e9a14SMatthew G. Knepley 0, 0, 1338412e9a14SMatthew G. Knepley 0, 0, 1339412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1340412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1341412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1342412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1343412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1344412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1345412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 1346412e9a14SMatthew G. Knepley 1, -1, 1, 0, 0, 3, 1347412e9a14SMatthew G. Knepley 0, -4, 1, -1, 0, 3, 1348412e9a14SMatthew G. Knepley 1, -4, 3, -2, -4, 3}; 1349412e9a14SMatthew G. Knepley /* Add 3 quads inside every triangular prism, making 4 new prisms. */ 1350412e9a14SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1351412e9a14SMatthew G. Knepley static PetscInt tripS[] = {1, 5, 9, 6}; 1352412e9a14SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1353412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1354412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1355412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1356412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0, 1357412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 1, 1358412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, 1359412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, 1360412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1361412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 0, 1362412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 0, 1363412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 2, 1364412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 3, 2, 1365412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 4, 2, 1366412e9a14SMatthew 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, 1367412e9a14SMatthew 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, 1368412e9a14SMatthew 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, 1369412e9a14SMatthew 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, 1370412e9a14SMatthew 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, 1371412e9a14SMatthew 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}; 1372412e9a14SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 1373412e9a14SMatthew G. Knepley 0, 0, 1374412e9a14SMatthew G. Knepley 0, 0, 1375412e9a14SMatthew G. Knepley 0, 0, 1376412e9a14SMatthew G. Knepley 0, 0, 1377412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1378412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1379412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1380412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1381412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1382412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1383412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1384412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1385412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1386412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1, 1387412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -4, 1388412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1, 1389412e9a14SMatthew G. Knepley -4, 0, 0, -1, 0, 1, 1390412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, -4, 1391412e9a14SMatthew G. Knepley -4, 0, 0, 0, -1, 1}; 1392412e9a14SMatthew G. Knepley /* Add 3 tensor quads inside every tensor triangular prism, making 4 new tensor triangular prisms. 1393412e9a14SMatthew G. Knepley 2 1394412e9a14SMatthew G. Knepley |\ 1395412e9a14SMatthew G. Knepley | \ 1396412e9a14SMatthew G. Knepley | \ 1397412e9a14SMatthew G. Knepley 0---1 139875d3a19aSMatthew G. Knepley 1399412e9a14SMatthew G. Knepley 2 140075d3a19aSMatthew G. Knepley 1401412e9a14SMatthew G. Knepley 0 1 140275d3a19aSMatthew G. Knepley 1403412e9a14SMatthew G. Knepley 2 1404412e9a14SMatthew G. Knepley |\ 1405412e9a14SMatthew G. Knepley | \ 1406412e9a14SMatthew G. Knepley | \ 1407412e9a14SMatthew G. Knepley 0---1 140875d3a19aSMatthew G. Knepley */ 1409412e9a14SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1410412e9a14SMatthew G. Knepley static PetscInt ttripS[] = {1, 3, 3}; 1411412e9a14SMatthew G. Knepley static PetscInt ttripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1412412e9a14SMatthew 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, 1413412e9a14SMatthew 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, 1414412e9a14SMatthew 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, 1415412e9a14SMatthew 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, 1416412e9a14SMatthew 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, 1417412e9a14SMatthew 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}; 1418412e9a14SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 1419412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1420412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1421412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1422412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1423412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1424412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 1425412e9a14SMatthew G. Knepley /* TODO Add 3 quads inside every tensor triangular prism, making 4 new triangular prisms. 1426412e9a14SMatthew G. Knepley 2 1427412e9a14SMatthew G. Knepley |\ 1428412e9a14SMatthew G. Knepley | \ 1429412e9a14SMatthew G. Knepley | \ 1430412e9a14SMatthew G. Knepley 0---1 143175d3a19aSMatthew G. Knepley 1432412e9a14SMatthew G. Knepley 2 143375d3a19aSMatthew G. Knepley 1434412e9a14SMatthew G. Knepley 0 1 143575d3a19aSMatthew G. Knepley 1436412e9a14SMatthew G. Knepley 2 1437412e9a14SMatthew G. Knepley |\ 1438412e9a14SMatthew G. Knepley | \ 1439412e9a14SMatthew G. Knepley | \ 1440412e9a14SMatthew G. Knepley 0---1 1441a97b51b8SMatthew G. Knepley */ 1442412e9a14SMatthew G. Knepley static DMPolytopeType ctripT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1443412e9a14SMatthew G. Knepley static PetscInt ctripS[] = {1, 3, 3}; 1444412e9a14SMatthew G. Knepley static PetscInt ctripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1445412e9a14SMatthew 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, 1446412e9a14SMatthew 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, 1447412e9a14SMatthew 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, 1448412e9a14SMatthew 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, 1449412e9a14SMatthew 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, 1450412e9a14SMatthew 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}; 1451412e9a14SMatthew G. Knepley static PetscInt ctripO[] = {0, 0, 1452412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1453412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1454412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1455412e9a14SMatthew G. Knepley -4, 0, 0, -1, 0, 1, 1456412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, -4, 1457412e9a14SMatthew G. Knepley -4, 0, 0, 0, -1, 1}; 1458412e9a14SMatthew G. Knepley /* Add 1 edge and 4 quads inside every tensor quad prism, making 4 new hexahedra. */ 1459412e9a14SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1460412e9a14SMatthew G. Knepley static PetscInt tquadpS[] = {1, 4, 4}; 1461412e9a14SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1462412e9a14SMatthew 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, 1463412e9a14SMatthew 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, 1464412e9a14SMatthew 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, 1465412e9a14SMatthew 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, 1466412e9a14SMatthew 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, 1467412e9a14SMatthew 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, 1468412e9a14SMatthew 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, 1469412e9a14SMatthew 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}; 1470412e9a14SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 1471412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1472412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1473412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1474412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1475412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1476412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1477412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1478412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 1479412e9a14SMatthew G. Knepley PetscBool convertTensor = PETSC_TRUE; 1480a97b51b8SMatthew G. Knepley 1481412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 1482412e9a14SMatthew G. Knepley if (convertTensor) { 1483412e9a14SMatthew G. Knepley switch (source) { 1484412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1485412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1486412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1487412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1488412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1489a97b51b8SMatthew G. Knepley break; 1490412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 1491412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 2; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 1492412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 3; *target = ctripT; *size = ctripS; *cone = ctripC; *ornt = ctripO; break; 1493412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 1494412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1495412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1496412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1497*da9060c4SMatthew G. Knepley /* TODO Fix pyramids: For now, we just ignore them */ 1498*da9060c4SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 1499*da9060c4SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1500*da9060c4SMatthew G. Knepley break; 1501412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1502b5da9499SMatthew G. Knepley } 1503b5da9499SMatthew G. Knepley } else { 1504412e9a14SMatthew G. Knepley switch (source) { 1505412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1506412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1507412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1508412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1509412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1510412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1511412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1512412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1513b5da9499SMatthew G. Knepley break; 1514412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1515412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1516412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1517412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 3; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 1518*da9060c4SMatthew G. Knepley /* TODO Fix pyramids: For now, we just ignore them */ 1519*da9060c4SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 1520*da9060c4SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1521*da9060c4SMatthew G. Knepley break; 1522412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 152327fcede3SMatthew G. Knepley } 152475d3a19aSMatthew G. Knepley } 152575d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 152675d3a19aSMatthew G. Knepley } 152775d3a19aSMatthew G. Knepley 1528412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 152975d3a19aSMatthew G. Knepley { 1530412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1531412e9a14SMatthew G. Knepley 1532412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 1533412e9a14SMatthew G. Knepley switch (source) { 1534412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1535412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1536412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1537412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1538412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 1539412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1540412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 1541412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1542412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1543412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1544412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1545412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1546412e9a14SMatthew G. Knepley break; 1547*da9060c4SMatthew G. Knepley /* TODO Fix pyramids: For now, we just ignore them */ 1548*da9060c4SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 1549*da9060c4SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1550*da9060c4SMatthew G. Knepley break; 1551412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1552412e9a14SMatthew G. Knepley } 1553412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1554412e9a14SMatthew G. Knepley } 1555412e9a14SMatthew G. Knepley 1556cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Alfeld2D(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1557cf4091a3SMatthew G. Knepley { 1558cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 1559cf4091a3SMatthew G. Knepley /* Add 1 vertex, 3 edges inside every triangle, making 3 new triangles. 1560cf4091a3SMatthew G. Knepley 2 1561cf4091a3SMatthew G. Knepley |\ 1562cf4091a3SMatthew G. Knepley |\\ 1563cf4091a3SMatthew G. Knepley | |\ 1564cf4091a3SMatthew G. Knepley | \ \ 1565cf4091a3SMatthew G. Knepley | | \ 1566cf4091a3SMatthew G. Knepley | \ \ 1567cf4091a3SMatthew G. Knepley | | \ 1568cf4091a3SMatthew G. Knepley 2 \ \ 1569cf4091a3SMatthew G. Knepley | | 1 1570cf4091a3SMatthew G. Knepley | 2 \ 1571cf4091a3SMatthew G. Knepley | | \ 1572cf4091a3SMatthew G. Knepley | /\ \ 1573cf4091a3SMatthew G. Knepley | 0 1 | 1574cf4091a3SMatthew G. Knepley | / \ | 1575cf4091a3SMatthew G. Knepley |/ \| 1576cf4091a3SMatthew G. Knepley 0---0----1 1577cf4091a3SMatthew G. Knepley */ 1578cf4091a3SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE}; 1579cf4091a3SMatthew G. Knepley static PetscInt triS[] = {1, 3, 3}; 1580cf4091a3SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1581cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 2, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1582cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 2, 2, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1583cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1584cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, 1585cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2}; 1586cf4091a3SMatthew G. Knepley static PetscInt triO[] = {0, 0, 1587cf4091a3SMatthew G. Knepley 0, 0, 1588cf4091a3SMatthew G. Knepley 0, 0, 1589cf4091a3SMatthew G. Knepley 0, 0, -2, 1590cf4091a3SMatthew G. Knepley 0, 0, -2, 1591cf4091a3SMatthew G. Knepley 0, 0, -2}; 1592cf4091a3SMatthew G. Knepley 1593cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 1594cf4091a3SMatthew G. Knepley switch (source) { 1595cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT: 1596cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1597cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1598cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1599cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1600cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 1601cf4091a3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1602cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1603cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 1604cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1605*da9060c4SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 1606cf4091a3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1607cf4091a3SMatthew G. Knepley break; 1608cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1609cf4091a3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1610cf4091a3SMatthew G. Knepley } 1611cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 1612cf4091a3SMatthew G. Knepley } 1613cf4091a3SMatthew G. Knepley 1614cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Alfeld3D(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1615cf4091a3SMatthew G. Knepley { 1616cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 1617cf4091a3SMatthew G. Knepley /* Add 6 triangles inside every cell, making 4 new tets 1618cf4091a3SMatthew 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 1619cf4091a3SMatthew 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] 1620cf4091a3SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 1621cf4091a3SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 1622cf4091a3SMatthew G. Knepley We make a new tet on each face 1623cf4091a3SMatthew G. Knepley [v0, v1, v2, (c0, 0)] 1624cf4091a3SMatthew G. Knepley [v0, v3, v1, (c0, 0)] 1625cf4091a3SMatthew G. Knepley [v0, v2, v3, (c0, 0)] 1626cf4091a3SMatthew G. Knepley [v2, v1, v3, (c0, 0)] 1627cf4091a3SMatthew G. Knepley We create a new face for each edge 1628cf4091a3SMatthew G. Knepley [v0, (c0, 0), v1 ] 1629cf4091a3SMatthew G. Knepley [v0, v2, (c0, 0)] 1630cf4091a3SMatthew G. Knepley [v2, v1, (c0, 0)] 1631cf4091a3SMatthew G. Knepley [v0, (c0, 0), v3 ] 1632cf4091a3SMatthew G. Knepley [v1, v3, (c0, 0)] 1633cf4091a3SMatthew G. Knepley [v3, v2, (c0, 0)] 1634cf4091a3SMatthew G. Knepley */ 1635cf4091a3SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON}; 1636cf4091a3SMatthew G. Knepley static PetscInt tetS[] = {1, 4, 6, 4}; 1637cf4091a3SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 3, 0, 0, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1638cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 3, 0, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1639cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 3, 0, 2, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1640cf4091a3SMatthew G. Knepley DM_POLYTOPE_POINT, 3, 1, 0, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1641cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 2, 0, 0, 0, 1642cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 0, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, 1643cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 0, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 1644cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 2, 1, 0, 0, 1645cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 1, 1646cf4091a3SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 2, 2, 1, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 3, 1647cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 2, 1648cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 4, 1649cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 5, 1650cf4091a3SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 1, 3, 0, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 4}; 1651cf4091a3SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 1652cf4091a3SMatthew G. Knepley 0, 0, 1653cf4091a3SMatthew G. Knepley 0, 0, 1654cf4091a3SMatthew G. Knepley 0, 0, 1655cf4091a3SMatthew G. Knepley 0, -2, -2, 1656cf4091a3SMatthew G. Knepley -2, 0, -2, 1657cf4091a3SMatthew G. Knepley -2, 0, -2, 1658cf4091a3SMatthew G. Knepley 0, -2, -2, 1659cf4091a3SMatthew G. Knepley -2, 0, -2, 1660cf4091a3SMatthew G. Knepley -2, 0, -2, 1661cf4091a3SMatthew G. Knepley 0, 0, 0, 0, 1662cf4091a3SMatthew G. Knepley 0, 0, -3, 0, 1663cf4091a3SMatthew G. Knepley 0, -3, -3, 0, 1664cf4091a3SMatthew G. Knepley 0, -3, -1, -1}; 1665cf4091a3SMatthew G. Knepley 1666cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 1667cf4091a3SMatthew G. Knepley switch (source) { 1668cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT: 1669cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1670cf4091a3SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1671cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1672cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1673cf4091a3SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1674cf4091a3SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1675cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1676cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 1677cf4091a3SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1678*da9060c4SMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 1679cf4091a3SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1680cf4091a3SMatthew G. Knepley break; 1681cf4091a3SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1682cf4091a3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1683cf4091a3SMatthew G. Knepley } 1684cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 1685cf4091a3SMatthew G. Knepley } 1686cf4091a3SMatthew G. Knepley 1687a5801f52SStefano Zampini typedef struct { 1688a5801f52SStefano Zampini PetscInt n; 1689a5801f52SStefano Zampini PetscReal r; 1690a5801f52SStefano Zampini PetscScalar *h; 1691a5801f52SStefano Zampini PetscInt *Nt; 1692a5801f52SStefano Zampini DMPolytopeType **target; 1693a5801f52SStefano Zampini PetscInt **size; 1694a5801f52SStefano Zampini PetscInt **cone; 1695a5801f52SStefano Zampini PetscInt **ornt; 1696a5801f52SStefano Zampini } PlexRefiner_BL; 1697a5801f52SStefano Zampini 1698a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerSetUp_BL(DMPlexCellRefiner cr) 1699a5801f52SStefano Zampini { 1700a5801f52SStefano Zampini PlexRefiner_BL *crbl; 1701a5801f52SStefano Zampini PetscErrorCode ierr; 1702a5801f52SStefano Zampini PetscInt i,n; 1703a5801f52SStefano Zampini PetscReal r; 1704a5801f52SStefano Zampini PetscInt c1,c2,o1,o2; 1705a5801f52SStefano Zampini 1706a5801f52SStefano Zampini PetscFunctionBegin; 1707a5801f52SStefano Zampini ierr = PetscNew(&crbl);CHKERRQ(ierr); 1708a5801f52SStefano Zampini cr->data = crbl; 1709a5801f52SStefano Zampini crbl->n = 1; /* 1 split -> 2 new cells */ 1710a5801f52SStefano Zampini crbl->r = 1; /* linear progression */ 1711a5801f52SStefano Zampini 1712a5801f52SStefano Zampini /* TODO: add setfromoptions to the refiners? */ 1713a5801f52SStefano Zampini ierr = PetscOptionsGetInt(((PetscObject) cr->dm)->options,((PetscObject) cr->dm)->prefix, "-dm_plex_refine_boundarylayer_splits", &crbl->n, NULL);CHKERRQ(ierr); 1714a5801f52SStefano Zampini if (crbl->n < 1) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Number of splits %D must be positive",crbl->n); 1715a5801f52SStefano Zampini ierr = PetscOptionsGetReal(((PetscObject) cr->dm)->options,((PetscObject) cr->dm)->prefix, "-dm_plex_refine_boundarylayer_progression", &crbl->r, NULL);CHKERRQ(ierr); 1716a5801f52SStefano Zampini n = crbl->n; 1717a5801f52SStefano Zampini r = crbl->r; 1718a5801f52SStefano Zampini 1719a5801f52SStefano 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 */ 1720a5801f52SStefano Zampini ierr = PetscMalloc5(4,&crbl->Nt,4,&crbl->target,4,&crbl->size,4,&crbl->cone,4,&crbl->ornt);CHKERRQ(ierr); 1721a5801f52SStefano Zampini 1722a5801f52SStefano Zampini /* progression */ 1723a5801f52SStefano Zampini ierr = PetscMalloc1(n,&crbl->h);CHKERRQ(ierr); 1724a5801f52SStefano Zampini if (r > 1) { 1725a5801f52SStefano Zampini PetscReal d = (r-1.)/(PetscPowRealInt(r,n+1)-1.); 1726a5801f52SStefano Zampini 1727a5801f52SStefano Zampini crbl->h[0] = d; 1728a5801f52SStefano Zampini for (i = 1; i < n; i++) { 1729a5801f52SStefano Zampini d *= r; 1730a5801f52SStefano Zampini crbl->h[i] = crbl->h[i-1] + d; 1731a5801f52SStefano Zampini } 1732a5801f52SStefano Zampini } else { /* linear */ 1733a5801f52SStefano Zampini for (i = 0; i < n; i++) crbl->h[i] = (i + 1.)/(n+1); /* linear */ 1734a5801f52SStefano Zampini } 1735a5801f52SStefano Zampini 1736a5801f52SStefano Zampini /* DM_POLYTOPE_POINT_PRISM_TENSOR produces n points and n+1 tensor segments */ 1737a5801f52SStefano Zampini c1 = 14+6*(n-1); 1738a5801f52SStefano Zampini o1 = 2*(n+1); 1739a5801f52SStefano Zampini crbl->Nt[0] = 2; 1740a5801f52SStefano Zampini 1741a5801f52SStefano 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); 1742a5801f52SStefano Zampini 1743a5801f52SStefano Zampini crbl->target[0][0] = DM_POLYTOPE_POINT; 1744a5801f52SStefano Zampini crbl->target[0][1] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1745a5801f52SStefano Zampini 1746a5801f52SStefano Zampini crbl->size[0][0] = n; 1747a5801f52SStefano Zampini crbl->size[0][1] = n+1; 1748a5801f52SStefano Zampini 1749a5801f52SStefano Zampini /* the tensor segments */ 1750a5801f52SStefano Zampini crbl->cone[0][0] = DM_POLYTOPE_POINT; 1751a5801f52SStefano Zampini crbl->cone[0][1] = 1; 1752a5801f52SStefano Zampini crbl->cone[0][2] = 0; 1753a5801f52SStefano Zampini crbl->cone[0][3] = 0; 1754a5801f52SStefano Zampini crbl->cone[0][4] = DM_POLYTOPE_POINT; 1755a5801f52SStefano Zampini crbl->cone[0][5] = 0; 1756a5801f52SStefano Zampini crbl->cone[0][6] = 0; 1757a5801f52SStefano Zampini for (i = 0; i < n-1; i++) { 1758a5801f52SStefano Zampini crbl->cone[0][7+6*i+0] = DM_POLYTOPE_POINT; 1759a5801f52SStefano Zampini crbl->cone[0][7+6*i+1] = 0; 1760a5801f52SStefano Zampini crbl->cone[0][7+6*i+2] = i; 1761a5801f52SStefano Zampini crbl->cone[0][7+6*i+3] = DM_POLYTOPE_POINT; 1762a5801f52SStefano Zampini crbl->cone[0][7+6*i+4] = 0; 1763a5801f52SStefano Zampini crbl->cone[0][7+6*i+5] = i+1; 1764a5801f52SStefano Zampini } 1765a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+0] = DM_POLYTOPE_POINT; 1766a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+1] = 0; 1767a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+2] = n-1; 1768a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+3] = DM_POLYTOPE_POINT; 1769a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+4] = 1; 1770a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+5] = 1; 1771a5801f52SStefano Zampini crbl->cone[0][7+6*(n-1)+6] = 0; 1772a5801f52SStefano Zampini for (i = 0; i < o1; i++) crbl->ornt[0][i] = 0; 1773a5801f52SStefano Zampini 1774a5801f52SStefano Zampini /* DM_POLYTOPE_SEG_PRISM_TENSOR produces n segments and n+1 tensor quads */ 1775a5801f52SStefano Zampini c1 = 8*n; 1776a5801f52SStefano Zampini c2 = 30+14*(n-1); 1777a5801f52SStefano Zampini o1 = 2*n; 1778a5801f52SStefano Zampini o2 = 4*(n+1); 1779a5801f52SStefano Zampini crbl->Nt[1] = 2; 1780a5801f52SStefano Zampini 1781a5801f52SStefano 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); 1782a5801f52SStefano Zampini 1783a5801f52SStefano Zampini crbl->target[1][0] = DM_POLYTOPE_SEGMENT; 1784a5801f52SStefano Zampini crbl->target[1][1] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1785a5801f52SStefano Zampini 1786a5801f52SStefano Zampini crbl->size[1][0] = n; 1787a5801f52SStefano Zampini crbl->size[1][1] = n+1; 1788a5801f52SStefano Zampini 1789a5801f52SStefano Zampini /* the segments */ 1790a5801f52SStefano Zampini for (i = 0; i < n; i++) { 1791a5801f52SStefano Zampini crbl->cone[1][8*i+0] = DM_POLYTOPE_POINT; 1792a5801f52SStefano Zampini crbl->cone[1][8*i+1] = 1; 1793a5801f52SStefano Zampini crbl->cone[1][8*i+2] = 2; 1794a5801f52SStefano Zampini crbl->cone[1][8*i+3] = i; 1795a5801f52SStefano Zampini crbl->cone[1][8*i+4] = DM_POLYTOPE_POINT; 1796a5801f52SStefano Zampini crbl->cone[1][8*i+5] = 1; 1797a5801f52SStefano Zampini crbl->cone[1][8*i+6] = 3; 1798a5801f52SStefano Zampini crbl->cone[1][8*i+7] = i; 1799a5801f52SStefano Zampini } 1800a5801f52SStefano Zampini 1801a5801f52SStefano Zampini /* the tensor quads */ 1802a5801f52SStefano Zampini crbl->cone[1][c1+ 0] = DM_POLYTOPE_SEGMENT; 1803a5801f52SStefano Zampini crbl->cone[1][c1+ 1] = 1; 1804a5801f52SStefano Zampini crbl->cone[1][c1+ 2] = 0; 1805a5801f52SStefano Zampini crbl->cone[1][c1+ 3] = 0; 1806a5801f52SStefano Zampini crbl->cone[1][c1+ 4] = DM_POLYTOPE_SEGMENT; 1807a5801f52SStefano Zampini crbl->cone[1][c1+ 5] = 0; 1808a5801f52SStefano Zampini crbl->cone[1][c1+ 6] = 0; 1809a5801f52SStefano Zampini crbl->cone[1][c1+ 7] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1810a5801f52SStefano Zampini crbl->cone[1][c1+ 8] = 1; 1811a5801f52SStefano Zampini crbl->cone[1][c1+ 9] = 2; 1812a5801f52SStefano Zampini crbl->cone[1][c1+10] = 0; 1813a5801f52SStefano Zampini crbl->cone[1][c1+11] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1814a5801f52SStefano Zampini crbl->cone[1][c1+12] = 1; 1815a5801f52SStefano Zampini crbl->cone[1][c1+13] = 3; 1816a5801f52SStefano Zampini crbl->cone[1][c1+14] = 0; 1817a5801f52SStefano Zampini for (i = 0; i < n-1; i++) { 1818a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 0] = DM_POLYTOPE_SEGMENT; 1819a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 1] = 0; 1820a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 2] = i; 1821a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 3] = DM_POLYTOPE_SEGMENT; 1822a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 4] = 0; 1823a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 5] = i+1; 1824a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 6] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1825a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 7] = 1; 1826a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 8] = 2; 1827a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+ 9] = i+1; 1828a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+10] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1829a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+11] = 1; 1830a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+12] = 3; 1831a5801f52SStefano Zampini crbl->cone[1][c1+15+14*i+13] = i+1; 1832a5801f52SStefano Zampini } 1833a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 0] = DM_POLYTOPE_SEGMENT; 1834a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 1] = 0; 1835a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 2] = n-1; 1836a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 3] = DM_POLYTOPE_SEGMENT; 1837a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 4] = 1; 1838a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 5] = 1; 1839a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 6] = 0; 1840a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 7] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1841a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 8] = 1; 1842a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+ 9] = 2; 1843a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+10] = n; 1844a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+11] = DM_POLYTOPE_POINT_PRISM_TENSOR; 1845a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+12] = 1; 1846a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+13] = 3; 1847a5801f52SStefano Zampini crbl->cone[1][c1+15+14*(n-1)+14] = n; 1848a5801f52SStefano Zampini for (i = 0; i < o1+o2; i++) crbl->ornt[1][i] = 0; 1849a5801f52SStefano Zampini 1850a5801f52SStefano Zampini /* DM_POLYTOPE_TRI_PRISM_TENSOR produces n triangles and n+1 tensor triangular prisms */ 1851a5801f52SStefano Zampini c1 = 12*n; 1852a5801f52SStefano Zampini c2 = 38+18*(n-1); 1853a5801f52SStefano Zampini o1 = 3*n; 1854a5801f52SStefano Zampini o2 = 5*(n+1); 1855a5801f52SStefano Zampini crbl->Nt[2] = 2; 1856a5801f52SStefano Zampini 1857a5801f52SStefano 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); 1858a5801f52SStefano Zampini 1859a5801f52SStefano Zampini crbl->target[2][0] = DM_POLYTOPE_TRIANGLE; 1860a5801f52SStefano Zampini crbl->target[2][1] = DM_POLYTOPE_TRI_PRISM_TENSOR; 1861a5801f52SStefano Zampini 1862a5801f52SStefano Zampini crbl->size[2][0] = n; 1863a5801f52SStefano Zampini crbl->size[2][1] = n+1; 1864a5801f52SStefano Zampini 1865a5801f52SStefano Zampini /* the triangles */ 1866a5801f52SStefano Zampini for (i = 0; i < n; i++) { 1867a5801f52SStefano Zampini crbl->cone[2][12*i+ 0] = DM_POLYTOPE_SEGMENT; 1868a5801f52SStefano Zampini crbl->cone[2][12*i+ 1] = 1; 1869a5801f52SStefano Zampini crbl->cone[2][12*i+ 2] = 2; 1870a5801f52SStefano Zampini crbl->cone[2][12*i+ 3] = i; 1871a5801f52SStefano Zampini crbl->cone[2][12*i+ 4] = DM_POLYTOPE_SEGMENT; 1872a5801f52SStefano Zampini crbl->cone[2][12*i+ 5] = 1; 1873a5801f52SStefano Zampini crbl->cone[2][12*i+ 6] = 3; 1874a5801f52SStefano Zampini crbl->cone[2][12*i+ 7] = i; 1875a5801f52SStefano Zampini crbl->cone[2][12*i+ 8] = DM_POLYTOPE_SEGMENT; 1876a5801f52SStefano Zampini crbl->cone[2][12*i+ 9] = 1; 1877a5801f52SStefano Zampini crbl->cone[2][12*i+10] = 4; 1878a5801f52SStefano Zampini crbl->cone[2][12*i+11] = i; 1879a5801f52SStefano Zampini } 1880a5801f52SStefano Zampini 1881a5801f52SStefano Zampini /* the triangular prisms */ 1882a5801f52SStefano Zampini crbl->cone[2][c1+ 0] = DM_POLYTOPE_TRIANGLE; 1883a5801f52SStefano Zampini crbl->cone[2][c1+ 1] = 1; 1884a5801f52SStefano Zampini crbl->cone[2][c1+ 2] = 0; 1885a5801f52SStefano Zampini crbl->cone[2][c1+ 3] = 0; 1886a5801f52SStefano Zampini crbl->cone[2][c1+ 4] = DM_POLYTOPE_TRIANGLE; 1887a5801f52SStefano Zampini crbl->cone[2][c1+ 5] = 0; 1888a5801f52SStefano Zampini crbl->cone[2][c1+ 6] = 0; 1889a5801f52SStefano Zampini crbl->cone[2][c1+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1890a5801f52SStefano Zampini crbl->cone[2][c1+ 8] = 1; 1891a5801f52SStefano Zampini crbl->cone[2][c1+ 9] = 2; 1892a5801f52SStefano Zampini crbl->cone[2][c1+10] = 0; 1893a5801f52SStefano Zampini crbl->cone[2][c1+11] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1894a5801f52SStefano Zampini crbl->cone[2][c1+12] = 1; 1895a5801f52SStefano Zampini crbl->cone[2][c1+13] = 3; 1896a5801f52SStefano Zampini crbl->cone[2][c1+14] = 0; 1897a5801f52SStefano Zampini crbl->cone[2][c1+15] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1898a5801f52SStefano Zampini crbl->cone[2][c1+16] = 1; 1899a5801f52SStefano Zampini crbl->cone[2][c1+17] = 4; 1900a5801f52SStefano Zampini crbl->cone[2][c1+18] = 0; 1901a5801f52SStefano Zampini for (i = 0; i < n-1; i++) { 1902a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 0] = DM_POLYTOPE_TRIANGLE; 1903a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 1] = 0; 1904a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 2] = i; 1905a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 3] = DM_POLYTOPE_TRIANGLE; 1906a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 4] = 0; 1907a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 5] = i+1; 1908a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 6] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1909a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 7] = 1; 1910a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 8] = 2; 1911a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+ 9] = i+1; 1912a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+10] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1913a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+11] = 1; 1914a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+12] = 3; 1915a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+13] = i+1; 1916a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+14] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1917a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+15] = 1; 1918a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+16] = 4; 1919a5801f52SStefano Zampini crbl->cone[2][c1+19+18*i+17] = i+1; 1920a5801f52SStefano Zampini } 1921a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 0] = DM_POLYTOPE_TRIANGLE; 1922a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 1] = 0; 1923a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 2] = n-1; 1924a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 3] = DM_POLYTOPE_TRIANGLE; 1925a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 4] = 1; 1926a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 5] = 1; 1927a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 6] = 0; 1928a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1929a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 8] = 1; 1930a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+ 9] = 2; 1931a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+10] = n; 1932a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+11] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1933a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+12] = 1; 1934a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+13] = 3; 1935a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+14] = n; 1936a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+15] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1937a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+16] = 1; 1938a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+17] = 4; 1939a5801f52SStefano Zampini crbl->cone[2][c1+19+18*(n-1)+18] = n; 1940a5801f52SStefano Zampini for (i = 0; i < o1+o2; i++) crbl->ornt[2][i] = 0; 1941a5801f52SStefano Zampini 1942a5801f52SStefano Zampini /* DM_POLYTOPE_QUAD_PRISM_TENSOR produces n quads and n+1 tensor quad prisms */ 1943a5801f52SStefano Zampini c1 = 16*n; 1944a5801f52SStefano Zampini c2 = 46+22*(n-1); 1945a5801f52SStefano Zampini o1 = 4*n; 1946a5801f52SStefano Zampini o2 = 6*(n+1); 1947a5801f52SStefano Zampini crbl->Nt[3] = 2; 1948a5801f52SStefano Zampini 1949a5801f52SStefano 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); 1950a5801f52SStefano Zampini 1951a5801f52SStefano Zampini crbl->target[3][0] = DM_POLYTOPE_QUADRILATERAL; 1952a5801f52SStefano Zampini crbl->target[3][1] = DM_POLYTOPE_QUAD_PRISM_TENSOR; 1953a5801f52SStefano Zampini 1954a5801f52SStefano Zampini crbl->size[3][0] = n; 1955a5801f52SStefano Zampini crbl->size[3][1] = n+1; 1956a5801f52SStefano Zampini 1957a5801f52SStefano Zampini /* the quads */ 1958a5801f52SStefano Zampini for (i = 0; i < n; i++) { 1959a5801f52SStefano Zampini crbl->cone[3][16*i+ 0] = DM_POLYTOPE_SEGMENT; 1960a5801f52SStefano Zampini crbl->cone[3][16*i+ 1] = 1; 1961a5801f52SStefano Zampini crbl->cone[3][16*i+ 2] = 2; 1962a5801f52SStefano Zampini crbl->cone[3][16*i+ 3] = i; 1963a5801f52SStefano Zampini crbl->cone[3][16*i+ 4] = DM_POLYTOPE_SEGMENT; 1964a5801f52SStefano Zampini crbl->cone[3][16*i+ 5] = 1; 1965a5801f52SStefano Zampini crbl->cone[3][16*i+ 6] = 3; 1966a5801f52SStefano Zampini crbl->cone[3][16*i+ 7] = i; 1967a5801f52SStefano Zampini crbl->cone[3][16*i+ 8] = DM_POLYTOPE_SEGMENT; 1968a5801f52SStefano Zampini crbl->cone[3][16*i+ 9] = 1; 1969a5801f52SStefano Zampini crbl->cone[3][16*i+10] = 4; 1970a5801f52SStefano Zampini crbl->cone[3][16*i+11] = i; 1971a5801f52SStefano Zampini crbl->cone[3][16*i+12] = DM_POLYTOPE_SEGMENT; 1972a5801f52SStefano Zampini crbl->cone[3][16*i+13] = 1; 1973a5801f52SStefano Zampini crbl->cone[3][16*i+14] = 5; 1974a5801f52SStefano Zampini crbl->cone[3][16*i+15] = i; 1975a5801f52SStefano Zampini } 1976a5801f52SStefano Zampini 1977a5801f52SStefano Zampini /* the quad prisms */ 1978a5801f52SStefano Zampini crbl->cone[3][c1+ 0] = DM_POLYTOPE_QUADRILATERAL; 1979a5801f52SStefano Zampini crbl->cone[3][c1+ 1] = 1; 1980a5801f52SStefano Zampini crbl->cone[3][c1+ 2] = 0; 1981a5801f52SStefano Zampini crbl->cone[3][c1+ 3] = 0; 1982a5801f52SStefano Zampini crbl->cone[3][c1+ 4] = DM_POLYTOPE_QUADRILATERAL; 1983a5801f52SStefano Zampini crbl->cone[3][c1+ 5] = 0; 1984a5801f52SStefano Zampini crbl->cone[3][c1+ 6] = 0; 1985a5801f52SStefano Zampini crbl->cone[3][c1+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1986a5801f52SStefano Zampini crbl->cone[3][c1+ 8] = 1; 1987a5801f52SStefano Zampini crbl->cone[3][c1+ 9] = 2; 1988a5801f52SStefano Zampini crbl->cone[3][c1+10] = 0; 1989a5801f52SStefano Zampini crbl->cone[3][c1+11] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1990a5801f52SStefano Zampini crbl->cone[3][c1+12] = 1; 1991a5801f52SStefano Zampini crbl->cone[3][c1+13] = 3; 1992a5801f52SStefano Zampini crbl->cone[3][c1+14] = 0; 1993a5801f52SStefano Zampini crbl->cone[3][c1+15] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1994a5801f52SStefano Zampini crbl->cone[3][c1+16] = 1; 1995a5801f52SStefano Zampini crbl->cone[3][c1+17] = 4; 1996a5801f52SStefano Zampini crbl->cone[3][c1+18] = 0; 1997a5801f52SStefano Zampini crbl->cone[3][c1+19] = DM_POLYTOPE_SEG_PRISM_TENSOR; 1998a5801f52SStefano Zampini crbl->cone[3][c1+20] = 1; 1999a5801f52SStefano Zampini crbl->cone[3][c1+21] = 5; 2000a5801f52SStefano Zampini crbl->cone[3][c1+22] = 0; 2001a5801f52SStefano Zampini for (i = 0; i < n-1; i++) { 2002a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 0] = DM_POLYTOPE_QUADRILATERAL; 2003a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 1] = 0; 2004a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 2] = i; 2005a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 3] = DM_POLYTOPE_QUADRILATERAL; 2006a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 4] = 0; 2007a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 5] = i+1; 2008a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 6] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2009a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 7] = 1; 2010a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 8] = 2; 2011a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+ 9] = i+1; 2012a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+10] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2013a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+11] = 1; 2014a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+12] = 3; 2015a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+13] = i+1; 2016a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+14] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2017a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+15] = 1; 2018a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+16] = 4; 2019a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+17] = i+1; 2020a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+18] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2021a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+19] = 1; 2022a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+20] = 5; 2023a5801f52SStefano Zampini crbl->cone[3][c1+23+22*i+21] = i+1; 2024a5801f52SStefano Zampini } 2025a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 0] = DM_POLYTOPE_QUADRILATERAL; 2026a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 1] = 0; 2027a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 2] = n-1; 2028a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 3] = DM_POLYTOPE_QUADRILATERAL; 2029a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 4] = 1; 2030a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 5] = 1; 2031a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 6] = 0; 2032a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2033a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 8] = 1; 2034a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+ 9] = 2; 2035a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+10] = n; 2036a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+11] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2037a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+12] = 1; 2038a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+13] = 3; 2039a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+14] = n; 2040a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+15] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2041a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+16] = 1; 2042a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+17] = 4; 2043a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+18] = n; 2044a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+19] = DM_POLYTOPE_SEG_PRISM_TENSOR; 2045a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+20] = 1; 2046a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+21] = 5; 2047a5801f52SStefano Zampini crbl->cone[3][c1+23+22*(n-1)+22] = n; 2048a5801f52SStefano Zampini for (i = 0; i < o1+o2; i++) crbl->ornt[3][i] = 0; 2049a5801f52SStefano Zampini PetscFunctionReturn(0); 2050a5801f52SStefano Zampini } 2051a5801f52SStefano Zampini 2052a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerDestroy_BL(DMPlexCellRefiner cr) 2053a5801f52SStefano Zampini { 2054a5801f52SStefano Zampini PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data; 2055a5801f52SStefano Zampini PetscErrorCode ierr; 2056a5801f52SStefano Zampini 2057a5801f52SStefano Zampini PetscFunctionBegin; 2058a5801f52SStefano Zampini ierr = PetscFree4(crbl->target[0],crbl->size[0],crbl->cone[0],crbl->ornt[0]);CHKERRQ(ierr); 2059a5801f52SStefano Zampini ierr = PetscFree4(crbl->target[1],crbl->size[1],crbl->cone[1],crbl->ornt[1]);CHKERRQ(ierr); 2060a5801f52SStefano Zampini ierr = PetscFree4(crbl->target[2],crbl->size[2],crbl->cone[2],crbl->ornt[2]);CHKERRQ(ierr); 2061a5801f52SStefano Zampini ierr = PetscFree4(crbl->target[3],crbl->size[3],crbl->cone[3],crbl->ornt[3]);CHKERRQ(ierr); 2062a5801f52SStefano Zampini ierr = PetscFree5(crbl->Nt,crbl->target,crbl->size,crbl->cone,crbl->ornt);CHKERRQ(ierr); 2063a5801f52SStefano Zampini ierr = PetscFree(crbl->h);CHKERRQ(ierr); 2064a5801f52SStefano Zampini ierr = PetscFree(cr->data);CHKERRQ(ierr); 2065a5801f52SStefano Zampini PetscFunctionReturn(0); 2066a5801f52SStefano Zampini } 2067a5801f52SStefano Zampini 2068cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_BL(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 2069cf4091a3SMatthew G. Knepley { 2070a5801f52SStefano Zampini PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data; 2071cf4091a3SMatthew G. Knepley PetscErrorCode ierr; 2072cf4091a3SMatthew G. Knepley 2073cf4091a3SMatthew G. Knepley PetscFunctionBeginHot; 2074cf4091a3SMatthew G. Knepley switch (source) { 2075a5801f52SStefano Zampini case DM_POLYTOPE_POINT_PRISM_TENSOR: 2076a5801f52SStefano Zampini *Nt = crbl->Nt[0]; 2077a5801f52SStefano Zampini *target = crbl->target[0]; 2078a5801f52SStefano Zampini *size = crbl->size[0]; 2079a5801f52SStefano Zampini *cone = crbl->cone[0]; 2080a5801f52SStefano Zampini *ornt = crbl->ornt[0]; 2081cf4091a3SMatthew G. Knepley break; 2082a5801f52SStefano Zampini case DM_POLYTOPE_SEG_PRISM_TENSOR: 2083a5801f52SStefano Zampini *Nt = crbl->Nt[1]; 2084a5801f52SStefano Zampini *target = crbl->target[1]; 2085a5801f52SStefano Zampini *size = crbl->size[1]; 2086a5801f52SStefano Zampini *cone = crbl->cone[1]; 2087a5801f52SStefano Zampini *ornt = crbl->ornt[1]; 2088a5801f52SStefano Zampini break; 2089a5801f52SStefano Zampini case DM_POLYTOPE_TRI_PRISM_TENSOR: 2090a5801f52SStefano Zampini *Nt = crbl->Nt[2]; 2091a5801f52SStefano Zampini *target = crbl->target[2]; 2092a5801f52SStefano Zampini *size = crbl->size[2]; 2093a5801f52SStefano Zampini *cone = crbl->cone[2]; 2094a5801f52SStefano Zampini *ornt = crbl->ornt[2]; 2095a5801f52SStefano Zampini break; 2096a5801f52SStefano Zampini case DM_POLYTOPE_QUAD_PRISM_TENSOR: 2097a5801f52SStefano Zampini *Nt = crbl->Nt[3]; 2098a5801f52SStefano Zampini *target = crbl->target[3]; 2099a5801f52SStefano Zampini *size = crbl->size[3]; 2100a5801f52SStefano Zampini *cone = crbl->cone[3]; 2101a5801f52SStefano Zampini *ornt = crbl->ornt[3]; 2102a5801f52SStefano Zampini break; 2103a5801f52SStefano Zampini default: 2104a5801f52SStefano Zampini ierr = DMPlexCellRefinerRefine_None(cr,source,Nt,target,size,cone,ornt);CHKERRQ(ierr); 2105a5801f52SStefano Zampini } 2106a5801f52SStefano Zampini PetscFunctionReturn(0); 2107a5801f52SStefano Zampini } 2108a5801f52SStefano Zampini 2109a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapSubcells_BL(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 2110a5801f52SStefano Zampini { 2111a5801f52SStefano Zampini /* We shift any input orientation in order to make it non-negative 2112a5801f52SStefano 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) 2113a5801f52SStefano Zampini The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 2114a5801f52SStefano Zampini Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 2115a5801f52SStefano Zampini */ 2116a5801f52SStefano Zampini PetscInt tquad_seg_o[] = { 0, 1, -2, -1, 2117a5801f52SStefano Zampini 0, 1, -2, -1, 2118a5801f52SStefano Zampini -2, -1, 0, 1, 2119a5801f52SStefano Zampini -2, -1, 0, 1}; 2120a5801f52SStefano Zampini PetscInt tquad_tquad_o[] = { 0, 1, -2, -1, 2121a5801f52SStefano Zampini 1, 0, -1, -2, 2122a5801f52SStefano Zampini -2, -1, 0, 1, 2123a5801f52SStefano Zampini -1, -2, 1, 0}; 2124a5801f52SStefano Zampini PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data; 2125a5801f52SStefano Zampini const PetscInt n = crbl->n; 2126a5801f52SStefano Zampini PetscErrorCode ierr; 2127a5801f52SStefano Zampini 2128a5801f52SStefano Zampini PetscFunctionBeginHot; 2129a5801f52SStefano Zampini *rnew = r; 2130a5801f52SStefano Zampini *onew = o; 2131a5801f52SStefano Zampini switch (pct) { 2132a5801f52SStefano Zampini case DM_POLYTOPE_POINT_PRISM_TENSOR: 2133a5801f52SStefano Zampini if (ct == DM_POLYTOPE_POINT_PRISM_TENSOR) { 2134a5801f52SStefano Zampini if (po == 0 || po == -1) {*rnew = r; *onew = o;} 2135a5801f52SStefano Zampini else if (po == 1 || po == -2) {*rnew = n - r; *onew = (o == 0 || o == -1) ? -2 : 0;} 2136a5801f52SStefano Zampini else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid orientation %D for tensor segment", po); 2137a5801f52SStefano Zampini } 2138a5801f52SStefano Zampini break; 2139a5801f52SStefano Zampini case DM_POLYTOPE_SEG_PRISM_TENSOR: 2140a5801f52SStefano Zampini switch (ct) { 2141a5801f52SStefano Zampini case DM_POLYTOPE_SEGMENT: 2142a5801f52SStefano Zampini *onew = tquad_seg_o[(po+2)*4+o+2]; 2143a5801f52SStefano Zampini *rnew = r; 2144a5801f52SStefano Zampini break; 2145a5801f52SStefano Zampini case DM_POLYTOPE_SEG_PRISM_TENSOR: 2146a5801f52SStefano Zampini *onew = tquad_tquad_o[(po+2)*4+o+2]; 2147a5801f52SStefano Zampini *rnew = r; 2148a5801f52SStefano Zampini break; 2149a5801f52SStefano Zampini default: break; 2150a5801f52SStefano Zampini } 2151a5801f52SStefano Zampini break; 2152a5801f52SStefano Zampini default: 2153a5801f52SStefano Zampini ierr = DMPlexCellRefinerMapSubcells_None(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 2154a5801f52SStefano Zampini } 2155a5801f52SStefano Zampini PetscFunctionReturn(0); 2156a5801f52SStefano Zampini } 2157a5801f52SStefano Zampini 2158a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapCoordinates_BL(DMPlexCellRefiner cr, DMPolytopeType pct, DMPolytopeType ct, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[]) 2159a5801f52SStefano Zampini { 2160a5801f52SStefano Zampini PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data; 2161a5801f52SStefano Zampini PetscInt d; 2162a5801f52SStefano Zampini PetscErrorCode ierr; 2163a5801f52SStefano Zampini 2164a5801f52SStefano Zampini PetscFunctionBeginHot; 2165a5801f52SStefano Zampini switch (pct) { 2166a5801f52SStefano Zampini case DM_POLYTOPE_POINT_PRISM_TENSOR: 2167a5801f52SStefano Zampini if (ct != DM_POLYTOPE_POINT) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for refined point type %s",DMPolytopeTypes[ct]); 2168a5801f52SStefano Zampini if (Nv != 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for parent vertices %D",Nv); 2169a5801f52SStefano 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); 2170a5801f52SStefano Zampini for (d = 0; d < dE; d++) out[d] = in[d] + crbl->h[r] * (in[d + dE] - in[d]); 2171a5801f52SStefano Zampini break; 2172a5801f52SStefano Zampini default: 2173a5801f52SStefano Zampini ierr = DMPlexCellRefinerMapCoordinates_Barycenter(cr,pct,ct,r,Nv,dE,in,out);CHKERRQ(ierr); 2174cf4091a3SMatthew G. Knepley } 2175cf4091a3SMatthew G. Knepley PetscFunctionReturn(0); 2176cf4091a3SMatthew G. Knepley } 2177cf4091a3SMatthew G. Knepley 2178412e9a14SMatthew G. Knepley static PetscErrorCode CellRefinerCreateOffset_Internal(DMPlexCellRefiner cr, PetscInt ctOrder[], PetscInt ctStart[], PetscInt **offset) 2179412e9a14SMatthew G. Knepley { 2180412e9a14SMatthew G. Knepley PetscInt c, cN, *off; 218175d3a19aSMatthew G. Knepley PetscErrorCode ierr; 218275d3a19aSMatthew G. Knepley 218375d3a19aSMatthew G. Knepley PetscFunctionBegin; 2184412e9a14SMatthew G. Knepley ierr = PetscCalloc1(DM_NUM_POLYTOPES*DM_NUM_POLYTOPES, &off);CHKERRQ(ierr); 2185412e9a14SMatthew G. Knepley for (c = DM_POLYTOPE_POINT; c < DM_NUM_POLYTOPES; ++c) { 2186412e9a14SMatthew G. Knepley const DMPolytopeType ct = (DMPolytopeType) c; 2187412e9a14SMatthew G. Knepley for (cN = DM_POLYTOPE_POINT; cN < DM_NUM_POLYTOPES; ++cN) { 2188412e9a14SMatthew G. Knepley const DMPolytopeType ctNew = (DMPolytopeType) cN; 2189412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2190412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 2191412e9a14SMatthew G. Knepley PetscInt Nct, n, i; 2192412e9a14SMatthew G. Knepley 2193412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ct) < 0 || DMPolytopeTypeGetDim(ctNew) < 0) {off[ct*DM_NUM_POLYTOPES+ctNew] = -1; break;} 2194412e9a14SMatthew G. Knepley off[ct*DM_NUM_POLYTOPES+ctNew] = 0; 2195412e9a14SMatthew G. Knepley for (i = DM_POLYTOPE_POINT; i < DM_NUM_POLYTOPES; ++i) { 2196412e9a14SMatthew G. Knepley const DMPolytopeType ict = (DMPolytopeType) ctOrder[i]; 2197412e9a14SMatthew G. Knepley const DMPolytopeType ictn = (DMPolytopeType) ctOrder[i+1]; 2198412e9a14SMatthew G. Knepley 2199412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ict, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 2200412e9a14SMatthew G. Knepley if (ict == ct) { 2201412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) break; 2202412e9a14SMatthew G. Knepley if (n == Nct) off[ct*DM_NUM_POLYTOPES+ctNew] = -1; 2203412e9a14SMatthew G. Knepley break; 2204412e9a14SMatthew G. Knepley } 2205412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) off[ct*DM_NUM_POLYTOPES+ctNew] += (ctStart[ictn]-ctStart[ict]) * rsize[n]; 2206412e9a14SMatthew G. Knepley } 2207412e9a14SMatthew G. Knepley } 2208412e9a14SMatthew G. Knepley } 2209412e9a14SMatthew G. Knepley *offset = off; 2210412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2211412e9a14SMatthew G. Knepley } 2212412e9a14SMatthew G. Knepley 2213412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetStarts(DMPlexCellRefiner cr, const PetscInt ctStart[], const PetscInt ctStartNew[]) 2214412e9a14SMatthew G. Knepley { 2215412e9a14SMatthew G. Knepley const PetscInt ctSize = DM_NUM_POLYTOPES+1; 2216412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2217412e9a14SMatthew G. Knepley 2218412e9a14SMatthew G. Knepley PetscFunctionBegin; 2219412e9a14SMatthew G. Knepley if (cr->setupcalled) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_ARG_WRONGSTATE, "Must call this function before DMPlexCellRefinerSetUp()"); 2220412e9a14SMatthew G. Knepley ierr = PetscCalloc2(ctSize, &cr->ctStart, ctSize, &cr->ctStartNew);CHKERRQ(ierr); 2221412e9a14SMatthew G. Knepley ierr = PetscArraycpy(cr->ctStart, ctStart, ctSize);CHKERRQ(ierr); 2222412e9a14SMatthew G. Knepley ierr = PetscArraycpy(cr->ctStartNew, ctStartNew, ctSize);CHKERRQ(ierr); 2223412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2224412e9a14SMatthew G. Knepley } 2225412e9a14SMatthew G. Knepley 2226412e9a14SMatthew G. Knepley /* Construct cell type order since we must loop over cell types in depth order */ 2227412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCreateCellTypeOrder_Internal(DMPolytopeType ctCell, PetscInt *ctOrder[], PetscInt *ctOrderInv[]) 2228412e9a14SMatthew G. Knepley { 2229412e9a14SMatthew G. Knepley PetscInt *ctO, *ctOInv; 2230412e9a14SMatthew G. Knepley PetscInt c, d, off = 0; 2231412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2232412e9a14SMatthew G. Knepley 2233412e9a14SMatthew G. Knepley PetscFunctionBegin; 2234412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctO, DM_NUM_POLYTOPES+1, &ctOInv);CHKERRQ(ierr); 2235412e9a14SMatthew G. Knepley for (d = 3; d >= DMPolytopeTypeGetDim(ctCell); --d) { 2236412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 2237412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue; 2238412e9a14SMatthew G. Knepley ctO[off++] = c; 2239412e9a14SMatthew G. Knepley } 2240412e9a14SMatthew G. Knepley } 2241412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ctCell) != 0) { 2242412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 2243412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != 0) continue; 2244412e9a14SMatthew G. Knepley ctO[off++] = c; 2245412e9a14SMatthew G. Knepley } 2246412e9a14SMatthew G. Knepley } 2247412e9a14SMatthew G. Knepley for (d = DMPolytopeTypeGetDim(ctCell)-1; d > 0; --d) { 2248412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 2249412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue; 2250412e9a14SMatthew G. Knepley ctO[off++] = c; 2251412e9a14SMatthew G. Knepley } 2252412e9a14SMatthew G. Knepley } 2253412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 2254412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) >= 0) continue; 2255412e9a14SMatthew G. Knepley ctO[off++] = c; 2256412e9a14SMatthew G. Knepley } 2257412e9a14SMatthew G. Knepley if (off != DM_NUM_POLYTOPES+1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid offset %D for cell type order", off); 2258412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 2259412e9a14SMatthew G. Knepley ctOInv[ctO[c]] = c; 2260412e9a14SMatthew G. Knepley } 2261412e9a14SMatthew G. Knepley *ctOrder = ctO; 2262412e9a14SMatthew G. Knepley *ctOrderInv = ctOInv; 2263412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2264412e9a14SMatthew G. Knepley } 2265412e9a14SMatthew G. Knepley 2266412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerSetUp(DMPlexCellRefiner cr) 2267412e9a14SMatthew G. Knepley { 2268412e9a14SMatthew G. Knepley DM dm = cr->dm; 2269412e9a14SMatthew G. Knepley DMPolytopeType ctCell; 2270412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p, c; 2271412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2272412e9a14SMatthew G. Knepley 2273412e9a14SMatthew G. Knepley PetscFunctionBegin; 2274412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 2275412e9a14SMatthew G. Knepley if (cr->setupcalled) PetscFunctionReturn(0); 2276a5801f52SStefano Zampini if (cr->ops->setup) { 2277a5801f52SStefano Zampini ierr = (*cr->ops->setup)(cr);CHKERRQ(ierr); 2278a5801f52SStefano Zampini } 2279412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2280a5801f52SStefano Zampini if (pEnd > pStart) { 2281a5801f52SStefano Zampini ierr = DMPlexGetCellType(dm, 0, &ctCell);CHKERRQ(ierr); 2282a5801f52SStefano Zampini } else { 2283412e9a14SMatthew G. Knepley PetscInt dim; 2284a57030b0SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 2285412e9a14SMatthew G. Knepley switch (dim) { 2286412e9a14SMatthew G. Knepley case 0: ctCell = DM_POLYTOPE_POINT;break; 2287412e9a14SMatthew G. Knepley case 1: ctCell = DM_POLYTOPE_SEGMENT;break; 2288412e9a14SMatthew G. Knepley case 2: ctCell = DM_POLYTOPE_TRIANGLE;break; 2289412e9a14SMatthew G. Knepley case 3: ctCell = DM_POLYTOPE_TETRAHEDRON;break; 2290a5801f52SStefano Zampini default: ctCell = DM_POLYTOPE_UNKNOWN; 2291412e9a14SMatthew G. Knepley } 2292412e9a14SMatthew G. Knepley } 2293412e9a14SMatthew G. Knepley ierr = DMPlexCreateCellTypeOrder_Internal(ctCell, &cr->ctOrder, &cr->ctOrderInv);CHKERRQ(ierr); 2294412e9a14SMatthew G. Knepley /* Construct sizes and offsets for each cell type */ 2295412e9a14SMatthew G. Knepley if (!cr->ctStart) { 2296412e9a14SMatthew G. Knepley PetscInt *ctS, *ctSN, *ctC, *ctCN; 2297412e9a14SMatthew G. Knepley 2298412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctS, DM_NUM_POLYTOPES+1, &ctSN);CHKERRQ(ierr); 2299412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctC, DM_NUM_POLYTOPES+1, &ctCN);CHKERRQ(ierr); 2300412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2301412e9a14SMatthew G. Knepley DMPolytopeType ct; 2302412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2303412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 2304412e9a14SMatthew G. Knepley PetscInt Nct, n; 2305412e9a14SMatthew G. Knepley 2306412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2307412e9a14SMatthew G. Knepley if ((PetscInt) ct < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No cell type for point %D", p); 2308412e9a14SMatthew G. Knepley ++ctC[ct]; 2309412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 2310412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) ctCN[rct[n]] += rsize[n]; 2311412e9a14SMatthew G. Knepley } 2312412e9a14SMatthew G. Knepley for (c = 0; c < DM_NUM_POLYTOPES; ++c) { 2313412e9a14SMatthew G. Knepley const PetscInt ct = cr->ctOrder[c]; 2314412e9a14SMatthew G. Knepley const PetscInt ctn = cr->ctOrder[c+1]; 2315412e9a14SMatthew G. Knepley 2316412e9a14SMatthew G. Knepley ctS[ctn] = ctS[ct] + ctC[ct]; 2317412e9a14SMatthew G. Knepley ctSN[ctn] = ctSN[ct] + ctCN[ct]; 2318412e9a14SMatthew G. Knepley } 2319412e9a14SMatthew G. Knepley ierr = PetscFree2(ctC, ctCN);CHKERRQ(ierr); 2320412e9a14SMatthew G. Knepley cr->ctStart = ctS; 2321412e9a14SMatthew G. Knepley cr->ctStartNew = ctSN; 2322412e9a14SMatthew G. Knepley } 2323412e9a14SMatthew G. Knepley ierr = CellRefinerCreateOffset_Internal(cr, cr->ctOrder, cr->ctStart, &cr->offset);CHKERRQ(ierr); 2324412e9a14SMatthew G. Knepley cr->setupcalled = PETSC_TRUE; 2325412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2326412e9a14SMatthew G. Knepley } 2327412e9a14SMatthew G. Knepley 2328412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView_Ascii(DMPlexCellRefiner cr, PetscViewer v) 2329412e9a14SMatthew G. Knepley { 2330412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2331412e9a14SMatthew G. Knepley 2332412e9a14SMatthew G. Knepley PetscFunctionBegin; 2333412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(v, "Cell Refiner: %s\n", DMPlexCellRefinerTypes[cr->type]);CHKERRQ(ierr); 2334412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2335412e9a14SMatthew G. Knepley } 2336412e9a14SMatthew G. Knepley 2337412e9a14SMatthew G. Knepley /* 2338412e9a14SMatthew G. Knepley DMPlexCellRefinerView - Views a DMPlexCellRefiner object 2339412e9a14SMatthew G. Knepley 2340412e9a14SMatthew G. Knepley Collective on cr 2341412e9a14SMatthew G. Knepley 2342412e9a14SMatthew G. Knepley Input Parameters: 2343412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 2344412e9a14SMatthew G. Knepley - viewer - The PetscViewer object 2345412e9a14SMatthew G. Knepley 2346412e9a14SMatthew G. Knepley Level: beginner 2347412e9a14SMatthew G. Knepley 2348412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerCreate() 2349412e9a14SMatthew G. Knepley */ 2350412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView(DMPlexCellRefiner cr, PetscViewer viewer) 2351412e9a14SMatthew G. Knepley { 2352412e9a14SMatthew G. Knepley PetscBool iascii; 2353412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2354412e9a14SMatthew G. Knepley 2355412e9a14SMatthew G. Knepley PetscFunctionBegin; 2356412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 2357412e9a14SMatthew G. Knepley if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2358412e9a14SMatthew G. Knepley if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) cr), &viewer);CHKERRQ(ierr);} 2359412e9a14SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 2360412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2361412e9a14SMatthew G. Knepley if (iascii) {ierr = DMPlexCellRefinerView_Ascii(cr, viewer);CHKERRQ(ierr);} 2362412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2363412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2364412e9a14SMatthew G. Knepley } 2365412e9a14SMatthew G. Knepley 2366412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerDestroy(DMPlexCellRefiner *cr) 2367412e9a14SMatthew G. Knepley { 2368412e9a14SMatthew G. Knepley PetscInt c; 2369412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2370412e9a14SMatthew G. Knepley 2371412e9a14SMatthew G. Knepley PetscFunctionBegin; 2372412e9a14SMatthew G. Knepley if (!*cr) PetscFunctionReturn(0); 2373412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(*cr, DM_CLASSID, 1); 2374a5801f52SStefano Zampini if ((*cr)->ops->destroy) { 2375a5801f52SStefano Zampini ierr = ((*cr)->ops->destroy)(*cr);CHKERRQ(ierr); 2376a5801f52SStefano Zampini } 2377412e9a14SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) (*cr)->dm);CHKERRQ(ierr); 2378412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->ctOrder, (*cr)->ctOrderInv);CHKERRQ(ierr); 2379412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->ctStart, (*cr)->ctStartNew);CHKERRQ(ierr); 2380412e9a14SMatthew G. Knepley ierr = PetscFree((*cr)->offset);CHKERRQ(ierr); 2381412e9a14SMatthew G. Knepley for (c = 0; c < DM_NUM_POLYTOPES; ++c) { 2382412e9a14SMatthew G. Knepley ierr = PetscFEDestroy(&(*cr)->coordFE[c]);CHKERRQ(ierr); 2383412e9a14SMatthew G. Knepley ierr = PetscFEGeomDestroy(&(*cr)->refGeom[c]);CHKERRQ(ierr); 2384412e9a14SMatthew G. Knepley } 2385412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->coordFE, (*cr)->refGeom);CHKERRQ(ierr); 2386412e9a14SMatthew G. Knepley ierr = PetscHeaderDestroy(cr);CHKERRQ(ierr); 2387412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2388412e9a14SMatthew G. Knepley } 2389412e9a14SMatthew G. Knepley 2390412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerCreate(DM dm, DMPlexCellRefiner *cr) 2391412e9a14SMatthew G. Knepley { 2392412e9a14SMatthew G. Knepley DMPlexCellRefiner tmp; 2393412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2394412e9a14SMatthew G. Knepley 2395412e9a14SMatthew G. Knepley PetscFunctionBegin; 2396412e9a14SMatthew G. Knepley PetscValidPointer(cr, 2); 2397412e9a14SMatthew G. Knepley *cr = NULL; 2398412e9a14SMatthew G. Knepley ierr = PetscHeaderCreate(tmp, DM_CLASSID, "DMPlexCellRefiner", "Cell Refiner", "DMPlexCellRefiner", PETSC_COMM_SELF, DMPlexCellRefinerDestroy, DMPlexCellRefinerView);CHKERRQ(ierr); 2399412e9a14SMatthew G. Knepley tmp->setupcalled = PETSC_FALSE; 2400412e9a14SMatthew G. Knepley 2401412e9a14SMatthew G. Knepley tmp->dm = dm; 2402412e9a14SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); 2403412e9a14SMatthew G. Knepley ierr = DMPlexGetCellRefinerType(dm, &tmp->type);CHKERRQ(ierr); 2404412e9a14SMatthew G. Knepley switch (tmp->type) { 240596ca5757SLisandro Dalcin case DM_REFINER_REGULAR: 2406412e9a14SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_Regular; 2407412e9a14SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_Regular; 2408412e9a14SMatthew G. Knepley tmp->ops->getcellvertices = DMPlexCellRefinerGetCellVertices_Regular; 2409412e9a14SMatthew G. Knepley tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_Regular; 2410a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 2411412e9a14SMatthew G. Knepley tmp->ops->getaffinetransforms = DMPlexCellRefinerGetAffineTransforms_Regular; 2412412e9a14SMatthew G. Knepley tmp->ops->getaffinefacetransforms = DMPlexCellRefinerGetAffineFaceTransforms_Regular; 2413412e9a14SMatthew G. Knepley break; 241496ca5757SLisandro Dalcin case DM_REFINER_TO_BOX: 241596ca5757SLisandro Dalcin tmp->ops->refine = DMPlexCellRefinerRefine_ToBox; 241696ca5757SLisandro Dalcin tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToBox; 241796ca5757SLisandro Dalcin tmp->ops->getcellvertices = DMPlexCellRefinerGetCellVertices_ToBox; 241896ca5757SLisandro Dalcin tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_ToBox; 2419a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 2420412e9a14SMatthew G. Knepley break; 242196ca5757SLisandro Dalcin case DM_REFINER_TO_SIMPLEX: 2422412e9a14SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_ToSimplex; 2423412e9a14SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToSimplex; 2424a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 2425412e9a14SMatthew G. Knepley break; 2426cf4091a3SMatthew G. Knepley case DM_REFINER_ALFELD2D: 2427cf4091a3SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_Alfeld2D; 2428cf4091a3SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_None; 2429a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 2430cf4091a3SMatthew G. Knepley break; 2431cf4091a3SMatthew G. Knepley case DM_REFINER_ALFELD3D: 2432cf4091a3SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_Alfeld3D; 2433cf4091a3SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_None; 2434a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_Barycenter; 2435cf4091a3SMatthew G. Knepley break; 2436a5801f52SStefano Zampini case DM_REFINER_BOUNDARYLAYER: 2437a5801f52SStefano Zampini tmp->ops->setup = DMPlexCellRefinerSetUp_BL; 2438a5801f52SStefano Zampini tmp->ops->destroy = DMPlexCellRefinerDestroy_BL; 2439cf4091a3SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_BL; 2440cf4091a3SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_BL; 2441a5801f52SStefano Zampini tmp->ops->mapcoords = DMPlexCellRefinerMapCoordinates_BL; 2442cf4091a3SMatthew G. Knepley break; 2443412e9a14SMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Invalid cell refiner type %s", DMPlexCellRefinerTypes[tmp->type]); 2444412e9a14SMatthew G. Knepley } 2445412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES, &tmp->coordFE, DM_NUM_POLYTOPES, &tmp->refGeom);CHKERRQ(ierr); 2446412e9a14SMatthew G. Knepley *cr = tmp; 2447412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2448412e9a14SMatthew G. Knepley } 2449412e9a14SMatthew G. Knepley 2450412e9a14SMatthew G. Knepley /*@ 2451412e9a14SMatthew G. Knepley DMPlexCellRefinerGetAffineTransforms - Gets the affine map from the reference cell to each subcell 2452412e9a14SMatthew G. Knepley 2453412e9a14SMatthew G. Knepley Input Parameters: 2454412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 2455412e9a14SMatthew G. Knepley - ct - The cell type 2456412e9a14SMatthew G. Knepley 2457412e9a14SMatthew G. Knepley Output Parameters: 2458412e9a14SMatthew G. Knepley + Nc - The number of subcells produced from this cell type 2459412e9a14SMatthew G. Knepley . v0 - The translation of the first vertex for each subcell 2460412e9a14SMatthew G. Knepley . J - The Jacobian for each subcell (map from reference cell to subcell) 2461412e9a14SMatthew G. Knepley - invJ - The inverse Jacobian for each subcell 2462412e9a14SMatthew G. Knepley 2463412e9a14SMatthew G. Knepley Level: developer 2464412e9a14SMatthew G. Knepley 2465412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineFaceTransforms(), Create() 2466412e9a14SMatthew G. Knepley @*/ 2467412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[]) 2468412e9a14SMatthew G. Knepley { 2469412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2470412e9a14SMatthew G. Knepley 2471412e9a14SMatthew G. Knepley PetscFunctionBegin; 2472412e9a14SMatthew G. Knepley if (!cr->ops->getaffinetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine transforms from this refiner"); 2473412e9a14SMatthew G. Knepley ierr = (*cr->ops->getaffinetransforms)(cr, ct, Nc, v0, J, invJ);CHKERRQ(ierr); 2474412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2475412e9a14SMatthew G. Knepley } 2476412e9a14SMatthew G. Knepley 2477412e9a14SMatthew G. Knepley /*@ 2478412e9a14SMatthew G. Knepley DMPlexCellRefinerGetAffineFaceTransforms - Gets the affine map from the reference face cell to each face in the given cell 2479412e9a14SMatthew G. Knepley 2480412e9a14SMatthew G. Knepley Input Parameters: 2481412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 2482412e9a14SMatthew G. Knepley - ct - The cell type 2483412e9a14SMatthew G. Knepley 2484412e9a14SMatthew G. Knepley Output Parameters: 2485412e9a14SMatthew G. Knepley + Nf - The number of faces for this cell type 2486412e9a14SMatthew G. Knepley . v0 - The translation of the first vertex for each face 2487412e9a14SMatthew G. Knepley . J - The Jacobian for each face (map from original cell to subcell) 2488412e9a14SMatthew G. Knepley . invJ - The inverse Jacobian for each face 2489412e9a14SMatthew G. Knepley - detJ - The determinant of the Jacobian for each face 2490412e9a14SMatthew G. Knepley 2491412e9a14SMatthew G. Knepley Note: The Jacobian and inverse Jacboian will be rectangular, and the inverse is really a generalized inverse. 2492412e9a14SMatthew G. Knepley 2493412e9a14SMatthew G. Knepley Level: developer 2494412e9a14SMatthew G. Knepley 2495412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineTransforms(), Create() 2496412e9a14SMatthew G. Knepley @*/ 2497412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[]) 2498412e9a14SMatthew G. Knepley { 2499412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2500412e9a14SMatthew G. Knepley 2501412e9a14SMatthew G. Knepley PetscFunctionBegin; 2502412e9a14SMatthew G. Knepley if (!cr->ops->getaffinefacetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine face transforms from this refiner"); 2503412e9a14SMatthew G. Knepley ierr = (*cr->ops->getaffinefacetransforms)(cr, ct, Nf, v0, J, invJ, detJ);CHKERRQ(ierr); 2504412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2505412e9a14SMatthew G. Knepley } 2506412e9a14SMatthew G. Knepley 2507412e9a14SMatthew G. Knepley /* Numbering regularly refined meshes 2508412e9a14SMatthew G. Knepley 2509412e9a14SMatthew G. Knepley We want the numbering of the new mesh to respect the same depth stratification as the old mesh. We first compute 2510412e9a14SMatthew G. Knepley the number of new points at each depth. This means that offsets for each depth can be computed, making no assumptions 2511412e9a14SMatthew G. Knepley about the order of different cell types. 2512412e9a14SMatthew G. Knepley 2513412e9a14SMatthew G. Knepley However, when we want to order different depth strata, it will be very useful to make assumptions about contiguous 2514412e9a14SMatthew G. Knepley numbering of different cell types, especially if we want to compute new numberings without communication. Therefore, we 2515412e9a14SMatthew G. Knepley will require that cells are numbering contiguously for each cell type, and that those blocks come in the same order as 2516412e9a14SMatthew G. Knepley the cell type enumeration within a given depth stratum. 2517412e9a14SMatthew G. Knepley 2518412e9a14SMatthew 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 2519412e9a14SMatthew G. Knepley start at the new depth offset, run through all prior cell types incrementing by the total addition from that type, then 2520412e9a14SMatthew G. Knepley offset by the old cell type number and replica number for the insertion. 2521412e9a14SMatthew G. Knepley */ 2522412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetNewPoint(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType ctNew, PetscInt p, PetscInt r, PetscInt *pNew) 2523412e9a14SMatthew G. Knepley { 2524412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2525412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 2526412e9a14SMatthew G. Knepley PetscInt Nct, n; 2527412e9a14SMatthew G. Knepley PetscInt off = cr->offset[ct*DM_NUM_POLYTOPES+ctNew]; 2528412e9a14SMatthew G. Knepley PetscInt ctS = cr->ctStart[ct], ctE = cr->ctStart[cr->ctOrder[cr->ctOrderInv[ct]+1]]; 2529412e9a14SMatthew G. Knepley PetscInt ctSN = cr->ctStartNew[ctNew], ctEN = cr->ctStartNew[cr->ctOrder[cr->ctOrderInv[ctNew]+1]]; 2530412e9a14SMatthew G. Knepley PetscInt newp = ctSN; 2531412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2532412e9a14SMatthew G. Knepley 2533412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 2534412e9a14SMatthew 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); 2535412e9a14SMatthew 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]); 2536412e9a14SMatthew G. Knepley 2537412e9a14SMatthew G. Knepley newp += off; 2538412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 2539412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2540412e9a14SMatthew G. Knepley if (rct[n] == ctNew) { 2541412e9a14SMatthew G. Knepley if (rsize[n] && r >= rsize[n]) 2542412e9a14SMatthew 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]); 2543412e9a14SMatthew G. Knepley newp += (p - ctS) * rsize[n] + r; 2544412e9a14SMatthew G. Knepley break; 2545412e9a14SMatthew G. Knepley } 2546412e9a14SMatthew G. Knepley } 2547412e9a14SMatthew G. Knepley 2548412e9a14SMatthew 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); 2549412e9a14SMatthew G. Knepley *pNew = newp; 2550412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2551412e9a14SMatthew G. Knepley } 2552412e9a14SMatthew G. Knepley 2553412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetConeSizes(DMPlexCellRefiner cr, DM rdm) 2554412e9a14SMatthew G. Knepley { 2555412e9a14SMatthew G. Knepley DM dm = cr->dm; 2556412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p, pNew; 2557412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2558412e9a14SMatthew G. Knepley 2559412e9a14SMatthew G. Knepley PetscFunctionBegin; 2560412e9a14SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 2561412e9a14SMatthew G. Knepley ierr = DMCreateLabel(rdm, "celltype");CHKERRQ(ierr); 2562412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2563412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2564412e9a14SMatthew G. Knepley DMPolytopeType ct; 2565412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2566412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2567412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2568412e9a14SMatthew G. Knepley 2569412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2570412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2571412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2572412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2573412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 2574412e9a14SMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, pNew, DMPolytopeTypeGetConeSize(rct[n]));CHKERRQ(ierr); 2575412e9a14SMatthew G. Knepley ierr = DMPlexSetCellType(rdm, pNew, rct[n]);CHKERRQ(ierr); 2576412e9a14SMatthew G. Knepley } 2577412e9a14SMatthew G. Knepley } 2578412e9a14SMatthew G. Knepley } 2579412e9a14SMatthew G. Knepley { 2580412e9a14SMatthew G. Knepley DMLabel ctLabel; 2581412e9a14SMatthew G. Knepley DM_Plex *plex = (DM_Plex *) rdm->data; 2582412e9a14SMatthew G. Knepley 2583412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(rdm, &ctLabel);CHKERRQ(ierr); 2584412e9a14SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) ctLabel, &plex->celltypeState);CHKERRQ(ierr); 2585412e9a14SMatthew G. Knepley } 2586412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2587412e9a14SMatthew G. Knepley } 2588412e9a14SMatthew G. Knepley 2589412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCones(DMPlexCellRefiner cr, DM rdm) 2590412e9a14SMatthew G. Knepley { 2591412e9a14SMatthew G. Knepley DM dm = cr->dm; 2592412e9a14SMatthew G. Knepley DMPolytopeType ct; 2593412e9a14SMatthew G. Knepley PetscInt *coneNew, *orntNew; 2594412e9a14SMatthew G. Knepley PetscInt maxConeSize = 0, pStart, pEnd, p, pNew; 2595412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2596412e9a14SMatthew G. Knepley 2597412e9a14SMatthew G. Knepley PetscFunctionBegin; 2598412e9a14SMatthew G. Knepley for (p = 0; p < DM_NUM_POLYTOPES; ++p) maxConeSize = PetscMax(maxConeSize, DMPolytopeTypeGetConeSize((DMPolytopeType) p)); 2599412e9a14SMatthew G. Knepley ierr = PetscMalloc2(maxConeSize, &coneNew, maxConeSize, &orntNew);CHKERRQ(ierr); 2600412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2601412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2602412e9a14SMatthew G. Knepley const PetscInt *cone, *ornt; 2603412e9a14SMatthew G. Knepley PetscInt coff, ooff, c; 2604412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2605412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2606412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2607412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2608412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 2609412e9a14SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &ornt);CHKERRQ(ierr); 2610412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2611412e9a14SMatthew G. Knepley for (n = 0, coff = 0, ooff = 0; n < Nct; ++n) { 2612412e9a14SMatthew G. Knepley const DMPolytopeType ctNew = rct[n]; 2613412e9a14SMatthew G. Knepley const PetscInt csizeNew = DMPolytopeTypeGetConeSize(ctNew); 2614412e9a14SMatthew G. Knepley 2615412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2616412e9a14SMatthew G. Knepley /* pNew is a subcell produced by subdividing p */ 2617412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 2618412e9a14SMatthew G. Knepley for (c = 0; c < csizeNew; ++c) { 2619412e9a14SMatthew G. Knepley PetscInt ppp = -1; /* Parent Parent point: Parent of point pp */ 2620412e9a14SMatthew G. Knepley PetscInt pp = p; /* Parent point: Point in the original mesh producing new cone point */ 2621412e9a14SMatthew G. Knepley PetscInt po = 0; /* Orientation of parent point pp in parent parent point ppp */ 2622412e9a14SMatthew G. Knepley DMPolytopeType pct = ct; /* Parent type: Cell type for parent of new cone point */ 2623412e9a14SMatthew G. Knepley const PetscInt *pcone = cone; /* Parent cone: Cone of parent point pp */ 2624412e9a14SMatthew G. Knepley PetscInt pr = -1; /* Replica number of pp that produces new cone point */ 2625412e9a14SMatthew G. Knepley const DMPolytopeType ft = (DMPolytopeType) rcone[coff++]; /* Cell type for new cone point of pNew */ 2626412e9a14SMatthew G. Knepley const PetscInt fn = rcone[coff++]; /* Number of cones of p that need to be taken when producing new cone point */ 2627412e9a14SMatthew G. Knepley PetscInt fo = rornt[ooff++]; /* Orientation of new cone point in pNew */ 2628412e9a14SMatthew G. Knepley PetscInt lc; 2629412e9a14SMatthew G. Knepley 2630412e9a14SMatthew G. Knepley /* Get the type (pct) and point number (pp) of the parent point in the original mesh which produces this cone point */ 2631412e9a14SMatthew G. Knepley for (lc = 0; lc < fn; ++lc) { 2632412e9a14SMatthew G. Knepley const PetscInt *ppornt; 2633412e9a14SMatthew G. Knepley PetscInt pcp; 2634412e9a14SMatthew G. Knepley 2635412e9a14SMatthew G. Knepley ierr = DMPolytopeMapCell(pct, po, rcone[coff++], &pcp);CHKERRQ(ierr); 2636412e9a14SMatthew G. Knepley ppp = pp; 2637412e9a14SMatthew G. Knepley pp = pcone[pcp]; 2638412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, pp, &pct);CHKERRQ(ierr); 2639412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, pp, &pcone);CHKERRQ(ierr); 2640412e9a14SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, ppp, &ppornt);CHKERRQ(ierr); 2641cf4091a3SMatthew G. Knepley if (po < 0 && pct != DM_POLYTOPE_POINT) { 2642cf4091a3SMatthew G. Knepley const PetscInt pornt = ppornt[pcp]; 2643cf4091a3SMatthew G. Knepley const PetscInt pcsize = DMPolytopeTypeGetConeSize(pct); 2644cf4091a3SMatthew G. Knepley const PetscInt pcstart = pornt < 0 ? -(pornt+1) : pornt; 2645cf4091a3SMatthew G. Knepley const PetscInt rcstart = (pcstart+pcsize-1)%pcsize; 2646cf4091a3SMatthew G. Knepley po = pornt < 0 ? -(rcstart+1) : rcstart; 2647cf4091a3SMatthew G. Knepley } else { 2648412e9a14SMatthew G. Knepley po = ppornt[pcp]; 2649412e9a14SMatthew G. Knepley } 2650cf4091a3SMatthew G. Knepley } 2651412e9a14SMatthew G. Knepley pr = rcone[coff++]; 2652412e9a14SMatthew G. Knepley /* Orientation po of pp maps (pr, fo) -> (pr', fo') */ 2653412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapSubcells(cr, pct, po, ft, pr, fo, &pr, &fo);CHKERRQ(ierr); 2654412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, pct, ft, pp, pr, &coneNew[c]);CHKERRQ(ierr); 2655412e9a14SMatthew G. Knepley orntNew[c] = fo; 2656412e9a14SMatthew G. Knepley } 2657412e9a14SMatthew G. Knepley ierr = DMPlexSetCone(rdm, pNew, coneNew);CHKERRQ(ierr); 2658412e9a14SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, pNew, orntNew);CHKERRQ(ierr); 2659412e9a14SMatthew G. Knepley } 2660412e9a14SMatthew G. Knepley } 2661412e9a14SMatthew G. Knepley } 2662412e9a14SMatthew G. Knepley ierr = PetscFree2(coneNew, orntNew);CHKERRQ(ierr); 2663412e9a14SMatthew G. Knepley ierr = DMPlexSymmetrize(rdm);CHKERRQ(ierr); 2664412e9a14SMatthew G. Knepley ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 2665412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2666412e9a14SMatthew G. Knepley } 2667412e9a14SMatthew G. Knepley 2668412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCoordinateFE(DMPlexCellRefiner cr, DMPolytopeType ct, PetscFE *fe) 2669412e9a14SMatthew G. Knepley { 2670412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2671412e9a14SMatthew G. Knepley 2672412e9a14SMatthew G. Knepley PetscFunctionBegin; 2673412e9a14SMatthew G. Knepley if (!cr->coordFE[ct]) { 2674412e9a14SMatthew G. Knepley PetscInt dim, cdim; 2675412e9a14SMatthew G. Knepley PetscBool isSimplex; 2676412e9a14SMatthew G. Knepley 2677412e9a14SMatthew G. Knepley switch (ct) { 2678412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: dim = 1; isSimplex = PETSC_TRUE; break; 2679412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: dim = 2; isSimplex = PETSC_TRUE; break; 2680412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: dim = 2; isSimplex = PETSC_FALSE; break; 2681412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: dim = 3; isSimplex = PETSC_TRUE; break; 2682412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: dim = 3; isSimplex = PETSC_FALSE; break; 2683412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No coordinate FE for cell type %s", DMPolytopeTypes[ct]); 2684412e9a14SMatthew G. Knepley } 2685412e9a14SMatthew G. Knepley ierr = DMGetCoordinateDim(cr->dm, &cdim);CHKERRQ(ierr); 2686412e9a14SMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, cdim, isSimplex, 1, PETSC_DETERMINE, &cr->coordFE[ct]);CHKERRQ(ierr); 2687412e9a14SMatthew G. Knepley { 2688412e9a14SMatthew G. Knepley PetscDualSpace dsp; 2689412e9a14SMatthew G. Knepley PetscQuadrature quad; 2690412e9a14SMatthew G. Knepley DM K; 2691412e9a14SMatthew G. Knepley PetscFEGeom *cg; 2692412e9a14SMatthew G. Knepley PetscReal *Xq, *xq, *wq; 2693412e9a14SMatthew G. Knepley PetscInt Nq, q; 2694412e9a14SMatthew G. Knepley 2695412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCellVertices(cr, ct, &Nq, &Xq);CHKERRQ(ierr); 2696412e9a14SMatthew G. Knepley ierr = PetscMalloc1(Nq*cdim, &xq);CHKERRQ(ierr); 2697412e9a14SMatthew G. Knepley for (q = 0; q < Nq*cdim; ++q) xq[q] = Xq[q]; 2698412e9a14SMatthew G. Knepley ierr = PetscMalloc1(Nq, &wq);CHKERRQ(ierr); 2699412e9a14SMatthew G. Knepley for (q = 0; q < Nq; ++q) wq[q] = 1.0; 2700412e9a14SMatthew G. Knepley ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &quad);CHKERRQ(ierr); 2701412e9a14SMatthew G. Knepley ierr = PetscQuadratureSetData(quad, dim, 1, Nq, xq, wq);CHKERRQ(ierr); 2702412e9a14SMatthew G. Knepley ierr = PetscFESetQuadrature(cr->coordFE[ct], quad);CHKERRQ(ierr); 2703412e9a14SMatthew G. Knepley 2704412e9a14SMatthew G. Knepley ierr = PetscFEGetDualSpace(cr->coordFE[ct], &dsp);CHKERRQ(ierr); 2705412e9a14SMatthew G. Knepley ierr = PetscDualSpaceGetDM(dsp, &K);CHKERRQ(ierr); 2706412e9a14SMatthew G. Knepley ierr = PetscFEGeomCreate(quad, 1, cdim, PETSC_FALSE, &cr->refGeom[ct]);CHKERRQ(ierr); 2707412e9a14SMatthew G. Knepley cg = cr->refGeom[ct]; 2708412e9a14SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(K, 0, NULL, cg->v, cg->J, cg->invJ, cg->detJ);CHKERRQ(ierr); 2709412e9a14SMatthew G. Knepley ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr); 2710412e9a14SMatthew G. Knepley } 2711412e9a14SMatthew G. Knepley } 2712412e9a14SMatthew G. Knepley *fe = cr->coordFE[ct]; 2713412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2714412e9a14SMatthew G. Knepley } 2715412e9a14SMatthew G. Knepley 2716412e9a14SMatthew G. Knepley /* 2717412e9a14SMatthew G. Knepley DMPlexCellRefinerMapLocalizedCoordinates - Given a cell of type ct with localized coordinates x, we generate localized coordinates xr for subcell r of type rct. 2718412e9a14SMatthew G. Knepley 2719412e9a14SMatthew G. Knepley Not collective 2720412e9a14SMatthew G. Knepley 2721412e9a14SMatthew G. Knepley Input Parameters: 2722412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner 2723412e9a14SMatthew G. Knepley . ct - The type of the parent cell 2724412e9a14SMatthew G. Knepley . rct - The type of the produced cell 2725412e9a14SMatthew G. Knepley . r - The index of the produced cell 2726412e9a14SMatthew G. Knepley - x - The localized coordinates for the parent cell 2727412e9a14SMatthew G. Knepley 2728412e9a14SMatthew G. Knepley Output Parameter: 2729412e9a14SMatthew G. Knepley . xr - The localized coordinates for the produced cell 2730412e9a14SMatthew G. Knepley 2731412e9a14SMatthew G. Knepley Level: developer 2732412e9a14SMatthew G. Knepley 2733412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerSetCoordinates() 2734412e9a14SMatthew G. Knepley */ 2735412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapLocalizedCoordinates(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, const PetscScalar x[], PetscScalar xr[]) 2736412e9a14SMatthew G. Knepley { 2737412e9a14SMatthew G. Knepley PetscFE fe = NULL; 2738412e9a14SMatthew G. Knepley PetscInt cdim, Nv, v, *subcellV; 2739412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2740412e9a14SMatthew G. Knepley 2741412e9a14SMatthew G. Knepley PetscFunctionBegin; 2742412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCoordinateFE(cr, ct, &fe);CHKERRQ(ierr); 2743412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetSubcellVertices(cr, ct, rct, r, &Nv, &subcellV);CHKERRQ(ierr); 2744412e9a14SMatthew G. Knepley ierr = PetscFEGetNumComponents(fe, &cdim);CHKERRQ(ierr); 2745412e9a14SMatthew G. Knepley for (v = 0; v < Nv; ++v) { 2746412e9a14SMatthew G. Knepley ierr = PetscFEInterpolate_Static(fe, x, cr->refGeom[ct], subcellV[v], &xr[v*cdim]);CHKERRQ(ierr); 2747412e9a14SMatthew G. Knepley } 2748412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 2749412e9a14SMatthew G. Knepley } 2750412e9a14SMatthew G. Knepley 2751412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCoordinates(DMPlexCellRefiner cr, DM rdm) 2752412e9a14SMatthew G. Knepley { 2753412e9a14SMatthew G. Knepley DM dm = cr->dm, cdm; 2754412e9a14SMatthew G. Knepley PetscSection coordSection, coordSectionNew; 2755412e9a14SMatthew G. Knepley Vec coordsLocal, coordsLocalNew; 2756412e9a14SMatthew G. Knepley const PetscScalar *coords; 2757412e9a14SMatthew G. Knepley PetscScalar *coordsNew; 2758412e9a14SMatthew G. Knepley const DMBoundaryType *bd; 2759412e9a14SMatthew G. Knepley const PetscReal *maxCell, *L; 2760412e9a14SMatthew G. Knepley PetscBool isperiodic, localizeVertices = PETSC_FALSE, localizeCells = PETSC_FALSE; 2761412e9a14SMatthew G. Knepley PetscInt dE, d, cStart, cEnd, c, vStartNew, vEndNew, v, pStart, pEnd, p, ocStart, ocEnd; 2762412e9a14SMatthew G. Knepley PetscErrorCode ierr; 2763412e9a14SMatthew G. Knepley 2764412e9a14SMatthew G. Knepley PetscFunctionBegin; 2765412e9a14SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 276690b157c4SStefano Zampini ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 276790b157c4SStefano Zampini /* Determine if we need to localize coordinates when generating them */ 2768b9ccc978SStefano Zampini if (isperiodic) { 2769412e9a14SMatthew G. Knepley localizeVertices = PETSC_TRUE; 2770412e9a14SMatthew G. Knepley if (!maxCell) { 2771412e9a14SMatthew G. Knepley PetscBool localized; 2772412e9a14SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 2773412e9a14SMatthew G. Knepley if (!localized) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Cannot refine a periodic mesh if coordinates have not been localized"); 2774412e9a14SMatthew G. Knepley localizeCells = PETSC_TRUE; 2775b9ccc978SStefano Zampini } 2776b9ccc978SStefano Zampini } 2777b9ccc978SStefano Zampini 2778b9ccc978SStefano Zampini ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 2779412e9a14SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &dE);CHKERRQ(ierr); 2780412e9a14SMatthew G. Knepley if (maxCell) { 2781412e9a14SMatthew G. Knepley PetscReal maxCellNew[3]; 2782412e9a14SMatthew G. Knepley 2783412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) maxCellNew[d] = maxCell[d]/2.0; 2784412e9a14SMatthew G. Knepley ierr = DMSetPeriodicity(rdm, isperiodic, maxCellNew, L, bd);CHKERRQ(ierr); 2785412e9a14SMatthew G. Knepley } else { 2786412e9a14SMatthew G. Knepley ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 2787412e9a14SMatthew G. Knepley } 2788b9ccc978SStefano Zampini ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &coordSectionNew);CHKERRQ(ierr); 2789b9ccc978SStefano Zampini ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 2790412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dE);CHKERRQ(ierr); 2791412e9a14SMatthew G. Knepley ierr = DMPlexGetDepthStratum(rdm, 0, &vStartNew, &vEndNew);CHKERRQ(ierr); 2792412e9a14SMatthew G. Knepley if (localizeCells) {ierr = PetscSectionSetChart(coordSectionNew, 0, vEndNew);CHKERRQ(ierr);} 2793412e9a14SMatthew G. Knepley else {ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vEndNew);CHKERRQ(ierr);} 2794b9ccc978SStefano Zampini 2795412e9a14SMatthew G. Knepley /* Localization should be inherited */ 2796412e9a14SMatthew G. Knepley /* Stefano calculates parent cells for each new cell for localization */ 2797412e9a14SMatthew G. Knepley /* Localized cells need coordinates of closure */ 2798412e9a14SMatthew G. Knepley for (v = vStartNew; v < vEndNew; ++v) { 2799412e9a14SMatthew G. Knepley ierr = PetscSectionSetDof(coordSectionNew, v, dE);CHKERRQ(ierr); 2800412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dE);CHKERRQ(ierr); 2801412e9a14SMatthew G. Knepley } 2802412e9a14SMatthew G. Knepley if (localizeCells) { 2803412e9a14SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 2804412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 2805412e9a14SMatthew G. Knepley PetscInt dof; 280690b157c4SStefano Zampini 2807412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr); 2808412e9a14SMatthew G. Knepley if (dof) { 2809412e9a14SMatthew G. Knepley DMPolytopeType ct; 2810412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2811412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2812412e9a14SMatthew G. Knepley PetscInt dim, cNew, Nct, n, r; 281390b157c4SStefano Zampini 2814412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 2815412e9a14SMatthew G. Knepley dim = DMPolytopeTypeGetDim(ct); 2816412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2817412e9a14SMatthew G. Knepley /* This allows for different cell types */ 2818412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2819412e9a14SMatthew G. Knepley if (dim != DMPolytopeTypeGetDim(rct[n])) continue; 2820412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2821412e9a14SMatthew G. Knepley PetscInt *closure = NULL; 2822412e9a14SMatthew G. Knepley PetscInt clSize, cl, Nv = 0; 282390b157c4SStefano Zampini 2824412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], c, r, &cNew);CHKERRQ(ierr); 2825412e9a14SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 2826412e9a14SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) {if ((closure[cl] >= vStartNew) && (closure[cl] < vEndNew)) ++Nv;} 2827412e9a14SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 2828412e9a14SMatthew G. Knepley ierr = PetscSectionSetDof(coordSectionNew, cNew, Nv * dE);CHKERRQ(ierr); 2829412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSectionNew, cNew, 0, Nv * dE);CHKERRQ(ierr); 28309fc2a3f3SStefano Zampini } 283190b157c4SStefano Zampini } 283290b157c4SStefano Zampini } 2833412e9a14SMatthew G. Knepley } 283475d3a19aSMatthew G. Knepley } 283575d3a19aSMatthew G. Knepley ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 2836412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-coarse_dm_view");CHKERRQ(ierr); 283746e270d4SMatthew G. Knepley ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 2838412e9a14SMatthew G. Knepley { 2839412e9a14SMatthew G. Knepley VecType vtype; 2840412e9a14SMatthew G. Knepley PetscInt coordSizeNew, bs; 2841412e9a14SMatthew G. Knepley const char *name; 2842412e9a14SMatthew G. Knepley 2843412e9a14SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); 2844412e9a14SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordsLocalNew);CHKERRQ(ierr); 284575d3a19aSMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 2846412e9a14SMatthew G. Knepley ierr = VecSetSizes(coordsLocalNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 2847412e9a14SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) coordsLocal, &name);CHKERRQ(ierr); 2848412e9a14SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordsLocalNew, name);CHKERRQ(ierr); 2849412e9a14SMatthew G. Knepley ierr = VecGetBlockSize(coordsLocal, &bs);CHKERRQ(ierr); 2850412e9a14SMatthew G. Knepley ierr = VecSetBlockSize(coordsLocalNew, bs);CHKERRQ(ierr); 2851412e9a14SMatthew G. Knepley ierr = VecGetType(coordsLocal, &vtype);CHKERRQ(ierr); 2852412e9a14SMatthew G. Knepley ierr = VecSetType(coordsLocalNew, vtype);CHKERRQ(ierr); 2853b5da9499SMatthew G. Knepley } 2854412e9a14SMatthew G. Knepley ierr = VecGetArrayRead(coordsLocal, &coords);CHKERRQ(ierr); 2855412e9a14SMatthew G. Knepley ierr = VecGetArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr); 2856412e9a14SMatthew G. Knepley ierr = PetscSectionGetChart(coordSection, &ocStart, &ocEnd);CHKERRQ(ierr); 2857412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2858412e9a14SMatthew G. Knepley /* First set coordinates for vertices*/ 2859412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2860412e9a14SMatthew G. Knepley DMPolytopeType ct; 2861412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2862412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2863412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2864412e9a14SMatthew G. Knepley PetscBool hasVertex = PETSC_FALSE, isLocalized = PETSC_FALSE; 286590b157c4SStefano Zampini 2866412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2867412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2868412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2869412e9a14SMatthew G. Knepley if (rct[n] == DM_POLYTOPE_POINT) {hasVertex = PETSC_TRUE; break;} 2870412e9a14SMatthew G. Knepley } 2871412e9a14SMatthew G. Knepley if (localizeVertices && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) { 2872412e9a14SMatthew G. Knepley PetscInt dof; 2873412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, p, &dof);CHKERRQ(ierr); 2874412e9a14SMatthew G. Knepley if (dof) isLocalized = PETSC_TRUE; 2875412e9a14SMatthew G. Knepley } 2876412e9a14SMatthew G. Knepley if (hasVertex) { 2877a5801f52SStefano Zampini const PetscScalar *icoords = NULL; 2878412e9a14SMatthew G. Knepley PetscScalar *pcoords = NULL; 2879412e9a14SMatthew G. Knepley PetscInt Nc, Nv, v, d; 288090b157c4SStefano Zampini 2881412e9a14SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr); 2882a5801f52SStefano Zampini 2883a5801f52SStefano Zampini icoords = pcoords; 2884a5801f52SStefano Zampini Nv = Nc/dE; 2885a5801f52SStefano Zampini if (ct != DM_POLYTOPE_POINT) { 2886412e9a14SMatthew G. Knepley if (localizeVertices) { 2887412e9a14SMatthew G. Knepley PetscScalar anchor[3]; 288890b157c4SStefano Zampini 2889412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) anchor[d] = pcoords[d]; 2890412e9a14SMatthew G. Knepley if (!isLocalized) { 2891a5801f52SStefano Zampini for (v = 0; v < Nv; ++v) {ierr = DMLocalizeCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], &pcoords[v*dE]);CHKERRQ(ierr);} 2892412e9a14SMatthew G. Knepley } else { 2893412e9a14SMatthew G. Knepley Nv = Nc/(2*dE); 2894a5801f52SStefano Zampini icoords = pcoords + Nv*dE; 2895a5801f52SStefano Zampini for (v = Nv; v < Nv*2; ++v) {ierr = DMLocalizeCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], &pcoords[v*dE]);CHKERRQ(ierr);} 289690b157c4SStefano Zampini } 2897b5da9499SMatthew G. Knepley } 289890b157c4SStefano Zampini } 2899412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2900412e9a14SMatthew G. Knepley if (rct[n] != DM_POLYTOPE_POINT) continue; 2901412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2902a5801f52SStefano Zampini PetscScalar vcoords[3]; 2903412e9a14SMatthew G. Knepley PetscInt vNew, off; 2904b5da9499SMatthew G. Knepley 2905412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &vNew);CHKERRQ(ierr); 2906412e9a14SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, vNew, &off);CHKERRQ(ierr); 2907a5801f52SStefano Zampini ierr = DMPlexCellRefinerMapCoordinates(cr, ct, rct[n], r, Nv, dE, icoords, vcoords);CHKERRQ(ierr); 2908eac51794SMatthew G. Knepley ierr = DMPlexSnapToGeomModel(dm, p, vcoords, &coordsNew[off]);CHKERRQ(ierr); 2909b5da9499SMatthew G. Knepley } 29109fc2a3f3SStefano Zampini } 2911a5801f52SStefano Zampini ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr); 2912412e9a14SMatthew G. Knepley } 2913412e9a14SMatthew G. Knepley } 2914412e9a14SMatthew G. Knepley /* Then set coordinates for cells by localizing */ 2915412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2916412e9a14SMatthew G. Knepley DMPolytopeType ct; 2917412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2918412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2919412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2920412e9a14SMatthew G. Knepley PetscBool isLocalized = PETSC_FALSE; 292190b157c4SStefano Zampini 2922412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2923412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2924412e9a14SMatthew G. Knepley if (localizeCells && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) { 2925412e9a14SMatthew G. Knepley PetscInt dof; 2926412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, p, &dof);CHKERRQ(ierr); 2927412e9a14SMatthew G. Knepley if (dof) isLocalized = PETSC_TRUE; 2928b5da9499SMatthew G. Knepley } 2929412e9a14SMatthew G. Knepley if (isLocalized) { 2930412e9a14SMatthew G. Knepley const PetscScalar *pcoords; 29319fc2a3f3SStefano Zampini 2932412e9a14SMatthew G. Knepley ierr = DMPlexPointLocalRead(cdm, p, coords, &pcoords);CHKERRQ(ierr); 2933412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2934412e9a14SMatthew G. Knepley const PetscInt Nr = rsize[n]; 293590b157c4SStefano Zampini 2936412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ct) != DMPolytopeTypeGetDim(rct[n])) continue; 2937412e9a14SMatthew G. Knepley for (r = 0; r < Nr; ++r) { 2938412e9a14SMatthew G. Knepley PetscInt pNew, offNew; 293990b157c4SStefano Zampini 2940412e9a14SMatthew G. Knepley /* It looks like Stefano and Lisandro are allowing localized coordinates without defining the periodic boundary, which means that 2941412e9a14SMatthew G. Knepley DMLocalizeCoordinate_Internal() will not work. Localized coordinates will have to have obtained by the affine map of the larger 2942412e9a14SMatthew G. Knepley cell to the ones it produces. */ 2943412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 2944412e9a14SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, pNew, &offNew);CHKERRQ(ierr); 2945412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapLocalizedCoordinates(cr, ct, rct[n], r, pcoords, &coordsNew[offNew]);CHKERRQ(ierr); 294690b157c4SStefano Zampini } 294790b157c4SStefano Zampini } 294890b157c4SStefano Zampini } 294990b157c4SStefano Zampini } 2950412e9a14SMatthew G. Knepley ierr = VecRestoreArrayRead(coordsLocal, &coords);CHKERRQ(ierr); 2951412e9a14SMatthew G. Knepley ierr = VecRestoreArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr); 2952412e9a14SMatthew G. Knepley ierr = DMSetCoordinatesLocal(rdm, coordsLocalNew);CHKERRQ(ierr); 2953412e9a14SMatthew G. Knepley /* TODO Stefano has a final reduction if some hybrid coordinates cannot be found. (needcoords) Should not be needed. */ 2954412e9a14SMatthew G. Knepley ierr = VecDestroy(&coordsLocalNew);CHKERRQ(ierr); 295575d3a19aSMatthew G. Knepley ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 2956412e9a14SMatthew G. Knepley if (!localizeCells) {ierr = DMLocalizeCoordinates(rdm);CHKERRQ(ierr);} 295775d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 295875d3a19aSMatthew G. Knepley } 295975d3a19aSMatthew G. Knepley 2960963fc26aSMatthew G. Knepley /*@ 2961963fc26aSMatthew G. Knepley DMPlexCreateProcessSF - Create an SF which just has process connectivity 2962963fc26aSMatthew G. Knepley 2963d083f849SBarry Smith Collective on dm 2964963fc26aSMatthew G. Knepley 2965963fc26aSMatthew G. Knepley Input Parameters: 2966963fc26aSMatthew G. Knepley + dm - The DM 2967963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity 2968963fc26aSMatthew G. Knepley 2969963fc26aSMatthew G. Knepley Output Parameters: 2970963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL 2971963fc26aSMatthew G. Knepley - sfProcess - An SF encoding the process connectivity, or NULL 2972963fc26aSMatthew G. Knepley 2973963fc26aSMatthew G. Knepley Level: developer 2974963fc26aSMatthew G. Knepley 2975963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 2976963fc26aSMatthew G. Knepley @*/ 2977963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 297875d3a19aSMatthew G. Knepley { 297975d3a19aSMatthew G. Knepley PetscInt numRoots, numLeaves, l; 298075d3a19aSMatthew G. Knepley const PetscInt *localPoints; 298175d3a19aSMatthew G. Knepley const PetscSFNode *remotePoints; 298275d3a19aSMatthew G. Knepley PetscInt *localPointsNew; 298375d3a19aSMatthew G. Knepley PetscSFNode *remotePointsNew; 298475d3a19aSMatthew G. Knepley PetscInt *ranks, *ranksNew; 29859852e123SBarry Smith PetscMPIInt size; 298675d3a19aSMatthew G. Knepley PetscErrorCode ierr; 298775d3a19aSMatthew G. Knepley 298875d3a19aSMatthew G. Knepley PetscFunctionBegin; 2989963fc26aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2990963fc26aSMatthew G. Knepley PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 2991963fc26aSMatthew G. Knepley if (processRanks) {PetscValidPointer(processRanks, 3);} 2992963fc26aSMatthew G. Knepley if (sfProcess) {PetscValidPointer(sfProcess, 4);} 29939852e123SBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 299475d3a19aSMatthew G. Knepley ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 2995785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 299675d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 299775d3a19aSMatthew G. Knepley ranks[l] = remotePoints[l].rank; 299875d3a19aSMatthew G. Knepley } 299975d3a19aSMatthew G. Knepley ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 3000785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 3001785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 3002785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 300375d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 300475d3a19aSMatthew G. Knepley ranksNew[l] = ranks[l]; 300575d3a19aSMatthew G. Knepley localPointsNew[l] = l; 300675d3a19aSMatthew G. Knepley remotePointsNew[l].index = 0; 300775d3a19aSMatthew G. Knepley remotePointsNew[l].rank = ranksNew[l]; 300875d3a19aSMatthew G. Knepley } 300975d3a19aSMatthew G. Knepley ierr = PetscFree(ranks);CHKERRQ(ierr); 3010963fc26aSMatthew G. Knepley if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 3011963fc26aSMatthew G. Knepley else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 3012963fc26aSMatthew G. Knepley if (sfProcess) { 301375d3a19aSMatthew G. Knepley ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 3014963fc26aSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 301575d3a19aSMatthew G. Knepley ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 30169852e123SBarry Smith ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 3017963fc26aSMatthew G. Knepley } 301875d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 301975d3a19aSMatthew G. Knepley } 302075d3a19aSMatthew G. Knepley 3021412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateSF(DMPlexCellRefiner cr, DM rdm) 302275d3a19aSMatthew G. Knepley { 3023412e9a14SMatthew G. Knepley DM dm = cr->dm; 3024412e9a14SMatthew G. Knepley DMPlexCellRefiner *crRem; 302575d3a19aSMatthew G. Knepley PetscSF sf, sfNew, sfProcess; 302675d3a19aSMatthew G. Knepley IS processRanks; 3027412e9a14SMatthew G. Knepley MPI_Datatype ctType; 302875d3a19aSMatthew G. Knepley PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 302975d3a19aSMatthew G. Knepley const PetscInt *localPoints, *neighbors; 303075d3a19aSMatthew G. Knepley const PetscSFNode *remotePoints; 303175d3a19aSMatthew G. Knepley PetscInt *localPointsNew; 303275d3a19aSMatthew G. Knepley PetscSFNode *remotePointsNew; 3033412e9a14SMatthew G. Knepley PetscInt *ctStartRem, *ctStartNewRem; 3034412e9a14SMatthew G. Knepley PetscInt ctSize = DM_NUM_POLYTOPES+1, numNeighbors, n, pStartNew, pEndNew, pNew, pNewRem; 303575d3a19aSMatthew G. Knepley PetscErrorCode ierr; 303675d3a19aSMatthew G. Knepley 303775d3a19aSMatthew G. Knepley PetscFunctionBegin; 303875d3a19aSMatthew G. Knepley ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 303975d3a19aSMatthew G. Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 304075d3a19aSMatthew G. Knepley ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 3041add09238SMatthew G. Knepley /* Calculate size of new SF */ 304275d3a19aSMatthew G. Knepley ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 304375d3a19aSMatthew G. Knepley if (numRoots < 0) PetscFunctionReturn(0); 304475d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 304575d3a19aSMatthew G. Knepley const PetscInt p = localPoints[l]; 3046412e9a14SMatthew G. Knepley DMPolytopeType ct; 3047412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3048412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 3049412e9a14SMatthew G. Knepley PetscInt Nct, n; 305075d3a19aSMatthew G. Knepley 3051412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 3052412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 3053412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) numLeavesNew += rsize[n]; 30540314a74cSLawrence Mitchell } 3055412e9a14SMatthew G. Knepley /* Communicate ctStart and cStartNew for each remote rank */ 305675d3a19aSMatthew G. Knepley ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 305775d3a19aSMatthew G. Knepley ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 3058412e9a14SMatthew G. Knepley ierr = PetscMalloc2(ctSize*numNeighbors, &ctStartRem, ctSize*numNeighbors, &ctStartNewRem);CHKERRQ(ierr); 3059412e9a14SMatthew G. Knepley ierr = MPI_Type_contiguous(ctSize, MPIU_INT, &ctType);CHKERRQ(ierr); 3060412e9a14SMatthew G. Knepley ierr = MPI_Type_commit(&ctType);CHKERRQ(ierr); 3061412e9a14SMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr); 3062412e9a14SMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr); 3063412e9a14SMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr); 3064412e9a14SMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr); 3065412e9a14SMatthew G. Knepley ierr = MPI_Type_free(&ctType);CHKERRQ(ierr); 306675d3a19aSMatthew G. Knepley ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 3067412e9a14SMatthew G. Knepley ierr = PetscMalloc1(numNeighbors, &crRem);CHKERRQ(ierr); 3068412e9a14SMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) { 3069412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &crRem[n]);CHKERRQ(ierr); 3070412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetStarts(crRem[n], &ctStartRem[n*ctSize], &ctStartNewRem[n*ctSize]); 3071412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(crRem[n]);CHKERRQ(ierr); 3072412e9a14SMatthew G. Knepley } 3073412e9a14SMatthew G. Knepley ierr = PetscFree2(ctStartRem, ctStartNewRem);CHKERRQ(ierr); 307475d3a19aSMatthew G. Knepley /* Calculate new point SF */ 3075785e854fSJed Brown ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 3076785e854fSJed Brown ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 307775d3a19aSMatthew G. Knepley ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 307875d3a19aSMatthew G. Knepley for (l = 0, m = 0; l < numLeaves; ++l) { 307975d3a19aSMatthew G. Knepley PetscInt p = localPoints[l]; 3080412e9a14SMatthew G. Knepley PetscInt pRem = remotePoints[l].index; 3081412e9a14SMatthew G. Knepley PetscMPIInt rankRem = remotePoints[l].rank; 3082412e9a14SMatthew G. Knepley DMPolytopeType ct; 3083412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3084412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 3085412e9a14SMatthew G. Knepley PetscInt neighbor, Nct, n, r; 308675d3a19aSMatthew G. Knepley 3087412e9a14SMatthew G. Knepley ierr = PetscFindInt(rankRem, numNeighbors, neighbors, &neighbor);CHKERRQ(ierr); 3088412e9a14SMatthew G. Knepley if (neighbor < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rankRem); 3089412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 3090412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 3091412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 3092412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 3093412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 3094412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(crRem[neighbor], ct, rct[n], pRem, r, &pNewRem);CHKERRQ(ierr); 3095412e9a14SMatthew G. Knepley localPointsNew[m] = pNew; 3096412e9a14SMatthew G. Knepley remotePointsNew[m].index = pNewRem; 3097412e9a14SMatthew G. Knepley remotePointsNew[m].rank = rankRem; 30980314a74cSLawrence Mitchell ++m; 30990314a74cSLawrence Mitchell } 31006ce3c06aSMatthew G. Knepley } 31016ce3c06aSMatthew G. Knepley } 3102412e9a14SMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) {ierr = DMPlexCellRefinerDestroy(&crRem[n]);CHKERRQ(ierr);} 3103412e9a14SMatthew G. Knepley ierr = PetscFree(crRem);CHKERRQ(ierr); 3104d7eabd03SStefano Zampini if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew); 310575d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 310675d3a19aSMatthew G. Knepley ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 3107ba3c3d50SMatthew G. Knepley { 3108ba3c3d50SMatthew G. Knepley PetscSFNode *rp, *rtmp; 3109ba3c3d50SMatthew G. Knepley PetscInt *lp, *idx, *ltmp, i; 3110ba3c3d50SMatthew G. Knepley 3111ba3c3d50SMatthew G. Knepley /* SF needs sorted leaves to correct calculate Gather */ 3112ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &idx);CHKERRQ(ierr); 3113ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 3114ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 3115c7c54c77SMatthew G. Knepley for (i = 0; i < numLeavesNew; ++i) { 3116d7eabd03SStefano 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); 3117c7c54c77SMatthew G. Knepley idx[i] = i; 3118c7c54c77SMatthew G. Knepley } 3119ba3c3d50SMatthew G. Knepley ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 3120ba3c3d50SMatthew G. Knepley for (i = 0; i < numLeavesNew; ++i) { 3121ba3c3d50SMatthew G. Knepley lp[i] = localPointsNew[idx[i]]; 3122ba3c3d50SMatthew G. Knepley rp[i] = remotePointsNew[idx[i]]; 3123ba3c3d50SMatthew G. Knepley } 3124ba3c3d50SMatthew G. Knepley ltmp = localPointsNew; 3125ba3c3d50SMatthew G. Knepley localPointsNew = lp; 3126ba3c3d50SMatthew G. Knepley rtmp = remotePointsNew; 3127ba3c3d50SMatthew G. Knepley remotePointsNew = rp; 3128ba3c3d50SMatthew G. Knepley ierr = PetscFree(idx);CHKERRQ(ierr); 3129ba3c3d50SMatthew G. Knepley ierr = PetscFree(ltmp);CHKERRQ(ierr); 3130ba3c3d50SMatthew G. Knepley ierr = PetscFree(rtmp);CHKERRQ(ierr); 3131ba3c3d50SMatthew G. Knepley } 313275d3a19aSMatthew G. Knepley ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 313375d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 313475d3a19aSMatthew G. Knepley } 313575d3a19aSMatthew G. Knepley 3136e7887635SMatthew G. Knepley static PetscErrorCode RefineLabel_Internal(DMPlexCellRefiner cr, DMLabel label, DMLabel labelNew) 313775d3a19aSMatthew G. Knepley { 3138412e9a14SMatthew G. Knepley DM dm = cr->dm; 3139e7887635SMatthew G. Knepley IS valueIS; 3140e7887635SMatthew G. Knepley const PetscInt *values; 3141e7887635SMatthew G. Knepley PetscInt defVal, Nv, val; 314275d3a19aSMatthew G. Knepley PetscErrorCode ierr; 314375d3a19aSMatthew G. Knepley 314475d3a19aSMatthew G. Knepley PetscFunctionBegin; 31455aa44df4SToby Isaac ierr = DMLabelGetDefaultValue(label, &defVal);CHKERRQ(ierr); 31465aa44df4SToby Isaac ierr = DMLabelSetDefaultValue(labelNew, defVal);CHKERRQ(ierr); 314775d3a19aSMatthew G. Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 3148e7887635SMatthew G. Knepley ierr = ISGetLocalSize(valueIS, &Nv);CHKERRQ(ierr); 314975d3a19aSMatthew G. Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 3150e7887635SMatthew G. Knepley for (val = 0; val < Nv; ++val) { 315175d3a19aSMatthew G. Knepley IS pointIS; 315275d3a19aSMatthew G. Knepley const PetscInt *points; 3153412e9a14SMatthew G. Knepley PetscInt numPoints, p; 315475d3a19aSMatthew G. Knepley 31552bc5314cSMichael Lange /* Ensure refined label is created with same number of strata as 31562bc5314cSMichael Lange * original (even if no entries here). */ 3157ad8374ffSToby Isaac ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 3158412e9a14SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 3159412e9a14SMatthew G. Knepley ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 3160412e9a14SMatthew G. Knepley ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 3161412e9a14SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 3162412e9a14SMatthew G. Knepley const PetscInt point = points[p]; 3163412e9a14SMatthew G. Knepley DMPolytopeType ct; 3164412e9a14SMatthew G. Knepley DMPolytopeType *rct; 3165412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 3166e7887635SMatthew G. Knepley PetscInt Nct, n, r, pNew; 3167412e9a14SMatthew G. Knepley 3168412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, point, &ct);CHKERRQ(ierr); 3169412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 3170412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 3171412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 3172412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], point, r, &pNew);CHKERRQ(ierr); 3173412e9a14SMatthew G. Knepley ierr = DMLabelSetValue(labelNew, pNew, values[val]);CHKERRQ(ierr); 317427fcede3SMatthew G. Knepley } 317575d3a19aSMatthew G. Knepley } 317675d3a19aSMatthew G. Knepley } 317775d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 317875d3a19aSMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 317975d3a19aSMatthew G. Knepley } 318075d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 318175d3a19aSMatthew G. Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 3182e7887635SMatthew G. Knepley PetscFunctionReturn(0); 3183e7887635SMatthew G. Knepley } 3184e7887635SMatthew G. Knepley 3185e7887635SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateLabels(DMPlexCellRefiner cr, DM rdm) 3186e7887635SMatthew G. Knepley { 3187e7887635SMatthew G. Knepley DM dm = cr->dm; 3188e7887635SMatthew G. Knepley PetscInt numLabels, l; 3189e7887635SMatthew G. Knepley PetscErrorCode ierr; 3190e7887635SMatthew G. Knepley 3191e7887635SMatthew G. Knepley PetscFunctionBegin; 3192e7887635SMatthew G. Knepley ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 3193e7887635SMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 3194e7887635SMatthew G. Knepley DMLabel label, labelNew; 3195e7887635SMatthew G. Knepley const char *lname; 3196e7887635SMatthew G. Knepley PetscBool isDepth, isCellType; 3197e7887635SMatthew G. Knepley 3198e7887635SMatthew G. Knepley ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 3199e7887635SMatthew G. Knepley ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 3200e7887635SMatthew G. Knepley if (isDepth) continue; 3201e7887635SMatthew G. Knepley ierr = PetscStrcmp(lname, "celltype", &isCellType);CHKERRQ(ierr); 3202e7887635SMatthew G. Knepley if (isCellType) continue; 3203e7887635SMatthew G. Knepley ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 3204e7887635SMatthew G. Knepley ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 3205e7887635SMatthew G. Knepley ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 3206e7887635SMatthew G. Knepley ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr); 320775d3a19aSMatthew G. Knepley } 320875d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 320975d3a19aSMatthew G. Knepley } 321075d3a19aSMatthew G. Knepley 321175d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */ 3212412e9a14SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform(DM dm, DMPlexCellRefiner cr, DM *dmRefined) 321375d3a19aSMatthew G. Knepley { 321475d3a19aSMatthew G. Knepley DM rdm; 3215412e9a14SMatthew G. Knepley PetscInt dim, embedDim, depth; 321675d3a19aSMatthew G. Knepley PetscErrorCode ierr; 321775d3a19aSMatthew G. Knepley 321875d3a19aSMatthew G. Knepley PetscFunctionBegin; 3219412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 322075d3a19aSMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 322175d3a19aSMatthew G. Knepley ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 3222c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3223c73cfb54SMatthew G. Knepley ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 32246dcbd917SStefano Zampini ierr = DMGetCoordinateDim(dm, &embedDim);CHKERRQ(ierr); 32256dcbd917SStefano Zampini ierr = DMSetCoordinateDim(rdm, embedDim);CHKERRQ(ierr); 322675d3a19aSMatthew G. Knepley /* Calculate number of new points of each depth */ 322775d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 32281e573d11SMatthew G. Knepley if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 322975d3a19aSMatthew G. Knepley /* Step 1: Set chart */ 3230412e9a14SMatthew G. Knepley ierr = DMPlexSetChart(rdm, 0, cr->ctStartNew[cr->ctOrder[DM_NUM_POLYTOPES]]);CHKERRQ(ierr); 32316d7373e8SToby Isaac /* Step 2: Set cone/support sizes (automatically stratifies) */ 3232412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetConeSizes(cr, rdm);CHKERRQ(ierr); 323375d3a19aSMatthew G. Knepley /* Step 3: Setup refined DM */ 323475d3a19aSMatthew G. Knepley ierr = DMSetUp(rdm);CHKERRQ(ierr); 32356d7373e8SToby Isaac /* Step 4: Set cones and supports (automatically symmetrizes) */ 3236412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetCones(cr, rdm);CHKERRQ(ierr); 32376d7373e8SToby Isaac /* Step 5: Create pointSF */ 3238412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreateSF(cr, rdm);CHKERRQ(ierr); 32396d7373e8SToby Isaac /* Step 6: Create labels */ 3240412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreateLabels(cr, rdm);CHKERRQ(ierr); 32416d7373e8SToby Isaac /* Step 7: Set coordinates */ 3242412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetCoordinates(cr, rdm);CHKERRQ(ierr); 324375d3a19aSMatthew G. Knepley *dmRefined = rdm; 324475d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 324575d3a19aSMatthew G. Knepley } 324675d3a19aSMatthew G. Knepley 32472389894bSMatthew G. Knepley /*@ 32482389894bSMatthew G. Knepley DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 32492389894bSMatthew G. Knepley 32502389894bSMatthew G. Knepley Input Parameter: 32512389894bSMatthew G. Knepley . dm - The coarse DM 32522389894bSMatthew G. Knepley 32532389894bSMatthew G. Knepley Output Parameter: 32542389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh 32552389894bSMatthew G. Knepley 32562389894bSMatthew G. Knepley Level: developer 32572389894bSMatthew G. Knepley 325897d8846cSMatthew Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetSubpointIS() 32592389894bSMatthew G. Knepley @*/ 32602389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 32612389894bSMatthew G. Knepley { 3262412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 3263412e9a14SMatthew G. Knepley PetscInt *fpoints; 3264327c2912SStefano Zampini PetscInt pStart, pEnd, p, vStart, vEnd, v; 32652389894bSMatthew G. Knepley PetscErrorCode ierr; 32662389894bSMatthew G. Knepley 32672389894bSMatthew G. Knepley PetscFunctionBegin; 32682389894bSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 32692389894bSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 3270412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr); 3271412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 32722389894bSMatthew G. Knepley ierr = PetscMalloc1(pEnd-pStart, &fpoints);CHKERRQ(ierr); 32732389894bSMatthew G. Knepley for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 3274412e9a14SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 3275327c2912SStefano Zampini PetscInt vNew = -1; /* silent overzelous may be used uninitialized */ 3276327c2912SStefano Zampini 3277412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, DM_POLYTOPE_POINT, DM_POLYTOPE_POINT, p, 0, &vNew);CHKERRQ(ierr); 3278412e9a14SMatthew G. Knepley fpoints[v-pStart] = vNew; 32792389894bSMatthew G. Knepley } 3280412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 32812389894bSMatthew G. Knepley ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 32822389894bSMatthew G. Knepley PetscFunctionReturn(0); 32832389894bSMatthew G. Knepley } 32842389894bSMatthew G. Knepley 32850e2b6761SMatthew G. Knepley /*@ 32860e2b6761SMatthew G. Knepley DMPlexSetRefinementUniform - Set the flag for uniform refinement 32870e2b6761SMatthew G. Knepley 32880e2b6761SMatthew G. Knepley Input Parameters: 32890e2b6761SMatthew G. Knepley + dm - The DM 32900e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement 32910e2b6761SMatthew G. Knepley 32920e2b6761SMatthew G. Knepley Level: developer 32930e2b6761SMatthew G. Knepley 32940e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 32950e2b6761SMatthew G. Knepley @*/ 329675d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 329775d3a19aSMatthew G. Knepley { 329875d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 329975d3a19aSMatthew G. Knepley 330075d3a19aSMatthew G. Knepley PetscFunctionBegin; 330175d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 330275d3a19aSMatthew G. Knepley mesh->refinementUniform = refinementUniform; 330375d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 330475d3a19aSMatthew G. Knepley } 330575d3a19aSMatthew G. Knepley 33060e2b6761SMatthew G. Knepley /*@ 33070e2b6761SMatthew G. Knepley DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 33080e2b6761SMatthew G. Knepley 33090e2b6761SMatthew G. Knepley Input Parameter: 33100e2b6761SMatthew G. Knepley . dm - The DM 33110e2b6761SMatthew G. Knepley 33120e2b6761SMatthew G. Knepley Output Parameter: 33130e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement 33140e2b6761SMatthew G. Knepley 33150e2b6761SMatthew G. Knepley Level: developer 33160e2b6761SMatthew G. Knepley 33170e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 33180e2b6761SMatthew G. Knepley @*/ 331975d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 332075d3a19aSMatthew G. Knepley { 332175d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 332275d3a19aSMatthew G. Knepley 332375d3a19aSMatthew G. Knepley PetscFunctionBegin; 332475d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 332575d3a19aSMatthew G. Knepley PetscValidPointer(refinementUniform, 2); 332675d3a19aSMatthew G. Knepley *refinementUniform = mesh->refinementUniform; 332775d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 332875d3a19aSMatthew G. Knepley } 332975d3a19aSMatthew G. Knepley 33300e2b6761SMatthew G. Knepley /*@ 33310e2b6761SMatthew G. Knepley DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 33320e2b6761SMatthew G. Knepley 33330e2b6761SMatthew G. Knepley Input Parameters: 33340e2b6761SMatthew G. Knepley + dm - The DM 33350e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh 33360e2b6761SMatthew G. Knepley 33370e2b6761SMatthew G. Knepley Level: developer 33380e2b6761SMatthew G. Knepley 33390e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 33400e2b6761SMatthew G. Knepley @*/ 334175d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 334275d3a19aSMatthew G. Knepley { 334375d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 334475d3a19aSMatthew G. Knepley 334575d3a19aSMatthew G. Knepley PetscFunctionBegin; 334675d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 334775d3a19aSMatthew G. Knepley mesh->refinementLimit = refinementLimit; 334875d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 334975d3a19aSMatthew G. Knepley } 335075d3a19aSMatthew G. Knepley 33510e2b6761SMatthew G. Knepley /*@ 33520e2b6761SMatthew G. Knepley DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 33530e2b6761SMatthew G. Knepley 33540e2b6761SMatthew G. Knepley Input Parameter: 33550e2b6761SMatthew G. Knepley . dm - The DM 33560e2b6761SMatthew G. Knepley 33570e2b6761SMatthew G. Knepley Output Parameter: 33580e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh 33590e2b6761SMatthew G. Knepley 33600e2b6761SMatthew G. Knepley Level: developer 33610e2b6761SMatthew G. Knepley 33620e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 33630e2b6761SMatthew G. Knepley @*/ 336475d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 336575d3a19aSMatthew G. Knepley { 336675d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 336775d3a19aSMatthew G. Knepley 336875d3a19aSMatthew G. Knepley PetscFunctionBegin; 336975d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 337075d3a19aSMatthew G. Knepley PetscValidPointer(refinementLimit, 2); 337175d3a19aSMatthew G. Knepley /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 337275d3a19aSMatthew G. Knepley *refinementLimit = mesh->refinementLimit; 337375d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 337475d3a19aSMatthew G. Knepley } 337575d3a19aSMatthew G. Knepley 3376b28003e6SMatthew G. Knepley /*@ 3377b28003e6SMatthew G. Knepley DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 3378b28003e6SMatthew G. Knepley 3379b28003e6SMatthew G. Knepley Input Parameters: 3380b28003e6SMatthew G. Knepley + dm - The DM 3381b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh 3382b28003e6SMatthew G. Knepley 3383b28003e6SMatthew G. Knepley Note: The calling sequence is refinementFunc(coords, limit) 3384b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid 3385b28003e6SMatthew G. Knepley $ limit - The maximum cell volume for a cell containing this point 3386b28003e6SMatthew G. Knepley 3387b28003e6SMatthew G. Knepley Level: developer 3388b28003e6SMatthew G. Knepley 3389b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 3390b28003e6SMatthew G. Knepley @*/ 3391b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 3392b28003e6SMatthew G. Knepley { 3393b28003e6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 3394b28003e6SMatthew G. Knepley 3395b28003e6SMatthew G. Knepley PetscFunctionBegin; 3396b28003e6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3397b28003e6SMatthew G. Knepley mesh->refinementFunc = refinementFunc; 3398b28003e6SMatthew G. Knepley PetscFunctionReturn(0); 3399b28003e6SMatthew G. Knepley } 3400b28003e6SMatthew G. Knepley 3401b28003e6SMatthew G. Knepley /*@ 3402b28003e6SMatthew G. Knepley DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 3403b28003e6SMatthew G. Knepley 3404b28003e6SMatthew G. Knepley Input Parameter: 3405b28003e6SMatthew G. Knepley . dm - The DM 3406b28003e6SMatthew G. Knepley 3407b28003e6SMatthew G. Knepley Output Parameter: 3408b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh 3409b28003e6SMatthew G. Knepley 3410b28003e6SMatthew G. Knepley Note: The calling sequence is refinementFunc(coords, limit) 3411b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid 3412b28003e6SMatthew G. Knepley $ limit - The maximum cell volume for a cell containing this point 3413b28003e6SMatthew G. Knepley 3414b28003e6SMatthew G. Knepley Level: developer 3415b28003e6SMatthew G. Knepley 3416b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 3417b28003e6SMatthew G. Knepley @*/ 3418b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 3419b28003e6SMatthew G. Knepley { 3420b28003e6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 3421b28003e6SMatthew G. Knepley 3422b28003e6SMatthew G. Knepley PetscFunctionBegin; 3423b28003e6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3424b28003e6SMatthew G. Knepley PetscValidPointer(refinementFunc, 2); 3425b28003e6SMatthew G. Knepley *refinementFunc = mesh->refinementFunc; 3426b28003e6SMatthew G. Knepley PetscFunctionReturn(0); 3427b28003e6SMatthew G. Knepley } 3428b28003e6SMatthew G. Knepley 3429e7887635SMatthew G. Knepley static PetscErrorCode RefineDiscLabels_Internal(DMPlexCellRefiner cr, DM rdm) 3430e7887635SMatthew G. Knepley { 3431e7887635SMatthew G. Knepley DM dm = cr->dm; 3432e7887635SMatthew G. Knepley PetscInt Nf, f, Nds, s; 3433e7887635SMatthew G. Knepley PetscErrorCode ierr; 3434e7887635SMatthew G. Knepley 3435e7887635SMatthew G. Knepley PetscFunctionBegin; 3436e7887635SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 3437e7887635SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 3438e7887635SMatthew G. Knepley DMLabel label, labelNew; 3439e7887635SMatthew G. Knepley PetscObject obj; 3440e7887635SMatthew G. Knepley const char *lname; 3441e7887635SMatthew G. Knepley 3442e7887635SMatthew G. Knepley ierr = DMGetField(rdm, f, &label, &obj);CHKERRQ(ierr); 3443e7887635SMatthew G. Knepley if (!label) continue; 3444e7887635SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 3445e7887635SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew);CHKERRQ(ierr); 3446e7887635SMatthew G. Knepley ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr); 3447e7887635SMatthew G. Knepley ierr = DMSetField_Internal(rdm, f, labelNew, obj);CHKERRQ(ierr); 3448e7887635SMatthew G. Knepley ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr); 3449e7887635SMatthew G. Knepley } 3450e7887635SMatthew G. Knepley ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr); 3451e7887635SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 3452e7887635SMatthew G. Knepley DMLabel label, labelNew; 3453e7887635SMatthew G. Knepley const char *lname; 3454e7887635SMatthew G. Knepley 3455e7887635SMatthew G. Knepley ierr = DMGetRegionNumDS(rdm, s, &label, NULL, NULL);CHKERRQ(ierr); 3456e7887635SMatthew G. Knepley if (!label) continue; 3457e7887635SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 3458e7887635SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew);CHKERRQ(ierr); 3459e7887635SMatthew G. Knepley ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr); 3460e7887635SMatthew G. Knepley ierr = DMSetRegionNumDS(rdm, s, labelNew, NULL, NULL);CHKERRQ(ierr); 3461e7887635SMatthew G. Knepley ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr); 3462e7887635SMatthew G. Knepley } 3463e7887635SMatthew G. Knepley PetscFunctionReturn(0); 3464e7887635SMatthew G. Knepley } 3465e7887635SMatthew G. Knepley 34660d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 34670d1cd5e0SMatthew G. Knepley { 3468492b8470SStefano Zampini PetscBool isUniform; 3469412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 34700d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 34710d1cd5e0SMatthew G. Knepley 34720d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 34730d1cd5e0SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 3474412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-initref_dm_view");CHKERRQ(ierr); 34750d1cd5e0SMatthew G. Knepley if (isUniform) { 347651a74b61SMatthew G. Knepley DM cdm, rcdm; 3477492b8470SStefano Zampini PetscBool localized; 34780d1cd5e0SMatthew G. Knepley 3479412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr); 3480412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 3481492b8470SStefano Zampini ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 3482412e9a14SMatthew G. Knepley ierr = DMPlexRefineUniform(dm, cr, dmRefined);CHKERRQ(ierr); 34839a7e3c0aSMatthew G. Knepley ierr = DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);CHKERRQ(ierr); 3484e7887635SMatthew G. Knepley ierr = DMCopyDisc(dm, *dmRefined);CHKERRQ(ierr); 348551a74b61SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 348651a74b61SMatthew G. Knepley ierr = DMGetCoordinateDM(*dmRefined, &rcdm);CHKERRQ(ierr); 348751a74b61SMatthew G. Knepley ierr = DMCopyDisc(cdm, rcdm);CHKERRQ(ierr); 3488e7887635SMatthew G. Knepley ierr = RefineDiscLabels_Internal(cr, *dmRefined);CHKERRQ(ierr); 34890d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 3490412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 34910d1cd5e0SMatthew G. Knepley } else { 34920d1cd5e0SMatthew G. Knepley ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 34930d1cd5e0SMatthew G. Knepley } 34940d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 34950d1cd5e0SMatthew G. Knepley } 34960d1cd5e0SMatthew G. Knepley 34970d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 34980d1cd5e0SMatthew G. Knepley { 34990d1cd5e0SMatthew G. Knepley DM cdm = dm; 35000d1cd5e0SMatthew G. Knepley PetscInt r; 35010d1cd5e0SMatthew G. Knepley PetscBool isUniform, localized; 35020d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 35030d1cd5e0SMatthew G. Knepley 35040d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 35050d1cd5e0SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 35060d1cd5e0SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 35070d1cd5e0SMatthew G. Knepley if (isUniform) { 35080d1cd5e0SMatthew G. Knepley for (r = 0; r < nlevels; ++r) { 3509412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 351051a74b61SMatthew G. Knepley DM codm, rcodm; 35110d1cd5e0SMatthew G. Knepley 3512412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(cdm, &cr);CHKERRQ(ierr); 3513412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 3514412e9a14SMatthew G. Knepley ierr = DMPlexRefineUniform(cdm, cr, &dmRefined[r]);CHKERRQ(ierr); 35159a7e3c0aSMatthew G. Knepley ierr = DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);CHKERRQ(ierr); 35169a7e3c0aSMatthew G. Knepley ierr = DMSetRefineLevel(dmRefined[r], cdm->levelup+1);CHKERRQ(ierr); 3517e7887635SMatthew G. Knepley ierr = DMCopyDisc(cdm, dmRefined[r]);CHKERRQ(ierr); 351851a74b61SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &codm);CHKERRQ(ierr); 351951a74b61SMatthew G. Knepley ierr = DMGetCoordinateDM(dmRefined[r], &rcodm);CHKERRQ(ierr); 352051a74b61SMatthew G. Knepley ierr = DMCopyDisc(codm, rcodm);CHKERRQ(ierr); 3521e7887635SMatthew G. Knepley ierr = RefineDiscLabels_Internal(cr, dmRefined[r]);CHKERRQ(ierr); 35220d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 35230d1cd5e0SMatthew G. Knepley ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 35240d1cd5e0SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 35250d1cd5e0SMatthew G. Knepley cdm = dmRefined[r]; 3526412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 35270d1cd5e0SMatthew G. Knepley } 35280d1cd5e0SMatthew G. Knepley } else { 35290d1cd5e0SMatthew G. Knepley for (r = 0; r < nlevels; ++r) { 35300d1cd5e0SMatthew G. Knepley ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 3531e7887635SMatthew G. Knepley ierr = DMCopyDisc(cdm, dmRefined[r]);CHKERRQ(ierr); 35320d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 35330d1cd5e0SMatthew G. Knepley if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 35340d1cd5e0SMatthew G. Knepley ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 35350d1cd5e0SMatthew G. Knepley cdm = dmRefined[r]; 35360d1cd5e0SMatthew G. Knepley } 35370d1cd5e0SMatthew G. Knepley } 35380d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 35390d1cd5e0SMatthew G. Knepley } 3540