1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2*412e9a14SMatthew G. Knepley #include <petsc/private/petscfeimpl.h> /* For PetscFEInterpolate_Static() */ 375d3a19aSMatthew G. Knepley #include <petscsf.h> 475d3a19aSMatthew G. Knepley 5*412e9a14SMatthew G. Knepley const char * const DMPlexCellRefinerTypes[] = {"Regular", "ToHex", "ToSimplex", "DMPlexCellRefinerTypes", "REFINER_", 0}; 675d3a19aSMatthew G. Knepley 709789c4cSMatthew G. Knepley /* 809789c4cSMatthew G. Knepley Note that j and invj are non-square: 909789c4cSMatthew G. Knepley v0 + j x_face = x_cell 1009789c4cSMatthew G. Knepley invj (x_cell - v0) = x_face 1109789c4cSMatthew G. Knepley */ 12*412e9a14SMatthew 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 28*412e9a14SMatthew G. Knepley v0[Nf][dc]: 3 x 2 29*412e9a14SMatthew G. Knepley J[Nf][df][dc]: 3 x 1 x 2 30*412e9a14SMatthew G. Knepley invJ[Nf][dc][df]: 3 x 2 x 1 31*412e9a14SMatthew G. Knepley detJ[Nf]: 3 3209789c4cSMatthew G. Knepley */ 33*412e9a14SMatthew G. Knepley static PetscReal tri_v0[] = {0.0, -1.0, 0.0, 0.0, -1.0, 0.0}; 34*412e9a14SMatthew G. Knepley static PetscReal tri_J[] = {1.0, 0.0, -1.0, 1.0, 0.0, -1.0}; 35*412e9a14SMatthew G. Knepley static PetscReal tri_invJ[] = {1.0, 0.0, -0.5, 0.5, 0.0, -1.0}; 36*412e9a14SMatthew 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 47*412e9a14SMatthew G. Knepley 48*412e9a14SMatthew G. Knepley v0[Nf][dc]: 4 x 2 49*412e9a14SMatthew G. Knepley J[Nf][df][dc]: 4 x 1 x 2 50*412e9a14SMatthew G. Knepley invJ[Nf][dc][df]: 4 x 2 x 1 51*412e9a14SMatthew G. Knepley detJ[Nf]: 4 5209789c4cSMatthew G. Knepley */ 53*412e9a14SMatthew G. Knepley static PetscReal quad_v0[] = {0.0, -1.0, 1.0, 0.0, 0.0, 1.0 -1.0, 0.0}; 54*412e9a14SMatthew G. Knepley static PetscReal quad_J[] = {1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, -1.0}; 55*412e9a14SMatthew G. Knepley static PetscReal quad_invJ[] = {1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, -1.0}; 56*412e9a14SMatthew G. Knepley static PetscReal quad_detJ[] = {1.0, 1.0, 1.0, 1.0}; 57*412e9a14SMatthew G. Knepley 58*412e9a14SMatthew G. Knepley PetscFunctionBegin; 59*412e9a14SMatthew G. Knepley switch (ct) { 60*412e9a14SMatthew 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; 61*412e9a14SMatthew 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: 63*412e9a14SMatthew 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 */ 69*412e9a14SMatthew 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 */ 86*412e9a14SMatthew G. Knepley static PetscReal tri_v0[] = {-1.0, -1.0, 0.0, -1.0, -1.0, 0.0, 0.0, -1.0}; 87*412e9a14SMatthew G. Knepley static PetscReal tri_J[] = {0.5, 0.0, 88*412e9a14SMatthew G. Knepley 0.0, 0.5, 89*412e9a14SMatthew G. Knepley 90*412e9a14SMatthew G. Knepley 0.5, 0.0, 91*412e9a14SMatthew G. Knepley 0.0, 0.5, 92*412e9a14SMatthew G. Knepley 93*412e9a14SMatthew G. Knepley 0.5, 0.0, 94*412e9a14SMatthew G. Knepley 0.0, 0.5, 95*412e9a14SMatthew G. Knepley 96*412e9a14SMatthew G. Knepley 0.0, -0.5, 97*412e9a14SMatthew G. Knepley 0.5, 0.5}; 98*412e9a14SMatthew G. Knepley static PetscReal tri_invJ[] = {2.0, 0.0, 99*412e9a14SMatthew G. Knepley 0.0, 2.0, 100*412e9a14SMatthew G. Knepley 101*412e9a14SMatthew G. Knepley 2.0, 0.0, 102*412e9a14SMatthew G. Knepley 0.0, 2.0, 103*412e9a14SMatthew G. Knepley 104*412e9a14SMatthew G. Knepley 2.0, 0.0, 105*412e9a14SMatthew G. Knepley 0.0, 2.0, 106*412e9a14SMatthew G. Knepley 107*412e9a14SMatthew G. Knepley 2.0, 2.0, 108*412e9a14SMatthew 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 */ 120*412e9a14SMatthew G. Knepley static PetscReal quad_v0[] = {-1.0, -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0}; 121*412e9a14SMatthew G. Knepley static PetscReal quad_J[] = {0.5, 0.0, 122*412e9a14SMatthew G. Knepley 0.0, 0.5, 123*412e9a14SMatthew G. Knepley 124*412e9a14SMatthew G. Knepley 0.5, 0.0, 125*412e9a14SMatthew G. Knepley 0.0, 0.5, 126*412e9a14SMatthew G. Knepley 127*412e9a14SMatthew G. Knepley 0.5, 0.0, 128*412e9a14SMatthew G. Knepley 0.0, 0.5, 129*412e9a14SMatthew G. Knepley 130*412e9a14SMatthew G. Knepley 0.5, 0.0, 131*412e9a14SMatthew G. Knepley 0.0, 0.5}; 132*412e9a14SMatthew G. Knepley static PetscReal quad_invJ[] = {2.0, 0.0, 133*412e9a14SMatthew G. Knepley 0.0, 2.0, 134*412e9a14SMatthew G. Knepley 135*412e9a14SMatthew G. Knepley 2.0, 0.0, 136*412e9a14SMatthew G. Knepley 0.0, 2.0, 137*412e9a14SMatthew G. Knepley 138*412e9a14SMatthew G. Knepley 2.0, 0.0, 139*412e9a14SMatthew G. Knepley 0.0, 2.0, 140*412e9a14SMatthew G. Knepley 141*412e9a14SMatthew G. Knepley 2.0, 0.0, 142*412e9a14SMatthew 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 */ 155*412e9a14SMatthew 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, 156*412e9a14SMatthew 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}; 157*412e9a14SMatthew G. Knepley static PetscReal hex_J[] = {0.5, 0.0, 0.0, 158*412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 159*412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 160bed052eaSMatthew G. Knepley 161*412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 162*412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 163*412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 164*412e9a14SMatthew G. Knepley 165*412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 166*412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 167*412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 168*412e9a14SMatthew G. Knepley 169*412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 170*412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 171*412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 172*412e9a14SMatthew G. Knepley 173*412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 174*412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 175*412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 176*412e9a14SMatthew G. Knepley 177*412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 178*412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 179*412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 180*412e9a14SMatthew G. Knepley 181*412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 182*412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 183*412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 184*412e9a14SMatthew G. Knepley 185*412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 186*412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 187*412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5}; 188*412e9a14SMatthew G. Knepley static PetscReal hex_invJ[] = {2.0, 0.0, 0.0, 189*412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 190*412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 191*412e9a14SMatthew G. Knepley 192*412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 193*412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 194*412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 195*412e9a14SMatthew G. Knepley 196*412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 197*412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 198*412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 199*412e9a14SMatthew G. Knepley 200*412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 201*412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 202*412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 203*412e9a14SMatthew G. Knepley 204*412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 205*412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 206*412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 207*412e9a14SMatthew G. Knepley 208*412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 209*412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 210*412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 211*412e9a14SMatthew G. Knepley 212*412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 213*412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 214*412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 215*412e9a14SMatthew G. Knepley 216*412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 217*412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 218*412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0}; 219bed052eaSMatthew G. Knepley 220bed052eaSMatthew G. Knepley PetscFunctionBegin; 221*412e9a14SMatthew G. Knepley switch (ct) { 222*412e9a14SMatthew 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; 223*412e9a14SMatthew 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; 224*412e9a14SMatthew 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; 225*412e9a14SMatthew G. Knepley default: 226*412e9a14SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 227*412e9a14SMatthew 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? */ 232*412e9a14SMatthew 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; 239*412e9a14SMatthew G. Knepley switch (ct) { 240*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 241*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 242*412e9a14SMatthew 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 } 246*412e9a14SMatthew G. Knepley if (sum > PETSC_SMALL) {*inside = PETSC_FALSE; break;} 24780389061SMatthew G. Knepley break; 248*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 249*412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 250*412e9a14SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) 251*412e9a14SMatthew G. Knepley if (PetscAbsReal(point[d]) > 1.+PETSC_SMALL) {*inside = PETSC_FALSE; break;} 25294339e62SJed Brown break; 25380389061SMatthew G. Knepley default: 254*412e9a14SMatthew 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 259*412e9a14SMatthew G. Knepley /* Regular Refinment of Hybrid Meshes 26075d3a19aSMatthew G. Knepley 261*412e9a14SMatthew 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 262*412e9a14SMatthew G. Knepley to automatically generate a refined Plex. In fact, we would like these rules to be general enough to encompass other 263*412e9a14SMatthew G. Knepley transformations, such as changing from one type of cell to another, as simplex to hex. 26475d3a19aSMatthew G. Knepley 265*412e9a14SMatthew G. Knepley To start, we can create a function that takes an original cell type and returns the number of new cells replacing it 266*412e9a14SMatthew G. Knepley and the types of the new cells. 267518a8359SMatthew G. Knepley 268*412e9a14SMatthew G. Knepley We need the group multiplication table for group actions from the dihedral group for each cell type. 26942525629SMatthew G. Knepley 270*412e9a14SMatthew 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 271*412e9a14SMatthew G. Knepley we can just write this operator for faces with identity, and then compose the face orientation actions to get the actual 272*412e9a14SMatthew G. Knepley (face, orient) pairs for each subcell. 273*412e9a14SMatthew G. Knepley */ 2740314a74cSLawrence Mitchell 27575d3a19aSMatthew G. Knepley /* 276*412e9a14SMatthew G. Knepley Input Parameters: 277*412e9a14SMatthew G. Knepley + ct - The type of the input cell 278*412e9a14SMatthew G. Knepley . co - The orientation of this cell in it parent 279*412e9a14SMatthew G. Knepley - cp - The requested cone point of this cell assuming orientation 0 280*412e9a14SMatthew G. Knepley 281*412e9a14SMatthew G. Knepley Output Parameters: 282*412e9a14SMatthew G. Knepley . cpnew - The new cone point, taking inout account the orientation co 283*412e9a14SMatthew G. Knepley */ 284*412e9a14SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPolytopeMapCell(DMPolytopeType ct, PetscInt co, PetscInt cp, PetscInt *cpnew) 285*412e9a14SMatthew G. Knepley { 286*412e9a14SMatthew G. Knepley const PetscInt csize = DMPolytopeTypeGetConeSize(ct); 287*412e9a14SMatthew G. Knepley 288*412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 289*412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_POINT) {*cpnew = cp;} 290*412e9a14SMatthew G. Knepley else {*cpnew = (co < 0 ? -(co+1)-cp+csize : co+cp)%csize;} 291*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 292*412e9a14SMatthew G. Knepley } 293*412e9a14SMatthew G. Knepley 294*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCellVertices_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 295*412e9a14SMatthew G. Knepley { 296*412e9a14SMatthew G. Knepley static PetscReal seg_v[] = {-1.0, 0.0, 1.0}; 297*412e9a14SMatthew 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}; 298*412e9a14SMatthew 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}; 299*412e9a14SMatthew G. Knepley static PetscReal tet_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 300*412e9a14SMatthew G. Knepley -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, -1.0, 1.0, -1.0, 301*412e9a14SMatthew 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}; 302*412e9a14SMatthew G. Knepley static PetscReal hex_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 303*412e9a14SMatthew G. Knepley -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0, -1.0, 304*412e9a14SMatthew G. Knepley -1.0, 1.0, -1.0, 0.0, 1.0, -1.0, 1.0, 1.0, -1.0, 305*412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0, -1.0, 0.0, 306*412e9a14SMatthew G. Knepley -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 307*412e9a14SMatthew G. Knepley -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 308*412e9a14SMatthew G. Knepley -1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 1.0, -1.0, 1.0, 309*412e9a14SMatthew G. Knepley -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 310*412e9a14SMatthew G. Knepley -1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0}; 311*412e9a14SMatthew G. Knepley 312*412e9a14SMatthew G. Knepley PetscFunctionBegin; 313*412e9a14SMatthew G. Knepley switch (ct) { 314*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nv = 3; *subcellV = seg_v; break; 315*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 6; *subcellV = tri_v; break; 316*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nv = 9; *subcellV = quad_v; break; 317*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 10; *subcellV = tet_v; break; 318*412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nv = 27; *subcellV = hex_v; break; 319*412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 320*412e9a14SMatthew G. Knepley } 321*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 322*412e9a14SMatthew G. Knepley } 323*412e9a14SMatthew G. Knepley 324*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCellVertices_ToHex(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 325*412e9a14SMatthew G. Knepley { 326*412e9a14SMatthew 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}; 327*412e9a14SMatthew G. Knepley static PetscReal tet_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 328*412e9a14SMatthew 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, 329*412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, -1.0/3.0, -1.0, -1.0/3.0, 0.0, -1.0, 0.0, 330*412e9a14SMatthew 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, 331*412e9a14SMatthew G. Knepley -1.0, -1.0, 1.0, -0.5, -0.5, -0.5}; 332*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 333*412e9a14SMatthew G. Knepley 334*412e9a14SMatthew G. Knepley PetscFunctionBegin; 335*412e9a14SMatthew G. Knepley switch (ct) { 336*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 337*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 338*412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 339*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCellVertices_Regular(cr, ct, Nv, subcellV);CHKERRQ(ierr);break; 340*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 7; *subcellV = tri_v; break; 341*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 15; *subcellV = tet_v; break; 342*412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 343*412e9a14SMatthew G. Knepley } 344*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 345*412e9a14SMatthew G. Knepley } 346*412e9a14SMatthew G. Knepley 347*412e9a14SMatthew G. Knepley /* 348*412e9a14SMatthew G. Knepley DMPlexCellRefinerGetCellVertices - Get the set of refined vertices lying in the closure of a reference cell of given type 349*412e9a14SMatthew G. Knepley 350*412e9a14SMatthew G. Knepley Input Parameters: 351*412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 352*412e9a14SMatthew G. Knepley - ct - The cell type 353*412e9a14SMatthew G. Knepley 354*412e9a14SMatthew G. Knepley Output Parameters: 355*412e9a14SMatthew G. Knepley + Nv - The number of refined vertices in the closure of the reference cell of given type 356*412e9a14SMatthew G. Knepley - subcellV - The coordinates of these vertices in the reference cell 357*412e9a14SMatthew G. Knepley 358*412e9a14SMatthew G. Knepley Level: developer 359*412e9a14SMatthew G. Knepley 360*412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetSubcellVertices() 361*412e9a14SMatthew G. Knepley */ 362*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCellVertices(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 363*412e9a14SMatthew G. Knepley { 364*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 365*412e9a14SMatthew G. Knepley 366*412e9a14SMatthew G. Knepley PetscFunctionBegin; 367*412e9a14SMatthew G. Knepley ierr = (*cr->ops->getcellvertices)(cr, ct, Nv, subcellV);CHKERRQ(ierr); 368*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 369*412e9a14SMatthew G. Knepley } 370*412e9a14SMatthew G. Knepley 371*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 372*412e9a14SMatthew G. Knepley { 373*412e9a14SMatthew G. Knepley static PetscInt seg_v[] = {0, 1, 1, 2}; 374*412e9a14SMatthew G. Knepley static PetscInt tri_v[] = {0, 3, 5, 3, 1, 4, 5, 4, 2, 3, 4, 5}; 375*412e9a14SMatthew G. Knepley static PetscInt quad_v[] = {0, 4, 8, 7, 4, 1, 5, 8, 8, 5, 2, 6, 7, 8, 6, 3}; 376*412e9a14SMatthew G. Knepley static PetscInt tet_v[] = {0, 3, 1, 6, 3, 2, 4, 8, 1, 4, 5, 7, 6, 8, 7, 9, 377*412e9a14SMatthew G. Knepley 1, 6, 3, 7, 8, 4, 3, 7, 7, 3, 1, 4, 7, 3, 8, 6}; 378*412e9a14SMatthew 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, 379*412e9a14SMatthew 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}; 380*412e9a14SMatthew G. Knepley 381*412e9a14SMatthew G. Knepley PetscFunctionBegin; 382*412e9a14SMatthew G. Knepley if (ct != rct) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Cell type %s does not produce %s", DMPolytopeTypes[ct], DMPolytopeTypes[rct]); 383*412e9a14SMatthew G. Knepley switch (ct) { 384*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nv = 2; *subcellV = &seg_v[r*(*Nv)]; break; 385*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 3; *subcellV = &tri_v[r*(*Nv)]; break; 386*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nv = 4; *subcellV = &quad_v[r*(*Nv)]; break; 387*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 4; *subcellV = &tet_v[r*(*Nv)]; break; 388*412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nv = 8; *subcellV = &hex_v[r*(*Nv)]; break; 389*412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 390*412e9a14SMatthew G. Knepley } 391*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 392*412e9a14SMatthew G. Knepley } 393*412e9a14SMatthew G. Knepley 394*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices_ToHex(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 395*412e9a14SMatthew G. Knepley { 396*412e9a14SMatthew G. Knepley static PetscInt tri_v[] = {0, 3, 6, 5, 3, 1, 4, 6, 5, 6, 4, 2}; 397*412e9a14SMatthew 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}; 398*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 399*412e9a14SMatthew G. Knepley 400*412e9a14SMatthew G. Knepley PetscFunctionBegin; 401*412e9a14SMatthew G. Knepley switch (ct) { 402*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 403*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 404*412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 405*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetSubcellVertices_Regular(cr, ct, rct, r, Nv, subcellV);CHKERRQ(ierr);break; 406*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 407*412e9a14SMatthew 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]); 408*412e9a14SMatthew G. Knepley *Nv = 4; *subcellV = &tri_v[r*(*Nv)]; break; 409*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 410*412e9a14SMatthew 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]); 411*412e9a14SMatthew G. Knepley *Nv = 8; *subcellV = &tet_v[r*(*Nv)]; break; 412*412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 413*412e9a14SMatthew G. Knepley } 414*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 415*412e9a14SMatthew G. Knepley } 416*412e9a14SMatthew G. Knepley 417*412e9a14SMatthew G. Knepley /* 418*412e9a14SMatthew G. Knepley DMPlexCellRefinerGetSubcellVertices - Get the set of refined vertices defining a subcell in the reference cell of given type 419*412e9a14SMatthew G. Knepley 420*412e9a14SMatthew G. Knepley Input Parameters: 421*412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 422*412e9a14SMatthew G. Knepley . ct - The cell type 423*412e9a14SMatthew G. Knepley . rct - The type of subcell 424*412e9a14SMatthew G. Knepley - r - The subcell index 425*412e9a14SMatthew G. Knepley 426*412e9a14SMatthew G. Knepley Output Parameters: 427*412e9a14SMatthew G. Knepley + Nv - The number of refined vertices in the subcell 428*412e9a14SMatthew G. Knepley - subcellV - The indices of these vertices in the set of vertices returned by DMPlexCellRefinerGetCellVertices() 429*412e9a14SMatthew G. Knepley 430*412e9a14SMatthew G. Knepley Level: developer 431*412e9a14SMatthew G. Knepley 432*412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetCellVertices() 433*412e9a14SMatthew G. Knepley */ 434*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 435*412e9a14SMatthew G. Knepley { 436*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 437*412e9a14SMatthew G. Knepley 438*412e9a14SMatthew G. Knepley PetscFunctionBegin; 439*412e9a14SMatthew G. Knepley ierr = (*cr->ops->getsubcellvertices)(cr, ct, rct, r, Nv, subcellV);CHKERRQ(ierr); 440*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 441*412e9a14SMatthew G. Knepley } 442*412e9a14SMatthew G. Knepley 443*412e9a14SMatthew G. Knepley /* 444*412e9a14SMatthew G. Knepley Input Parameters: 445*412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner 446*412e9a14SMatthew G. Knepley . pct - The cell type of the parent, from whom the new cell is being produced 447*412e9a14SMatthew G. Knepley . po - The orientation of the parent cell in its enclosing parent 448*412e9a14SMatthew G. Knepley . ct - The type being produced 449*412e9a14SMatthew G. Knepley . r - The replica number requested for the produced cell type 450*412e9a14SMatthew G. Knepley - o - The relative orientation of the replica 451*412e9a14SMatthew G. Knepley 452*412e9a14SMatthew G. Knepley Output Parameters: 453*412e9a14SMatthew G. Knepley + rnew - The replica number, given the orientation of of the parent 454*412e9a14SMatthew G. Knepley - onew - The replica orientation, given the orientation of the parent 455*412e9a14SMatthew G. Knepley */ 456*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 457*412e9a14SMatthew G. Knepley { 458*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 459*412e9a14SMatthew G. Knepley 460*412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 461*412e9a14SMatthew G. Knepley ierr = (*cr->ops->mapsubcells)(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 462*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 463*412e9a14SMatthew G. Knepley } 464*412e9a14SMatthew G. Knepley 465*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_Regular(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 466*412e9a14SMatthew G. Knepley { 467*412e9a14SMatthew G. Knepley /* We shift any input orientation in order to make it non-negative 468*412e9a14SMatthew 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) 469*412e9a14SMatthew G. Knepley The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 470*412e9a14SMatthew G. Knepley Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 471*412e9a14SMatthew G. Knepley */ 472*412e9a14SMatthew G. Knepley PetscInt tri_seg_o[] = {-2, 0, 473*412e9a14SMatthew G. Knepley -2, 0, 474*412e9a14SMatthew G. Knepley -2, 0, 475*412e9a14SMatthew G. Knepley 0, -2, 476*412e9a14SMatthew G. Knepley 0, -2, 477*412e9a14SMatthew G. Knepley 0, -2}; 478*412e9a14SMatthew G. Knepley PetscInt tri_seg_r[] = {1, 0, 2, 479*412e9a14SMatthew G. Knepley 0, 2, 1, 480*412e9a14SMatthew G. Knepley 2, 1, 0, 481*412e9a14SMatthew G. Knepley 0, 1, 2, 482*412e9a14SMatthew G. Knepley 1, 2, 0, 483*412e9a14SMatthew G. Knepley 2, 0, 1}; 484*412e9a14SMatthew G. Knepley PetscInt tri_tri_o[] = {0, 1, 2, -3, -2, -1, 485*412e9a14SMatthew G. Knepley 2, 0, 1, -2, -1, -3, 486*412e9a14SMatthew G. Knepley 1, 2, 0, -1, -3, -2, 487*412e9a14SMatthew G. Knepley -3, -2, -1, 0, 1, 2, 488*412e9a14SMatthew G. Knepley -1, -3, -2, 1, 2, 0, 489*412e9a14SMatthew G. Knepley -2, -1, -3, 2, 0, 1}; 490*412e9a14SMatthew G. Knepley /* orientation if the replica is the center triangle */ 491*412e9a14SMatthew G. Knepley PetscInt tri_tri_o_c[] = {2, 0, 1, -2, -1, -3, 492*412e9a14SMatthew G. Knepley 1, 2, 0, -1, -3, -2, 493*412e9a14SMatthew G. Knepley 0, 1, 2, -3, -2, -1, 494*412e9a14SMatthew G. Knepley -3, -2, -1, 0, 1, 2, 495*412e9a14SMatthew G. Knepley -1, -3, -2, 1, 2, 0, 496*412e9a14SMatthew G. Knepley -2, -1, -3, 2, 0, 1}; 497*412e9a14SMatthew G. Knepley PetscInt tri_tri_r[] = {0, 2, 1, 3, 498*412e9a14SMatthew G. Knepley 2, 1, 0, 3, 499*412e9a14SMatthew G. Knepley 1, 0, 2, 3, 500*412e9a14SMatthew G. Knepley 0, 1, 2, 3, 501*412e9a14SMatthew G. Knepley 1, 2, 0, 3, 502*412e9a14SMatthew G. Knepley 2, 0, 1, 3}; 503*412e9a14SMatthew G. Knepley PetscInt quad_seg_r[] = {3, 2, 1, 0, 504*412e9a14SMatthew G. Knepley 2, 1, 0, 3, 505*412e9a14SMatthew G. Knepley 1, 0, 3, 2, 506*412e9a14SMatthew G. Knepley 0, 3, 2, 1, 507*412e9a14SMatthew G. Knepley 0, 1, 2, 3, 508*412e9a14SMatthew G. Knepley 1, 2, 3, 0, 509*412e9a14SMatthew G. Knepley 2, 3, 0, 1, 510*412e9a14SMatthew G. Knepley 3, 0, 1, 2}; 511*412e9a14SMatthew G. Knepley PetscInt quad_quad_o[] = { 0, 1, 2, 3, -4, -3, -2, -1, 512*412e9a14SMatthew G. Knepley 4, 0, 1, 2, -3, -2, -1, -4, 513*412e9a14SMatthew G. Knepley 3, 4, 0, 1, -2, -1, -4, -3, 514*412e9a14SMatthew G. Knepley 2, 3, 4, 0, -1, -4, -3, -2, 515*412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 516*412e9a14SMatthew G. Knepley -1, -4, -3, -2, 1, 2, 3, 0, 517*412e9a14SMatthew G. Knepley -2, -1, -4, -3, 2, 3, 0, 1, 518*412e9a14SMatthew G. Knepley -3, -2, -1, -4, 3, 0, 1, 2}; 519*412e9a14SMatthew G. Knepley PetscInt quad_quad_r[] = {0, 3, 2, 1, 520*412e9a14SMatthew G. Knepley 3, 2, 1, 0, 521*412e9a14SMatthew G. Knepley 2, 1, 0, 3, 522*412e9a14SMatthew G. Knepley 1, 0, 3, 2, 523*412e9a14SMatthew G. Knepley 0, 1, 2, 3, 524*412e9a14SMatthew G. Knepley 1, 2, 3, 0, 525*412e9a14SMatthew G. Knepley 2, 3, 0, 1, 526*412e9a14SMatthew G. Knepley 3, 0, 1, 2}; 527*412e9a14SMatthew G. Knepley PetscInt tquad_tquad_o[] = { 0, 1, -2, -1, 528*412e9a14SMatthew G. Knepley 1, 0, -1, -2, 529*412e9a14SMatthew G. Knepley -2, -1, 0, 1, 530*412e9a14SMatthew G. Knepley -1, -2, 1, 0}; 531*412e9a14SMatthew G. Knepley PetscInt tquad_tquad_r[] = {1, 0, 532*412e9a14SMatthew G. Knepley 1, 0, 533*412e9a14SMatthew G. Knepley 0, 1, 534*412e9a14SMatthew G. Knepley 0, 1}; 535*412e9a14SMatthew G. Knepley 536*412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 537*412e9a14SMatthew G. Knepley /* The default is no transformation */ 538*412e9a14SMatthew G. Knepley *rnew = r; 539*412e9a14SMatthew G. Knepley *onew = o; 540*412e9a14SMatthew G. Knepley switch (pct) { 541*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 542*412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_SEGMENT) { 543*412e9a14SMatthew G. Knepley if (po == 0 || po == -1) {*rnew = r; *onew = o;} 544*412e9a14SMatthew G. Knepley else if (po == 1 || po == -2) {*rnew = (r+1)%2; *onew = (o == 0 || o == -1) ? -2 : 0;} 545*412e9a14SMatthew G. Knepley else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid orientation %D for segment", po); 546*412e9a14SMatthew G. Knepley } 547*412e9a14SMatthew G. Knepley break; 548*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 549*412e9a14SMatthew G. Knepley switch (ct) { 550*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 551*412e9a14SMatthew G. Knepley if (o == -1) o = 0; 552*412e9a14SMatthew G. Knepley if (o == -2) o = 1; 553*412e9a14SMatthew G. Knepley *onew = tri_seg_o[(po+3)*2+o]; 554*412e9a14SMatthew G. Knepley *rnew = tri_seg_r[(po+3)*3+r]; 555*412e9a14SMatthew G. Knepley break; 556*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 557*412e9a14SMatthew 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]; 558*412e9a14SMatthew G. Knepley *rnew = tri_tri_r[(po+3)*4+r]; 559*412e9a14SMatthew G. Knepley break; 560*412e9a14SMatthew G. Knepley default: break; 561*412e9a14SMatthew G. Knepley } 562*412e9a14SMatthew G. Knepley break; 563*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 564*412e9a14SMatthew G. Knepley switch (ct) { 565*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 566*412e9a14SMatthew G. Knepley *onew = o; 567*412e9a14SMatthew G. Knepley *rnew = quad_seg_r[(po+4)*4+r]; 568*412e9a14SMatthew G. Knepley break; 569*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 570*412e9a14SMatthew G. Knepley *onew = quad_quad_o[(po+4)*8+o+4]; 571*412e9a14SMatthew G. Knepley *rnew = quad_quad_r[(po+4)*4+r]; 572*412e9a14SMatthew G. Knepley break; 573*412e9a14SMatthew G. Knepley default: break; 574*412e9a14SMatthew G. Knepley } 575*412e9a14SMatthew G. Knepley break; 576*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 577*412e9a14SMatthew G. Knepley switch (ct) { 578*412e9a14SMatthew G. Knepley /* DM_POLYTOPE_POINT_PRISM_TENSOR does not change */ 579*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 580*412e9a14SMatthew G. Knepley *onew = tquad_tquad_o[(po+2)*4+o+2]; 581*412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 582*412e9a14SMatthew G. Knepley break; 583*412e9a14SMatthew G. Knepley default: break; 584*412e9a14SMatthew G. Knepley } 585*412e9a14SMatthew G. Knepley break; 586*412e9a14SMatthew G. Knepley default: break; 587*412e9a14SMatthew G. Knepley } 588*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 589*412e9a14SMatthew G. Knepley } 590*412e9a14SMatthew G. Knepley 591*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_ToHex(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 592*412e9a14SMatthew G. Knepley { 593*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 594*412e9a14SMatthew G. Knepley /* We shift any input orientation in order to make it non-negative 595*412e9a14SMatthew 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) 596*412e9a14SMatthew G. Knepley The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 597*412e9a14SMatthew G. Knepley Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 598*412e9a14SMatthew G. Knepley */ 599*412e9a14SMatthew G. Knepley PetscInt tri_seg_o[] = {0, -2, 600*412e9a14SMatthew G. Knepley 0, -2, 601*412e9a14SMatthew G. Knepley 0, -2, 602*412e9a14SMatthew G. Knepley 0, -2, 603*412e9a14SMatthew G. Knepley 0, -2, 604*412e9a14SMatthew G. Knepley 0, -2}; 605*412e9a14SMatthew G. Knepley PetscInt tri_seg_r[] = {2, 1, 0, 606*412e9a14SMatthew G. Knepley 1, 0, 2, 607*412e9a14SMatthew G. Knepley 0, 2, 1, 608*412e9a14SMatthew G. Knepley 0, 1, 2, 609*412e9a14SMatthew G. Knepley 1, 2, 0, 610*412e9a14SMatthew G. Knepley 2, 0, 1}; 611*412e9a14SMatthew G. Knepley PetscInt tri_tri_o[] = {0, 1, 2, 3, -4, -3, -2, -1, 612*412e9a14SMatthew G. Knepley 3, 0, 1, 2, -3, -2, -1, -4, 613*412e9a14SMatthew G. Knepley 1, 2, 3, 0, -1, -4, -3, -2, 614*412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 615*412e9a14SMatthew G. Knepley -1, -4, -3, -2, 1, 2, 3, 0, 616*412e9a14SMatthew G. Knepley -3, -2, -1, -4, 3, 0, 1, 2}; 617*412e9a14SMatthew G. Knepley PetscInt tri_tri_r[] = {0, 2, 1, 618*412e9a14SMatthew G. Knepley 2, 1, 0, 619*412e9a14SMatthew G. Knepley 1, 0, 2, 620*412e9a14SMatthew G. Knepley 0, 1, 2, 621*412e9a14SMatthew G. Knepley 1, 2, 0, 622*412e9a14SMatthew G. Knepley 2, 0, 1}; 623*412e9a14SMatthew G. Knepley PetscInt tquad_tquad_o[] = { 0, 1, -2, -1, 624*412e9a14SMatthew G. Knepley 1, 0, -1, -2, 625*412e9a14SMatthew G. Knepley -2, -1, 0, 1, 626*412e9a14SMatthew G. Knepley -1, -2, 1, 0}; 627*412e9a14SMatthew G. Knepley PetscInt tquad_tquad_r[] = {1, 0, 628*412e9a14SMatthew G. Knepley 1, 0, 629*412e9a14SMatthew G. Knepley 0, 1, 630*412e9a14SMatthew G. Knepley 0, 1}; 631*412e9a14SMatthew G. Knepley PetscInt tquad_quad_o[] = {-2, -1, -4, -3, 2, 3, 0, 1, 632*412e9a14SMatthew G. Knepley 1, 2, 3, 0, -1, -4, -3, -2, 633*412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 634*412e9a14SMatthew G. Knepley 1, 0, 3, 2, -3, -4, -1, -2}; 635*412e9a14SMatthew G. Knepley 636*412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 637*412e9a14SMatthew G. Knepley *rnew = r; 638*412e9a14SMatthew G. Knepley *onew = o; 639*412e9a14SMatthew G. Knepley switch (pct) { 640*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 641*412e9a14SMatthew G. Knepley switch (ct) { 642*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 643*412e9a14SMatthew G. Knepley if (o == -1) o = 0; 644*412e9a14SMatthew G. Knepley if (o == -2) o = 1; 645*412e9a14SMatthew G. Knepley *onew = tri_seg_o[(po+3)*2+o]; 646*412e9a14SMatthew G. Knepley *rnew = tri_seg_r[(po+3)*3+r]; 647*412e9a14SMatthew G. Knepley break; 648*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 649*412e9a14SMatthew G. Knepley *onew = tri_tri_o[(po+3)*8+o+4]; 650*412e9a14SMatthew G. Knepley /* TODO See sheet, for fixing po == 1 and 2 */ 651*412e9a14SMatthew G. Knepley if (po == 2 && r == 2 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+3)%4)+4]; 652*412e9a14SMatthew G. Knepley if (po == 2 && r == 2 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+5)%4)]; 653*412e9a14SMatthew G. Knepley if (po == 1 && r == 1 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+1)%4)+4]; 654*412e9a14SMatthew G. Knepley if (po == 1 && r == 1 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+7)%4)]; 655*412e9a14SMatthew G. Knepley if (po == -1 && r == 2 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+3)%4)+4]; 656*412e9a14SMatthew G. Knepley if (po == -1 && r == 2 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+5)%4)]; 657*412e9a14SMatthew G. Knepley if (po == -2 && r == 1 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+1)%4)+4]; 658*412e9a14SMatthew G. Knepley if (po == -2 && r == 1 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+7)%4)]; 659*412e9a14SMatthew G. Knepley *rnew = tri_tri_r[(po+3)*3+r]; 660*412e9a14SMatthew G. Knepley break; 661*412e9a14SMatthew G. Knepley default: break; 662*412e9a14SMatthew G. Knepley } 663*412e9a14SMatthew G. Knepley break; 664*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 665*412e9a14SMatthew G. Knepley switch (ct) { 666*412e9a14SMatthew G. Knepley /* DM_POLYTOPE_POINT_PRISM_TENSOR does not change */ 667*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 668*412e9a14SMatthew G. Knepley *onew = tquad_tquad_o[(po+2)*4+o+2]; 669*412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 670*412e9a14SMatthew G. Knepley break; 671*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 672*412e9a14SMatthew G. Knepley *onew = tquad_quad_o[(po+2)*8+o+4]; 673*412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 674*412e9a14SMatthew G. Knepley break; 675*412e9a14SMatthew G. Knepley default: break; 676*412e9a14SMatthew G. Knepley } 677*412e9a14SMatthew G. Knepley break; 678*412e9a14SMatthew G. Knepley default: 679*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapSubcells_Regular(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 680*412e9a14SMatthew G. Knepley } 681*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 682*412e9a14SMatthew G. Knepley } 683*412e9a14SMatthew G. Knepley 684*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 685*412e9a14SMatthew G. Knepley { 686*412e9a14SMatthew G. Knepley return DMPlexCellRefinerMapSubcells_Regular(cr, pct, po, ct, r, o, rnew, onew); 687*412e9a14SMatthew G. Knepley } 688*412e9a14SMatthew G. Knepley 689*412e9a14SMatthew G. Knepley /*@ 690*412e9a14SMatthew G. Knepley DMPlexCellRefinerRefine - Return a description of the refinement for a given cell type 691*412e9a14SMatthew G. Knepley 692*412e9a14SMatthew G. Knepley Input Parameter: 693*412e9a14SMatthew G. Knepley . source - The cell type for a source point 694*412e9a14SMatthew G. Knepley 695*412e9a14SMatthew G. Knepley Output Parameter: 696*412e9a14SMatthew G. Knepley + Nt - The number of cell types generated by refinement 697*412e9a14SMatthew G. Knepley . target - The cell types generated 698*412e9a14SMatthew G. Knepley . size - The number of subcells of each type, ordered by dimension 699*412e9a14SMatthew G. Knepley . cone - A list of the faces for each subcell of the same type as source 700*412e9a14SMatthew G. Knepley - ornt - A list of the face orientations for each subcell of the same type as source 701*412e9a14SMatthew G. Knepley 702*412e9a14SMatthew G. Knepley Note: The cone array gives the cone of each subcell listed by the first three outputs. For the each cone point, we 703*412e9a14SMatthew G. Knepley need the cell type, point identifier, and orientation within the subcell. The orientation is with respect to the canonical 704*412e9a14SMatthew G. Knepley division (described in these outputs) of the cell in the original mesh. The point identifier is given by 705*412e9a14SMatthew G. Knepley $ the number of cones to be taken, or 0 for the current cell 706*412e9a14SMatthew G. Knepley $ the cell cone point number at each level from which it is subdivided 707*412e9a14SMatthew G. Knepley $ the replica number r of the subdivision. 708*412e9a14SMatthew G. Knepley The orientation is with respect to the canonical cone orientation. For example, the prescription for edge division is 709*412e9a14SMatthew G. Knepley $ Nt = 2 710*412e9a14SMatthew G. Knepley $ target = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT} 711*412e9a14SMatthew G. Knepley $ size = {1, 2} 712*412e9a14SMatthew 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} 713*412e9a14SMatthew G. Knepley $ ornt = { 0, 0, 0, 0} 714*412e9a14SMatthew G. Knepley 715*412e9a14SMatthew G. Knepley Level: developer 716*412e9a14SMatthew G. Knepley 717*412e9a14SMatthew G. Knepley .seealso: DMPlexRefineToHex() 718*412e9a14SMatthew G. Knepley @*/ 719*412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerRefine(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 720*412e9a14SMatthew G. Knepley { 721*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 722*412e9a14SMatthew G. Knepley 723*412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 724*412e9a14SMatthew G. Knepley ierr = (*cr->ops->refine)(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 725*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 726*412e9a14SMatthew G. Knepley } 727*412e9a14SMatthew G. Knepley 728*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Regular(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 729*412e9a14SMatthew G. Knepley { 730*412e9a14SMatthew G. Knepley /* All vertices remain in the refined mesh */ 731*412e9a14SMatthew G. Knepley static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT}; 732*412e9a14SMatthew G. Knepley static PetscInt vertexS[] = {1}; 733*412e9a14SMatthew G. Knepley static PetscInt vertexC[] = {0}; 734*412e9a14SMatthew G. Knepley static PetscInt vertexO[] = {0}; 735*412e9a14SMatthew G. Knepley /* Split all edges with a new vertex, making two new 2 edges 736*412e9a14SMatthew G. Knepley 0--0--0--1--1 737*412e9a14SMatthew G. Knepley */ 738*412e9a14SMatthew G. Knepley static DMPolytopeType edgeT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT}; 739*412e9a14SMatthew G. Knepley static PetscInt edgeS[] = {1, 2}; 740*412e9a14SMatthew 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}; 741*412e9a14SMatthew G. Knepley static PetscInt edgeO[] = { 0, 0, 0, 0}; 742*412e9a14SMatthew G. Knepley /* Do not split tensor edges */ 743*412e9a14SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR}; 744*412e9a14SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 745*412e9a14SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 746*412e9a14SMatthew G. Knepley static PetscInt tedgeO[] = { 0, 0}; 747*412e9a14SMatthew G. Knepley /* Add 3 edges inside every triangle, making 4 new triangles. 74875d3a19aSMatthew G. Knepley 2 74975d3a19aSMatthew G. Knepley |\ 75075d3a19aSMatthew G. Knepley | \ 75175d3a19aSMatthew G. Knepley | \ 752*412e9a14SMatthew G. Knepley 0 1 75375d3a19aSMatthew G. Knepley | C \ 75475d3a19aSMatthew G. Knepley | \ 75575d3a19aSMatthew G. Knepley | \ 75675d3a19aSMatthew G. Knepley 2---1---1 75775d3a19aSMatthew G. Knepley |\ D / \ 758*412e9a14SMatthew G. Knepley 1 2 0 0 75975d3a19aSMatthew G. Knepley |A \ / B \ 760*412e9a14SMatthew G. Knepley 0-0-0---1---1 76175d3a19aSMatthew G. Knepley */ 762*412e9a14SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE}; 763*412e9a14SMatthew G. Knepley static PetscInt triS[] = {3, 4}; 764*412e9a14SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 765*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 1, 2, 0, 766*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 0, 0, 767*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 768*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 0, 769*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, 770*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2}; 771*412e9a14SMatthew G. Knepley static PetscInt triO[] = {0, 0, 772*412e9a14SMatthew G. Knepley 0, 0, 773*412e9a14SMatthew G. Knepley 0, 0, 774*412e9a14SMatthew G. Knepley 0, -2, 0, 775*412e9a14SMatthew G. Knepley 0, 0, -2, 776*412e9a14SMatthew G. Knepley -2, 0, 0, 777*412e9a14SMatthew G. Knepley 0, 0, 0}; 778*412e9a14SMatthew G. Knepley /* Add a vertex in the center of each quadrilateral, and 4 edges inside, making 4 new quads. 779*412e9a14SMatthew G. Knepley 3----1----2----0----2 780*412e9a14SMatthew G. Knepley | | | 781*412e9a14SMatthew G. Knepley 0 D 2 C 1 782*412e9a14SMatthew G. Knepley | | | 783*412e9a14SMatthew G. Knepley 3----3----0----1----1 784*412e9a14SMatthew G. Knepley | | | 785*412e9a14SMatthew G. Knepley 1 A 0 B 0 786*412e9a14SMatthew G. Knepley | | | 787*412e9a14SMatthew G. Knepley 0----0----0----1----1 788*412e9a14SMatthew G. Knepley */ 789*412e9a14SMatthew G. Knepley static DMPolytopeType quadT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 790*412e9a14SMatthew G. Knepley static PetscInt quadS[] = {1, 4, 4}; 791*412e9a14SMatthew G. Knepley static PetscInt quadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 792*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 793*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 794*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 795*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, 796*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 797*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, 798*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0}; 799*412e9a14SMatthew G. Knepley static PetscInt quadO[] = {0, 0, 800*412e9a14SMatthew G. Knepley 0, 0, 801*412e9a14SMatthew G. Knepley 0, 0, 802*412e9a14SMatthew G. Knepley 0, 0, 803*412e9a14SMatthew G. Knepley 0, 0, -2, 0, 804*412e9a14SMatthew G. Knepley 0, 0, 0, -2, 805*412e9a14SMatthew G. Knepley -2, 0, 0, 0, 806*412e9a14SMatthew G. Knepley 0, -2, 0, 0}; 807*412e9a14SMatthew G. Knepley /* Add 1 edge inside every tensor quad, making 2 new tensor quads 808*412e9a14SMatthew G. Knepley 2----2----1----3----3 809*412e9a14SMatthew G. Knepley | | | 810*412e9a14SMatthew G. Knepley | | | 811*412e9a14SMatthew G. Knepley | | | 812*412e9a14SMatthew G. Knepley 4 A 6 B 5 813*412e9a14SMatthew G. Knepley | | | 814*412e9a14SMatthew G. Knepley | | | 815*412e9a14SMatthew G. Knepley | | | 816*412e9a14SMatthew G. Knepley 0----0----0----1----1 817*412e9a14SMatthew G. Knepley */ 818*412e9a14SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR}; 819*412e9a14SMatthew G. Knepley static PetscInt tquadS[] = {1, 2}; 820*412e9a14SMatthew G. Knepley static PetscInt tquadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 821*412e9a14SMatthew 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, 822*412e9a14SMatthew 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}; 823*412e9a14SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 824*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 825*412e9a14SMatthew G. Knepley 0, 0, 0, 0}; 826*412e9a14SMatthew G. Knepley /* Add 1 edge and 8 triangles inside every cell, making 8 new tets 827*412e9a14SMatthew 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 828*412e9a14SMatthew 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] 829*412e9a14SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 830*412e9a14SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 831*412e9a14SMatthew G. Knepley The first four tets just cut off the corners, using the replica notation for new vertices, 832*412e9a14SMatthew G. Knepley [v0, (e0, 0), (e2, 0), (e3, 0)] 833*412e9a14SMatthew G. Knepley [(e0, 0), v1, (e1, 0), (e4, 0)] 834*412e9a14SMatthew G. Knepley [(e2, 0), (e1, 0), v2, (e5, 0)] 835*412e9a14SMatthew G. Knepley [(e3, 0), (e4, 0), (e5, 0), v3 ] 836*412e9a14SMatthew G. Knepley The next four tets match a vertex to the newly created faces from cutting off those first tets. 837*412e9a14SMatthew G. Knepley [(e2, 0), (e3, 0), (e0, 0), (e5, 0)] 838*412e9a14SMatthew G. Knepley [(e4, 0), (e1, 0), (e0, 0), (e5, 0)] 839*412e9a14SMatthew G. Knepley [(e5, 0), (e0, 0), (e2, 0), (e1, 0)] 840*412e9a14SMatthew G. Knepley [(e5, 0), (e0, 0), (e4, 0), (e3, 0)] 841*412e9a14SMatthew 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 842*412e9a14SMatthew G. Knepley [(e2, 0), (e0, 0), (e3, 0)] 843*412e9a14SMatthew G. Knepley [(e0, 0), (e1, 0), (e4, 0)] 844*412e9a14SMatthew G. Knepley [(e2, 0), (e5, 0), (e1, 0)] 845*412e9a14SMatthew G. Knepley [(e3, 0), (e4, 0), (e5, 0)] 846*412e9a14SMatthew G. Knepley The next four, from the second group of tets, are 847*412e9a14SMatthew G. Knepley [(e2, 0), (e0, 0), (e5, 0)] 848*412e9a14SMatthew G. Knepley [(e4, 0), (e0, 0), (e5, 0)] 849*412e9a14SMatthew G. Knepley [(e0, 0), (e1, 0), (e5, 0)] 850*412e9a14SMatthew G. Knepley [(e5, 0), (e3, 0), (e0, 0)] 851*412e9a14SMatthew G. Knepley I could write a program to generate these orientations by comparing the faces from GetRawFaces() with my existing table. 852*412e9a14SMatthew G. Knepley */ 853*412e9a14SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON}; 854*412e9a14SMatthew G. Knepley static PetscInt tetS[] = {1, 8, 8}; 855*412e9a14SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 2, 2, 1, 0, 856*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 2, 2, 857*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 1, 1, 858*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 1, 0, 1, 859*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 2, 1, 860*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0, 861*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, 862*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 0, 863*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0, 0, 864*412e9a14SMatthew 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, 865*412e9a14SMatthew 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, 866*412e9a14SMatthew 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, 867*412e9a14SMatthew 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, 868*412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 2, 3, DM_POLYTOPE_TRIANGLE, 0, 4, DM_POLYTOPE_TRIANGLE, 0, 7, 869*412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 1, 3, 3, DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 6, 870*412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 4, DM_POLYTOPE_TRIANGLE, 0, 6, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 1, 0, 3, 871*412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 7, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 1, 1, 3}; 872*412e9a14SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 873*412e9a14SMatthew G. Knepley 0, 0, 0, 874*412e9a14SMatthew G. Knepley 0, 0, 0, 875*412e9a14SMatthew G. Knepley 0, 0, 0, 876*412e9a14SMatthew G. Knepley 0, 0, 0, 877*412e9a14SMatthew G. Knepley 0, 0, -2, 878*412e9a14SMatthew G. Knepley 0, 0, -2, 879*412e9a14SMatthew G. Knepley 0, -2, -2, 880*412e9a14SMatthew G. Knepley 0, -2, 0, 881*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 882*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 883*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 884*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 885*412e9a14SMatthew G. Knepley -3, 0, 0, -2, 886*412e9a14SMatthew G. Knepley -2, 1, 0, 0, 887*412e9a14SMatthew G. Knepley -2, -2, -1, 2, 888*412e9a14SMatthew G. Knepley -2, 0, -2, 1}; 889*412e9a14SMatthew G. Knepley /* Add a vertex in the center of each cell, add 6 edges and 12 quads inside every cell, making 8 new hexes 890*412e9a14SMatthew 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 891*412e9a14SMatthew G. Knepley [v0, v1, v2, v3] f0 bottom 892*412e9a14SMatthew G. Knepley [v4, v5, v6, v7] f1 top 893*412e9a14SMatthew G. Knepley [v0, v3, v5, v4] f2 front 894*412e9a14SMatthew G. Knepley [v2, v1, v7, v6] f3 back 895*412e9a14SMatthew G. Knepley [v3, v2, v6, v5] f4 right 896*412e9a14SMatthew G. Knepley [v0, v4, v7, v1] f5 left 897*412e9a14SMatthew G. Knepley The eight hexes are divided into four on the bottom, and four on the top, 898*412e9a14SMatthew G. Knepley [v0, (e0, 0), (f0, 0), (e3, 0), (e9, 0), (f2, 0), (c0, 0), (f5, 0)] 899*412e9a14SMatthew G. Knepley [(e0, 0), v1, (e1, 0), (f0, 0), (f5, 0), (c0, 0), (f3, 0), (e10, 0)] 900*412e9a14SMatthew G. Knepley [(f0, 0), (e1, 0), v2, (e2, 0), (c0, 0), (f4, 0), (e11, 0), (f3, 0)] 901*412e9a14SMatthew G. Knepley [(e3, 0), (f0, 0), (e2, 0), v3, (f2, 0), (e8, 0), (f4, 0), (c0, 0)] 902*412e9a14SMatthew G. Knepley [(e9, 0), (f5, 0), (c0, 0), (f2, 0), v4, (e4, 0), (f1, 0), (e7, 0)] 903*412e9a14SMatthew G. Knepley [(f2, 0), (c0, 0), (f4, 0), (e8, 0), (e4, 0), v5, (e5, 0), (f1, 0)] 904*412e9a14SMatthew G. Knepley [(c0, 0), (f3, 0), (e11, 0), (f4, 0), (f1, 0), (e5, 0), v6, (e6, 0)] 905*412e9a14SMatthew G. Knepley [(f5, 0), (e10, 0), (f3, 0), (c0, 0), (e7, 0), (f1, 0), (e6, 0), v7] 906*412e9a14SMatthew 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, 907*412e9a14SMatthew G. Knepley [(e9, 0), (f2, 0), (c0, 0), (f5, 0)] 908*412e9a14SMatthew G. Knepley [(f5, 0), (c0, 0), (f3, 0), (e10, 0)] 909*412e9a14SMatthew G. Knepley [(c0, 0), (f4, 0), (e11, 0), (f3, 0)] 910*412e9a14SMatthew G. Knepley [(f2, 0), (e8, 0), (f4, 0), (c0, 0)] 911*412e9a14SMatthew G. Knepley and on the x-z plane, 912*412e9a14SMatthew G. Knepley [(f0, 0), (e0, 0), (f5, 0), (c0, 0)] 913*412e9a14SMatthew G. Knepley [(c0, 0), (f5, 0), (e7, 0), (f1, 0)] 914*412e9a14SMatthew G. Knepley [(f4, 0), (c0, 0), (f1, 0), (e5, 0)] 915*412e9a14SMatthew G. Knepley [(e2, 0), (f0, 0), (c0, 0), (f4, 0)] 916*412e9a14SMatthew G. Knepley and on the y-z plane, 917*412e9a14SMatthew G. Knepley [(e3, 0), (f2, 0), (c0, 0), (f0, 0)] 918*412e9a14SMatthew G. Knepley [(f2, 0), (e4, 0), (f1, 0), (c0, 0)] 919*412e9a14SMatthew G. Knepley [(c0, 0), (f1, 0), (e6, 0), (f3, 0)] 920*412e9a14SMatthew G. Knepley [(f0, 0), (c0, 0), (f3, 0), (e1, 0)] 921*412e9a14SMatthew G. Knepley */ 922*412e9a14SMatthew G. Knepley static DMPolytopeType hexT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 923*412e9a14SMatthew G. Knepley static PetscInt hexS[] = {1, 6, 12, 8}; 924*412e9a14SMatthew G. Knepley static PetscInt hexC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 925*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 926*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 927*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 928*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0, 929*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 5, 0, DM_POLYTOPE_POINT, 0, 0, 930*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 1, 5, 0, 931*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 5, 2, 932*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 3, 933*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 2, 934*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 5, 3, DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 0, 0, 935*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 1, 5, 1, DM_POLYTOPE_SEGMENT, 1, 1, 3, DM_POLYTOPE_SEGMENT, 0, 1, 936*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 4, 2, 937*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 0, 938*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 0, 3, 939*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 940*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 3, 941*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1, 942*412e9a14SMatthew 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, 943*412e9a14SMatthew 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, 944*412e9a14SMatthew 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, 945*412e9a14SMatthew 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, 946*412e9a14SMatthew 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, 947*412e9a14SMatthew 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, 948*412e9a14SMatthew 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, 949*412e9a14SMatthew 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}; 950*412e9a14SMatthew G. Knepley static PetscInt hexO[] = {0, 0, 951*412e9a14SMatthew G. Knepley 0, 0, 952*412e9a14SMatthew G. Knepley 0, 0, 953*412e9a14SMatthew G. Knepley 0, 0, 954*412e9a14SMatthew G. Knepley 0, 0, 955*412e9a14SMatthew G. Knepley 0, 0, 956*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 957*412e9a14SMatthew G. Knepley 0, -2, -2, 0, 958*412e9a14SMatthew G. Knepley -2, -2, 0, 0, 959*412e9a14SMatthew G. Knepley -2, 0, 0, -2, 960*412e9a14SMatthew G. Knepley -2, 0, 0, -2, 961*412e9a14SMatthew G. Knepley -2, -2, 0, 0, 962*412e9a14SMatthew G. Knepley 0, -2, -2, 0, 963*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 964*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 965*412e9a14SMatthew G. Knepley -2, 0, 0, -2, 966*412e9a14SMatthew G. Knepley -2, -2, 0, 0, 967*412e9a14SMatthew G. Knepley 0, -2, -2, 0, 968*412e9a14SMatthew G. Knepley 0, 0, 0, 0, -4, 0, 969*412e9a14SMatthew G. Knepley 0, 0, -1, 0, -4, 0, 970*412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 971*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 972*412e9a14SMatthew G. Knepley -4, 0, 0, 0, -4, 0, 973*412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, 0, 974*412e9a14SMatthew G. Knepley -4, 0, -1, 0, 0, 0, 975*412e9a14SMatthew G. Knepley -4, 0, -1, 0, -4, 0}; 976*412e9a14SMatthew G. Knepley /* Add 3 quads inside every triangular prism, making 4 new prisms. */ 977*412e9a14SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_TRI_PRISM}; 978*412e9a14SMatthew G. Knepley static PetscInt tripS[] = {3, 4, 6, 8}; 979*412e9a14SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 3, 0, 980*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 1, 4, 0, 981*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 1, 2, 0, 982*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 4, 1, 983*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 0, 984*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, 985*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 986*412e9a14SMatthew 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, 987*412e9a14SMatthew 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, 988*412e9a14SMatthew 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, 989*412e9a14SMatthew 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, 990*412e9a14SMatthew 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, 991*412e9a14SMatthew 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, 992*412e9a14SMatthew 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, 993*412e9a14SMatthew 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, 994*412e9a14SMatthew 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, 995*412e9a14SMatthew 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, 996*412e9a14SMatthew 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, 997*412e9a14SMatthew 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, 998*412e9a14SMatthew 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, 999*412e9a14SMatthew 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}; 1000*412e9a14SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 1001*412e9a14SMatthew G. Knepley 0, 0, 1002*412e9a14SMatthew G. Knepley 0, 0, 1003*412e9a14SMatthew G. Knepley 0, -2, -2, 1004*412e9a14SMatthew G. Knepley -2, 0, -2, 1005*412e9a14SMatthew G. Knepley -2, -2, 0, 1006*412e9a14SMatthew G. Knepley 0, 0, 0, 1007*412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1008*412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1009*412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1010*412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1011*412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1012*412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1013*412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1014*412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1015*412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 1016*412e9a14SMatthew G. Knepley 2, 0, 0, 0, 0, 1017*412e9a14SMatthew G. Knepley -3, 0, 0, -1, 0, 1018*412e9a14SMatthew G. Knepley -3, 0, 0, 0, -1, 1019*412e9a14SMatthew G. Knepley -3, 0, -1, 0, 0, 1020*412e9a14SMatthew G. Knepley -3, 0, 0, 0, 0}; 1021*412e9a14SMatthew G. Knepley /* Add 3 tensor quads inside every tensor triangular prism, making 4 new prisms. 1022*412e9a14SMatthew G. Knepley 2 1023*412e9a14SMatthew G. Knepley |\ 1024*412e9a14SMatthew G. Knepley | \ 1025*412e9a14SMatthew G. Knepley | \ 1026*412e9a14SMatthew G. Knepley 0---1 102775d3a19aSMatthew G. Knepley 1028*412e9a14SMatthew G. Knepley 2 102975d3a19aSMatthew G. Knepley 1030*412e9a14SMatthew G. Knepley 0 1 103175d3a19aSMatthew G. Knepley 1032*412e9a14SMatthew G. Knepley 2 1033*412e9a14SMatthew G. Knepley |\ 1034*412e9a14SMatthew G. Knepley | \ 1035*412e9a14SMatthew G. Knepley | \ 1036*412e9a14SMatthew G. Knepley 0---1 1037*412e9a14SMatthew G. Knepley */ 1038*412e9a14SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_TRI_PRISM_TENSOR}; 1039*412e9a14SMatthew G. Knepley static PetscInt ttripS[] = {3, 4}; 1040*412e9a14SMatthew 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, 1041*412e9a14SMatthew 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, 1042*412e9a14SMatthew 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, 1043*412e9a14SMatthew 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, 1044*412e9a14SMatthew 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, 1045*412e9a14SMatthew 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, 1046*412e9a14SMatthew 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}; 1047*412e9a14SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 0, 0, 1048*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1049*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1050*412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1051*412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1052*412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 1053*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0}; 1054*412e9a14SMatthew G. Knepley /* Add 1 edge and 4 tensor quads inside every tensor quad prism, making 4 new prisms. */ 1055*412e9a14SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1056*412e9a14SMatthew G. Knepley static PetscInt tquadpS[] = {1, 4, 4}; 1057*412e9a14SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1058*412e9a14SMatthew 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, 1059*412e9a14SMatthew 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, 1060*412e9a14SMatthew 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, 1061*412e9a14SMatthew 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, 1062*412e9a14SMatthew 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, 1063*412e9a14SMatthew 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, 1064*412e9a14SMatthew 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, 1065*412e9a14SMatthew 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}; 1066*412e9a14SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 1067*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1068*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1069*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1070*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1071*412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1072*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1073*412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1074*412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 107575d3a19aSMatthew G. Knepley 1076*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1077*412e9a14SMatthew G. Knepley switch (source) { 1078*412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break; 1079*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nt = 2; *target = edgeT; *size = edgeS; *cone = edgeC; *ornt = edgeO; break; 1080*412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 1081*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 2; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1082*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nt = 3; *target = quadT; *size = quadS; *cone = quadC; *ornt = quadO; break; 1083*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 2; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 1084*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 3; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1085*412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nt = 4; *target = hexT; *size = hexS; *cone = hexC; *ornt = hexO; break; 1086*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1087*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 2; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 1088*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 1089*412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1090*412e9a14SMatthew G. Knepley } 1091*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1092*412e9a14SMatthew G. Knepley } 109375d3a19aSMatthew G. Knepley 1094*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_ToHex(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1095*412e9a14SMatthew G. Knepley { 1096*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1097*412e9a14SMatthew G. Knepley /* Change tensor edges to segments */ 1098*412e9a14SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_SEGMENT}; 1099*412e9a14SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 1100*412e9a14SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 1101*412e9a14SMatthew G. Knepley static PetscInt tedgeO[] = { 0, 0}; 1102*412e9a14SMatthew G. Knepley /* Add 1 vertex, 3 edges inside every triangle, making 3 new quadrilaterals. 1103e5337592SStefano Zampini 2 1104e5337592SStefano Zampini |\ 1105e5337592SStefano Zampini | \ 1106e5337592SStefano Zampini | \ 1107e5337592SStefano Zampini | \ 1108*412e9a14SMatthew G. Knepley 0 1 1109*412e9a14SMatthew G. Knepley | \ 1110e5337592SStefano Zampini | \ 1111e5337592SStefano Zampini 2 1 1112e5337592SStefano Zampini |\ / \ 1113e5337592SStefano Zampini | 2 1 \ 1114e5337592SStefano Zampini | \ / \ 1115*412e9a14SMatthew G. Knepley 1 | 0 1116e5337592SStefano Zampini | 0 \ 1117e5337592SStefano Zampini | | \ 1118*412e9a14SMatthew G. Knepley | | \ 1119*412e9a14SMatthew G. Knepley 0-0-0-----1-----1 1120e5337592SStefano Zampini */ 1121*412e9a14SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 1122*412e9a14SMatthew G. Knepley static PetscInt triS[] = {1, 3, 3}; 1123*412e9a14SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1124*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1125*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1126*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 1127*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1128*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0}; 1129*412e9a14SMatthew G. Knepley static PetscInt triO[] = {0, 0, 1130*412e9a14SMatthew G. Knepley 0, 0, 1131*412e9a14SMatthew G. Knepley 0, 0, 1132*412e9a14SMatthew G. Knepley 0, 0, -2, 0, 1133*412e9a14SMatthew G. Knepley 0, 0, 0, -2, 1134*412e9a14SMatthew G. Knepley 0, -2, 0, 0}; 1135*412e9a14SMatthew G. Knepley /* Add 1 edge inside every tensor quad, making 2 new quadrilaterals 1136*412e9a14SMatthew G. Knepley 2----2----1----3----3 11374330a3fcSStefano Zampini | | | 11384330a3fcSStefano Zampini | | | 11394330a3fcSStefano Zampini | | | 1140*412e9a14SMatthew G. Knepley 4 A 6 B 5 11414330a3fcSStefano Zampini | | | 1142*412e9a14SMatthew G. Knepley | | | 1143*412e9a14SMatthew G. Knepley | | | 1144*412e9a14SMatthew G. Knepley 0----0----0----1----1 11454330a3fcSStefano Zampini */ 1146*412e9a14SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 1147*412e9a14SMatthew G. Knepley static PetscInt tquadS[] = {1, 2}; 1148*412e9a14SMatthew G. Knepley static PetscInt tquadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1149*412e9a14SMatthew G. Knepley /* TODO Fix these */ 1150*412e9a14SMatthew 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, 1151*412e9a14SMatthew 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}; 1152*412e9a14SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 1153*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1154*412e9a14SMatthew G. Knepley 0, 0, -2, -2}; 1155*412e9a14SMatthew G. Knepley /* Add 6 triangles inside every cell, making 4 new hexs 1156*412e9a14SMatthew G. Knepley TODO: Need different SubcellMap(). Need to make a struct with the function pointers in it 1157*412e9a14SMatthew 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 1158*412e9a14SMatthew 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] 1159*412e9a14SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 1160*412e9a14SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 1161*412e9a14SMatthew G. Knepley We make a new hex in each corner 1162*412e9a14SMatthew G. Knepley [v0, (e0, 0), (f0, 0), (e2, 0), (e3, 0), (f2, 0), (c0, 0), (f1, 0)] 1163*412e9a14SMatthew G. Knepley [v1, (e4, 0), (f3, 0), (e1, 0), (e0, 0), (f0, 0), (c0, 0), (f1, 0)] 1164*412e9a14SMatthew G. Knepley [v2, (e1, 0), (f3, 0), (e5, 0), (e2, 0), (f2, 0), (c0, 0), (f0, 0)] 1165*412e9a14SMatthew G. Knepley [v3, (e4, 0), (f1, 0), (e3, 0), (e5, 0), (f2, 0), (c0, 0), (f3, 0)] 1166*412e9a14SMatthew G. Knepley We create a new face for each edge 1167*412e9a14SMatthew G. Knepley [(e3, 0), (f2, 0), (c0, 0), (f1, 0)] 1168*412e9a14SMatthew G. Knepley [(f0, 0), (e0, 0), (f1, 0), (c0, 0)] 1169*412e9a14SMatthew G. Knepley [(e2, 0), (f0, 0), (c0, 0), (f2, 0)] 1170*412e9a14SMatthew G. Knepley [(f3, 0), (e4, 0), (f1, 0), (c0, 0)] 1171*412e9a14SMatthew G. Knepley [(e1, 0), (f3, 0), (c0, 0), (f0, 0)] 1172*412e9a14SMatthew G. Knepley [(e5, 0), (f3, 0), (c0, 0), (f2, 0)] 1173*412e9a14SMatthew 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. 117475d3a19aSMatthew G. Knepley */ 1175*412e9a14SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1176*412e9a14SMatthew G. Knepley static PetscInt tetS[] = {1, 4, 6, 4}; 1177*412e9a14SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1178*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1179*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1180*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1181*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, 1182*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1183*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1184*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 3, 1185*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1, 1186*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 1187*412e9a14SMatthew 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, 1188*412e9a14SMatthew 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, 1189*412e9a14SMatthew 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, 1190*412e9a14SMatthew 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}; 1191*412e9a14SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 1192*412e9a14SMatthew G. Knepley 0, 0, 1193*412e9a14SMatthew G. Knepley 0, 0, 1194*412e9a14SMatthew G. Knepley 0, 0, 1195*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1196*412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1197*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1198*412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1199*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1200*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1201*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 1202*412e9a14SMatthew G. Knepley 1, -1, 1, 0, 0, 3, 1203*412e9a14SMatthew G. Knepley 0, -4, 1, -1, 0, 3, 1204*412e9a14SMatthew G. Knepley 1, -4, 3, -2, -4, 3}; 1205*412e9a14SMatthew G. Knepley /* Add 3 quads inside every triangular prism, making 4 new prisms. */ 1206*412e9a14SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1207*412e9a14SMatthew G. Knepley static PetscInt tripS[] = {1, 5, 9, 6}; 1208*412e9a14SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1209*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1210*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1211*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1212*412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0, 1213*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 1, 1214*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, 1215*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, 1216*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1217*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 0, 1218*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 0, 1219*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 2, 1220*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 3, 2, 1221*412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 4, 2, 1222*412e9a14SMatthew 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, 1223*412e9a14SMatthew 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, 1224*412e9a14SMatthew 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, 1225*412e9a14SMatthew 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, 1226*412e9a14SMatthew 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, 1227*412e9a14SMatthew 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}; 1228*412e9a14SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 1229*412e9a14SMatthew G. Knepley 0, 0, 1230*412e9a14SMatthew G. Knepley 0, 0, 1231*412e9a14SMatthew G. Knepley 0, 0, 1232*412e9a14SMatthew G. Knepley 0, 0, 1233*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1234*412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1235*412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1236*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1237*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1238*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1239*412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1240*412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1241*412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1242*412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1, 1243*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -4, 1244*412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1, 1245*412e9a14SMatthew G. Knepley -4, 0, 0, -1, 0, 1, 1246*412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, -4, 1247*412e9a14SMatthew G. Knepley -4, 0, 0, 0, -1, 1}; 1248*412e9a14SMatthew G. Knepley /* Add 3 tensor quads inside every tensor triangular prism, making 4 new tensor triangular prisms. 1249*412e9a14SMatthew G. Knepley 2 1250*412e9a14SMatthew G. Knepley |\ 1251*412e9a14SMatthew G. Knepley | \ 1252*412e9a14SMatthew G. Knepley | \ 1253*412e9a14SMatthew G. Knepley 0---1 125475d3a19aSMatthew G. Knepley 1255*412e9a14SMatthew G. Knepley 2 125675d3a19aSMatthew G. Knepley 1257*412e9a14SMatthew G. Knepley 0 1 125875d3a19aSMatthew G. Knepley 1259*412e9a14SMatthew G. Knepley 2 1260*412e9a14SMatthew G. Knepley |\ 1261*412e9a14SMatthew G. Knepley | \ 1262*412e9a14SMatthew G. Knepley | \ 1263*412e9a14SMatthew G. Knepley 0---1 126475d3a19aSMatthew G. Knepley */ 1265*412e9a14SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1266*412e9a14SMatthew G. Knepley static PetscInt ttripS[] = {1, 3, 3}; 1267*412e9a14SMatthew G. Knepley static PetscInt ttripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1268*412e9a14SMatthew 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, 1269*412e9a14SMatthew 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, 1270*412e9a14SMatthew 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, 1271*412e9a14SMatthew 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, 1272*412e9a14SMatthew 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, 1273*412e9a14SMatthew 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}; 1274*412e9a14SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 1275*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1276*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1277*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1278*412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1279*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1280*412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 1281*412e9a14SMatthew G. Knepley /* TODO Add 3 quads inside every tensor triangular prism, making 4 new triangular prisms. 1282*412e9a14SMatthew G. Knepley 2 1283*412e9a14SMatthew G. Knepley |\ 1284*412e9a14SMatthew G. Knepley | \ 1285*412e9a14SMatthew G. Knepley | \ 1286*412e9a14SMatthew G. Knepley 0---1 128775d3a19aSMatthew G. Knepley 1288*412e9a14SMatthew G. Knepley 2 128975d3a19aSMatthew G. Knepley 1290*412e9a14SMatthew G. Knepley 0 1 129175d3a19aSMatthew G. Knepley 1292*412e9a14SMatthew G. Knepley 2 1293*412e9a14SMatthew G. Knepley |\ 1294*412e9a14SMatthew G. Knepley | \ 1295*412e9a14SMatthew G. Knepley | \ 1296*412e9a14SMatthew G. Knepley 0---1 1297a97b51b8SMatthew G. Knepley */ 1298*412e9a14SMatthew G. Knepley static DMPolytopeType ctripT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1299*412e9a14SMatthew G. Knepley static PetscInt ctripS[] = {1, 3, 3}; 1300*412e9a14SMatthew G. Knepley static PetscInt ctripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1301*412e9a14SMatthew 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, 1302*412e9a14SMatthew 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, 1303*412e9a14SMatthew 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, 1304*412e9a14SMatthew 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, 1305*412e9a14SMatthew 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, 1306*412e9a14SMatthew 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}; 1307*412e9a14SMatthew G. Knepley static PetscInt ctripO[] = {0, 0, 1308*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1309*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1310*412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1311*412e9a14SMatthew G. Knepley -4, 0, 0, -1, 0, 1, 1312*412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, -4, 1313*412e9a14SMatthew G. Knepley -4, 0, 0, 0, -1, 1}; 1314*412e9a14SMatthew G. Knepley /* Add 1 edge and 4 quads inside every tensor quad prism, making 4 new hexahedra. */ 1315*412e9a14SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1316*412e9a14SMatthew G. Knepley static PetscInt tquadpS[] = {1, 4, 4}; 1317*412e9a14SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1318*412e9a14SMatthew 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, 1319*412e9a14SMatthew 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, 1320*412e9a14SMatthew 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, 1321*412e9a14SMatthew 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, 1322*412e9a14SMatthew 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, 1323*412e9a14SMatthew 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, 1324*412e9a14SMatthew 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, 1325*412e9a14SMatthew 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}; 1326*412e9a14SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 1327*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1328*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1329*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1330*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1331*412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1332*412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1333*412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1334*412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 1335*412e9a14SMatthew G. Knepley PetscBool convertTensor = PETSC_TRUE; 1336a97b51b8SMatthew G. Knepley 1337*412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 1338*412e9a14SMatthew G. Knepley if (convertTensor) { 1339*412e9a14SMatthew G. Knepley switch (source) { 1340*412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1341*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1342*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1343*412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1344*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1345a97b51b8SMatthew G. Knepley break; 1346*412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 1347*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 2; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 1348*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 3; *target = ctripT; *size = ctripS; *cone = ctripC; *ornt = ctripO; break; 1349*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 1350*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1351*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1352*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1353*412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1354b5da9499SMatthew G. Knepley } 1355b5da9499SMatthew G. Knepley } else { 1356*412e9a14SMatthew G. Knepley switch (source) { 1357*412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1358*412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1359*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1360*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1361*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1362*412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1363*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1364*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1365b5da9499SMatthew G. Knepley break; 1366*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1367*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1368*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1369*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 3; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 1370*412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 137127fcede3SMatthew G. Knepley } 137275d3a19aSMatthew G. Knepley } 137375d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 137475d3a19aSMatthew G. Knepley } 137575d3a19aSMatthew G. Knepley 1376*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 137775d3a19aSMatthew G. Knepley { 1378*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1379*412e9a14SMatthew G. Knepley 1380*412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 1381*412e9a14SMatthew G. Knepley switch (source) { 1382*412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1383*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1384*412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1385*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1386*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 1387*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1388*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 1389*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1390*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1391*412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1392*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1393*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1394*412e9a14SMatthew G. Knepley break; 1395*412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1396*412e9a14SMatthew G. Knepley } 1397*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1398*412e9a14SMatthew G. Knepley } 1399*412e9a14SMatthew G. Knepley 1400*412e9a14SMatthew G. Knepley static PetscErrorCode CellRefinerCreateOffset_Internal(DMPlexCellRefiner cr, PetscInt ctOrder[], PetscInt ctStart[], PetscInt **offset) 1401*412e9a14SMatthew G. Knepley { 1402*412e9a14SMatthew G. Knepley PetscInt c, cN, *off; 140375d3a19aSMatthew G. Knepley PetscErrorCode ierr; 140475d3a19aSMatthew G. Knepley 140575d3a19aSMatthew G. Knepley PetscFunctionBegin; 1406*412e9a14SMatthew G. Knepley ierr = PetscCalloc1(DM_NUM_POLYTOPES*DM_NUM_POLYTOPES, &off);CHKERRQ(ierr); 1407*412e9a14SMatthew G. Knepley for (c = DM_POLYTOPE_POINT; c < DM_NUM_POLYTOPES; ++c) { 1408*412e9a14SMatthew G. Knepley const DMPolytopeType ct = (DMPolytopeType) c; 1409*412e9a14SMatthew G. Knepley for (cN = DM_POLYTOPE_POINT; cN < DM_NUM_POLYTOPES; ++cN) { 1410*412e9a14SMatthew G. Knepley const DMPolytopeType ctNew = (DMPolytopeType) cN; 1411*412e9a14SMatthew G. Knepley DMPolytopeType *rct; 1412*412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 1413*412e9a14SMatthew G. Knepley PetscInt Nct, n, i; 1414*412e9a14SMatthew G. Knepley 1415*412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ct) < 0 || DMPolytopeTypeGetDim(ctNew) < 0) {off[ct*DM_NUM_POLYTOPES+ctNew] = -1; break;} 1416*412e9a14SMatthew G. Knepley off[ct*DM_NUM_POLYTOPES+ctNew] = 0; 1417*412e9a14SMatthew G. Knepley for (i = DM_POLYTOPE_POINT; i < DM_NUM_POLYTOPES; ++i) { 1418*412e9a14SMatthew G. Knepley const DMPolytopeType ict = (DMPolytopeType) ctOrder[i]; 1419*412e9a14SMatthew G. Knepley const DMPolytopeType ictn = (DMPolytopeType) ctOrder[i+1]; 1420*412e9a14SMatthew G. Knepley 1421*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ict, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 1422*412e9a14SMatthew G. Knepley if (ict == ct) { 1423*412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) break; 1424*412e9a14SMatthew G. Knepley if (n == Nct) off[ct*DM_NUM_POLYTOPES+ctNew] = -1; 1425*412e9a14SMatthew G. Knepley break; 1426*412e9a14SMatthew G. Knepley } 1427*412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) off[ct*DM_NUM_POLYTOPES+ctNew] += (ctStart[ictn]-ctStart[ict]) * rsize[n]; 1428*412e9a14SMatthew G. Knepley } 1429*412e9a14SMatthew G. Knepley } 1430*412e9a14SMatthew G. Knepley } 1431*412e9a14SMatthew G. Knepley *offset = off; 1432*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1433*412e9a14SMatthew G. Knepley } 1434*412e9a14SMatthew G. Knepley 1435*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetStarts(DMPlexCellRefiner cr, const PetscInt ctStart[], const PetscInt ctStartNew[]) 1436*412e9a14SMatthew G. Knepley { 1437*412e9a14SMatthew G. Knepley const PetscInt ctSize = DM_NUM_POLYTOPES+1; 1438*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1439*412e9a14SMatthew G. Knepley 1440*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1441*412e9a14SMatthew G. Knepley if (cr->setupcalled) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_ARG_WRONGSTATE, "Must call this function before DMPlexCellRefinerSetUp()"); 1442*412e9a14SMatthew G. Knepley ierr = PetscCalloc2(ctSize, &cr->ctStart, ctSize, &cr->ctStartNew);CHKERRQ(ierr); 1443*412e9a14SMatthew G. Knepley ierr = PetscArraycpy(cr->ctStart, ctStart, ctSize);CHKERRQ(ierr); 1444*412e9a14SMatthew G. Knepley ierr = PetscArraycpy(cr->ctStartNew, ctStartNew, ctSize);CHKERRQ(ierr); 1445*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1446*412e9a14SMatthew G. Knepley } 1447*412e9a14SMatthew G. Knepley 1448*412e9a14SMatthew G. Knepley /* Construct cell type order since we must loop over cell types in depth order */ 1449*412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCreateCellTypeOrder_Internal(DMPolytopeType ctCell, PetscInt *ctOrder[], PetscInt *ctOrderInv[]) 1450*412e9a14SMatthew G. Knepley { 1451*412e9a14SMatthew G. Knepley PetscInt *ctO, *ctOInv; 1452*412e9a14SMatthew G. Knepley PetscInt c, d, off = 0; 1453*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1454*412e9a14SMatthew G. Knepley 1455*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1456*412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctO, DM_NUM_POLYTOPES+1, &ctOInv);CHKERRQ(ierr); 1457*412e9a14SMatthew G. Knepley for (d = 3; d >= DMPolytopeTypeGetDim(ctCell); --d) { 1458*412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1459*412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue; 1460*412e9a14SMatthew G. Knepley ctO[off++] = c; 1461*412e9a14SMatthew G. Knepley } 1462*412e9a14SMatthew G. Knepley } 1463*412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ctCell) != 0) { 1464*412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1465*412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != 0) continue; 1466*412e9a14SMatthew G. Knepley ctO[off++] = c; 1467*412e9a14SMatthew G. Knepley } 1468*412e9a14SMatthew G. Knepley } 1469*412e9a14SMatthew G. Knepley for (d = DMPolytopeTypeGetDim(ctCell)-1; d > 0; --d) { 1470*412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1471*412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue; 1472*412e9a14SMatthew G. Knepley ctO[off++] = c; 1473*412e9a14SMatthew G. Knepley } 1474*412e9a14SMatthew G. Knepley } 1475*412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1476*412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) >= 0) continue; 1477*412e9a14SMatthew G. Knepley ctO[off++] = c; 1478*412e9a14SMatthew G. Knepley } 1479*412e9a14SMatthew G. Knepley if (off != DM_NUM_POLYTOPES+1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid offset %D for cell type order", off); 1480*412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1481*412e9a14SMatthew G. Knepley ctOInv[ctO[c]] = c; 1482*412e9a14SMatthew G. Knepley } 1483*412e9a14SMatthew G. Knepley *ctOrder = ctO; 1484*412e9a14SMatthew G. Knepley *ctOrderInv = ctOInv; 1485*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1486*412e9a14SMatthew G. Knepley } 1487*412e9a14SMatthew G. Knepley 1488*412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerSetUp(DMPlexCellRefiner cr) 1489*412e9a14SMatthew G. Knepley { 1490*412e9a14SMatthew G. Knepley DM dm = cr->dm; 1491*412e9a14SMatthew G. Knepley DMPolytopeType ctCell; 1492*412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p, c; 1493*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1494*412e9a14SMatthew G. Knepley 1495*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1496*412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 1497*412e9a14SMatthew G. Knepley if (cr->setupcalled) PetscFunctionReturn(0); 1498*412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 1499*412e9a14SMatthew G. Knepley if (pEnd > pStart) {ierr = DMPlexGetCellType(dm, 0, &ctCell);CHKERRQ(ierr);} 1500*412e9a14SMatthew G. Knepley else { 1501*412e9a14SMatthew G. Knepley PetscInt dim; 1502a57030b0SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1503*412e9a14SMatthew G. Knepley switch (dim) { 1504*412e9a14SMatthew G. Knepley case 0: ctCell = DM_POLYTOPE_POINT;break; 1505*412e9a14SMatthew G. Knepley case 1: ctCell = DM_POLYTOPE_SEGMENT;break; 1506*412e9a14SMatthew G. Knepley case 2: ctCell = DM_POLYTOPE_TRIANGLE;break; 1507*412e9a14SMatthew G. Knepley case 3: ctCell = DM_POLYTOPE_TETRAHEDRON;break; 1508*412e9a14SMatthew G. Knepley default: ctCell = DM_POLYTOPE_TETRAHEDRON; 1509*412e9a14SMatthew G. Knepley } 1510*412e9a14SMatthew G. Knepley } 1511*412e9a14SMatthew G. Knepley ierr = DMPlexCreateCellTypeOrder_Internal(ctCell, &cr->ctOrder, &cr->ctOrderInv);CHKERRQ(ierr); 1512*412e9a14SMatthew G. Knepley /* Construct sizes and offsets for each cell type */ 1513*412e9a14SMatthew G. Knepley if (!cr->ctStart) { 1514*412e9a14SMatthew G. Knepley PetscInt *ctS, *ctSN, *ctC, *ctCN; 1515*412e9a14SMatthew G. Knepley 1516*412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctS, DM_NUM_POLYTOPES+1, &ctSN);CHKERRQ(ierr); 1517*412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctC, DM_NUM_POLYTOPES+1, &ctCN);CHKERRQ(ierr); 1518*412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 1519*412e9a14SMatthew G. Knepley DMPolytopeType ct; 1520*412e9a14SMatthew G. Knepley DMPolytopeType *rct; 1521*412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 1522*412e9a14SMatthew G. Knepley PetscInt Nct, n; 1523*412e9a14SMatthew G. Knepley 1524*412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 1525*412e9a14SMatthew G. Knepley if ((PetscInt) ct < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No cell type for point %D", p); 1526*412e9a14SMatthew G. Knepley ++ctC[ct]; 1527*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 1528*412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) ctCN[rct[n]] += rsize[n]; 1529*412e9a14SMatthew G. Knepley } 1530*412e9a14SMatthew G. Knepley for (c = 0; c < DM_NUM_POLYTOPES; ++c) { 1531*412e9a14SMatthew G. Knepley const PetscInt ct = cr->ctOrder[c]; 1532*412e9a14SMatthew G. Knepley const PetscInt ctn = cr->ctOrder[c+1]; 1533*412e9a14SMatthew G. Knepley 1534*412e9a14SMatthew G. Knepley ctS[ctn] = ctS[ct] + ctC[ct]; 1535*412e9a14SMatthew G. Knepley ctSN[ctn] = ctSN[ct] + ctCN[ct]; 1536*412e9a14SMatthew G. Knepley } 1537*412e9a14SMatthew G. Knepley ierr = PetscFree2(ctC, ctCN);CHKERRQ(ierr); 1538*412e9a14SMatthew G. Knepley cr->ctStart = ctS; 1539*412e9a14SMatthew G. Knepley cr->ctStartNew = ctSN; 1540*412e9a14SMatthew G. Knepley } 1541*412e9a14SMatthew G. Knepley ierr = CellRefinerCreateOffset_Internal(cr, cr->ctOrder, cr->ctStart, &cr->offset);CHKERRQ(ierr); 1542*412e9a14SMatthew G. Knepley cr->setupcalled = PETSC_TRUE; 1543*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1544*412e9a14SMatthew G. Knepley } 1545*412e9a14SMatthew G. Knepley 1546*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView_Ascii(DMPlexCellRefiner cr, PetscViewer v) 1547*412e9a14SMatthew G. Knepley { 1548*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1549*412e9a14SMatthew G. Knepley 1550*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1551*412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(v, "Cell Refiner: %s\n", DMPlexCellRefinerTypes[cr->type]);CHKERRQ(ierr); 1552*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1553*412e9a14SMatthew G. Knepley } 1554*412e9a14SMatthew G. Knepley 1555*412e9a14SMatthew G. Knepley /* 1556*412e9a14SMatthew G. Knepley DMPlexCellRefinerView - Views a DMPlexCellRefiner object 1557*412e9a14SMatthew G. Knepley 1558*412e9a14SMatthew G. Knepley Collective on cr 1559*412e9a14SMatthew G. Knepley 1560*412e9a14SMatthew G. Knepley Input Parameters: 1561*412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 1562*412e9a14SMatthew G. Knepley - viewer - The PetscViewer object 1563*412e9a14SMatthew G. Knepley 1564*412e9a14SMatthew G. Knepley Level: beginner 1565*412e9a14SMatthew G. Knepley 1566*412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerCreate() 1567*412e9a14SMatthew G. Knepley */ 1568*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView(DMPlexCellRefiner cr, PetscViewer viewer) 1569*412e9a14SMatthew G. Knepley { 1570*412e9a14SMatthew G. Knepley PetscBool iascii; 1571*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1572*412e9a14SMatthew G. Knepley 1573*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1574*412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 1575*412e9a14SMatthew G. Knepley if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1576*412e9a14SMatthew G. Knepley if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) cr), &viewer);CHKERRQ(ierr);} 1577*412e9a14SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1578*412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1579*412e9a14SMatthew G. Knepley if (iascii) {ierr = DMPlexCellRefinerView_Ascii(cr, viewer);CHKERRQ(ierr);} 1580*412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1581*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1582*412e9a14SMatthew G. Knepley } 1583*412e9a14SMatthew G. Knepley 1584*412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerDestroy(DMPlexCellRefiner *cr) 1585*412e9a14SMatthew G. Knepley { 1586*412e9a14SMatthew G. Knepley PetscInt c; 1587*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1588*412e9a14SMatthew G. Knepley 1589*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1590*412e9a14SMatthew G. Knepley if (!*cr) PetscFunctionReturn(0); 1591*412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(*cr, DM_CLASSID, 1); 1592*412e9a14SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) (*cr)->dm);CHKERRQ(ierr); 1593*412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->ctOrder, (*cr)->ctOrderInv);CHKERRQ(ierr); 1594*412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->ctStart, (*cr)->ctStartNew);CHKERRQ(ierr); 1595*412e9a14SMatthew G. Knepley ierr = PetscFree((*cr)->offset);CHKERRQ(ierr); 1596*412e9a14SMatthew G. Knepley for (c = 0; c < DM_NUM_POLYTOPES; ++c) { 1597*412e9a14SMatthew G. Knepley ierr = PetscFEDestroy(&(*cr)->coordFE[c]);CHKERRQ(ierr); 1598*412e9a14SMatthew G. Knepley ierr = PetscFEGeomDestroy(&(*cr)->refGeom[c]);CHKERRQ(ierr); 1599*412e9a14SMatthew G. Knepley } 1600*412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->coordFE, (*cr)->refGeom);CHKERRQ(ierr); 1601*412e9a14SMatthew G. Knepley ierr = PetscHeaderDestroy(cr);CHKERRQ(ierr); 1602*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1603*412e9a14SMatthew G. Knepley } 1604*412e9a14SMatthew G. Knepley 1605*412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerCreate(DM dm, DMPlexCellRefiner *cr) 1606*412e9a14SMatthew G. Knepley { 1607*412e9a14SMatthew G. Knepley DMPlexCellRefiner tmp; 1608*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1609*412e9a14SMatthew G. Knepley 1610*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1611*412e9a14SMatthew G. Knepley PetscValidPointer(cr, 2); 1612*412e9a14SMatthew G. Knepley *cr = NULL; 1613*412e9a14SMatthew G. Knepley ierr = PetscHeaderCreate(tmp, DM_CLASSID, "DMPlexCellRefiner", "Cell Refiner", "DMPlexCellRefiner", PETSC_COMM_SELF, DMPlexCellRefinerDestroy, DMPlexCellRefinerView);CHKERRQ(ierr); 1614*412e9a14SMatthew G. Knepley tmp->setupcalled = PETSC_FALSE; 1615*412e9a14SMatthew G. Knepley 1616*412e9a14SMatthew G. Knepley tmp->dm = dm; 1617*412e9a14SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); 1618*412e9a14SMatthew G. Knepley ierr = DMPlexGetCellRefinerType(dm, &tmp->type);CHKERRQ(ierr); 1619*412e9a14SMatthew G. Knepley switch (tmp->type) { 1620*412e9a14SMatthew G. Knepley case REFINER_REGULAR: 1621*412e9a14SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_Regular; 1622*412e9a14SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_Regular; 1623*412e9a14SMatthew G. Knepley tmp->ops->getcellvertices = DMPlexCellRefinerGetCellVertices_Regular; 1624*412e9a14SMatthew G. Knepley tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_Regular; 1625*412e9a14SMatthew G. Knepley tmp->ops->getaffinetransforms = DMPlexCellRefinerGetAffineTransforms_Regular; 1626*412e9a14SMatthew G. Knepley tmp->ops->getaffinefacetransforms = DMPlexCellRefinerGetAffineFaceTransforms_Regular; 1627*412e9a14SMatthew G. Knepley break; 1628*412e9a14SMatthew G. Knepley case REFINER_TO_HEX: 1629*412e9a14SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_ToHex; 1630*412e9a14SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToHex; 1631*412e9a14SMatthew G. Knepley tmp->ops->getcellvertices = DMPlexCellRefinerGetCellVertices_ToHex; 1632*412e9a14SMatthew G. Knepley tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_ToHex; 1633*412e9a14SMatthew G. Knepley break; 1634*412e9a14SMatthew G. Knepley case REFINER_TO_SIMPLEX: 1635*412e9a14SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_ToSimplex; 1636*412e9a14SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToSimplex; 1637*412e9a14SMatthew G. Knepley break; 1638*412e9a14SMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Invalid cell refiner type %s", DMPlexCellRefinerTypes[tmp->type]); 1639*412e9a14SMatthew G. Knepley } 1640*412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES, &tmp->coordFE, DM_NUM_POLYTOPES, &tmp->refGeom);CHKERRQ(ierr); 1641*412e9a14SMatthew G. Knepley *cr = tmp; 1642*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1643*412e9a14SMatthew G. Knepley } 1644*412e9a14SMatthew G. Knepley 1645*412e9a14SMatthew G. Knepley /*@ 1646*412e9a14SMatthew G. Knepley DMPlexCellRefinerGetAffineTransforms - Gets the affine map from the reference cell to each subcell 1647*412e9a14SMatthew G. Knepley 1648*412e9a14SMatthew G. Knepley Input Parameters: 1649*412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 1650*412e9a14SMatthew G. Knepley - ct - The cell type 1651*412e9a14SMatthew G. Knepley 1652*412e9a14SMatthew G. Knepley Output Parameters: 1653*412e9a14SMatthew G. Knepley + Nc - The number of subcells produced from this cell type 1654*412e9a14SMatthew G. Knepley . v0 - The translation of the first vertex for each subcell 1655*412e9a14SMatthew G. Knepley . J - The Jacobian for each subcell (map from reference cell to subcell) 1656*412e9a14SMatthew G. Knepley - invJ - The inverse Jacobian for each subcell 1657*412e9a14SMatthew G. Knepley 1658*412e9a14SMatthew G. Knepley Level: developer 1659*412e9a14SMatthew G. Knepley 1660*412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineFaceTransforms(), Create() 1661*412e9a14SMatthew G. Knepley @*/ 1662*412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[]) 1663*412e9a14SMatthew G. Knepley { 1664*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1665*412e9a14SMatthew G. Knepley 1666*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1667*412e9a14SMatthew G. Knepley if (!cr->ops->getaffinetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine transforms from this refiner"); 1668*412e9a14SMatthew G. Knepley ierr = (*cr->ops->getaffinetransforms)(cr, ct, Nc, v0, J, invJ);CHKERRQ(ierr); 1669*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1670*412e9a14SMatthew G. Knepley } 1671*412e9a14SMatthew G. Knepley 1672*412e9a14SMatthew G. Knepley /*@ 1673*412e9a14SMatthew G. Knepley DMPlexCellRefinerGetAffineFaceTransforms - Gets the affine map from the reference face cell to each face in the given cell 1674*412e9a14SMatthew G. Knepley 1675*412e9a14SMatthew G. Knepley Input Parameters: 1676*412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 1677*412e9a14SMatthew G. Knepley - ct - The cell type 1678*412e9a14SMatthew G. Knepley 1679*412e9a14SMatthew G. Knepley Output Parameters: 1680*412e9a14SMatthew G. Knepley + Nf - The number of faces for this cell type 1681*412e9a14SMatthew G. Knepley . v0 - The translation of the first vertex for each face 1682*412e9a14SMatthew G. Knepley . J - The Jacobian for each face (map from original cell to subcell) 1683*412e9a14SMatthew G. Knepley . invJ - The inverse Jacobian for each face 1684*412e9a14SMatthew G. Knepley - detJ - The determinant of the Jacobian for each face 1685*412e9a14SMatthew G. Knepley 1686*412e9a14SMatthew G. Knepley Note: The Jacobian and inverse Jacboian will be rectangular, and the inverse is really a generalized inverse. 1687*412e9a14SMatthew G. Knepley 1688*412e9a14SMatthew G. Knepley Level: developer 1689*412e9a14SMatthew G. Knepley 1690*412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineTransforms(), Create() 1691*412e9a14SMatthew G. Knepley @*/ 1692*412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[]) 1693*412e9a14SMatthew G. Knepley { 1694*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1695*412e9a14SMatthew G. Knepley 1696*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1697*412e9a14SMatthew G. Knepley if (!cr->ops->getaffinefacetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine face transforms from this refiner"); 1698*412e9a14SMatthew G. Knepley ierr = (*cr->ops->getaffinefacetransforms)(cr, ct, Nf, v0, J, invJ, detJ);CHKERRQ(ierr); 1699*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1700*412e9a14SMatthew G. Knepley } 1701*412e9a14SMatthew G. Knepley 1702*412e9a14SMatthew G. Knepley /* Numbering regularly refined meshes 1703*412e9a14SMatthew G. Knepley 1704*412e9a14SMatthew G. Knepley We want the numbering of the new mesh to respect the same depth stratification as the old mesh. We first compute 1705*412e9a14SMatthew G. Knepley the number of new points at each depth. This means that offsets for each depth can be computed, making no assumptions 1706*412e9a14SMatthew G. Knepley about the order of different cell types. 1707*412e9a14SMatthew G. Knepley 1708*412e9a14SMatthew G. Knepley However, when we want to order different depth strata, it will be very useful to make assumptions about contiguous 1709*412e9a14SMatthew G. Knepley numbering of different cell types, especially if we want to compute new numberings without communication. Therefore, we 1710*412e9a14SMatthew G. Knepley will require that cells are numbering contiguously for each cell type, and that those blocks come in the same order as 1711*412e9a14SMatthew G. Knepley the cell type enumeration within a given depth stratum. 1712*412e9a14SMatthew G. Knepley 1713*412e9a14SMatthew 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 1714*412e9a14SMatthew G. Knepley start at the new depth offset, run through all prior cell types incrementing by the total addition from that type, then 1715*412e9a14SMatthew G. Knepley offset by the old cell type number and replica number for the insertion. 1716*412e9a14SMatthew G. Knepley */ 1717*412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetNewPoint(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType ctNew, PetscInt p, PetscInt r, PetscInt *pNew) 1718*412e9a14SMatthew G. Knepley { 1719*412e9a14SMatthew G. Knepley DMPolytopeType *rct; 1720*412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 1721*412e9a14SMatthew G. Knepley PetscInt Nct, n; 1722*412e9a14SMatthew G. Knepley PetscInt off = cr->offset[ct*DM_NUM_POLYTOPES+ctNew]; 1723*412e9a14SMatthew G. Knepley PetscInt ctS = cr->ctStart[ct], ctE = cr->ctStart[cr->ctOrder[cr->ctOrderInv[ct]+1]]; 1724*412e9a14SMatthew G. Knepley PetscInt ctSN = cr->ctStartNew[ctNew], ctEN = cr->ctStartNew[cr->ctOrder[cr->ctOrderInv[ctNew]+1]]; 1725*412e9a14SMatthew G. Knepley PetscInt newp = ctSN; 1726*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1727*412e9a14SMatthew G. Knepley 1728*412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 1729*412e9a14SMatthew 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); 1730*412e9a14SMatthew 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]); 1731*412e9a14SMatthew G. Knepley 1732*412e9a14SMatthew G. Knepley newp += off; 1733*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 1734*412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 1735*412e9a14SMatthew G. Knepley if (rct[n] == ctNew) { 1736*412e9a14SMatthew G. Knepley if (rsize[n] && r >= rsize[n]) 1737*412e9a14SMatthew 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]); 1738*412e9a14SMatthew G. Knepley newp += (p - ctS) * rsize[n] + r; 1739*412e9a14SMatthew G. Knepley break; 1740*412e9a14SMatthew G. Knepley } 1741*412e9a14SMatthew G. Knepley } 1742*412e9a14SMatthew G. Knepley 1743*412e9a14SMatthew 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); 1744*412e9a14SMatthew G. Knepley *pNew = newp; 1745*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1746*412e9a14SMatthew G. Knepley } 1747*412e9a14SMatthew G. Knepley 1748*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetConeSizes(DMPlexCellRefiner cr, DM rdm) 1749*412e9a14SMatthew G. Knepley { 1750*412e9a14SMatthew G. Knepley DM dm = cr->dm; 1751*412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p, pNew; 1752*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1753*412e9a14SMatthew G. Knepley 1754*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1755*412e9a14SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 1756*412e9a14SMatthew G. Knepley ierr = DMCreateLabel(rdm, "celltype");CHKERRQ(ierr); 1757*412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 1758*412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 1759*412e9a14SMatthew G. Knepley DMPolytopeType ct; 1760*412e9a14SMatthew G. Knepley DMPolytopeType *rct; 1761*412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 1762*412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 1763*412e9a14SMatthew G. Knepley 1764*412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 1765*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 1766*412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 1767*412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 1768*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 1769*412e9a14SMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, pNew, DMPolytopeTypeGetConeSize(rct[n]));CHKERRQ(ierr); 1770*412e9a14SMatthew G. Knepley ierr = DMPlexSetCellType(rdm, pNew, rct[n]);CHKERRQ(ierr); 1771*412e9a14SMatthew G. Knepley } 1772*412e9a14SMatthew G. Knepley } 1773*412e9a14SMatthew G. Knepley } 1774*412e9a14SMatthew G. Knepley { 1775*412e9a14SMatthew G. Knepley DMLabel ctLabel; 1776*412e9a14SMatthew G. Knepley DM_Plex *plex = (DM_Plex *) rdm->data; 1777*412e9a14SMatthew G. Knepley 1778*412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(rdm, &ctLabel);CHKERRQ(ierr); 1779*412e9a14SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) ctLabel, &plex->celltypeState);CHKERRQ(ierr); 1780*412e9a14SMatthew G. Knepley } 1781*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1782*412e9a14SMatthew G. Knepley } 1783*412e9a14SMatthew G. Knepley 1784*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCones(DMPlexCellRefiner cr, DM rdm) 1785*412e9a14SMatthew G. Knepley { 1786*412e9a14SMatthew G. Knepley DM dm = cr->dm; 1787*412e9a14SMatthew G. Knepley DMPolytopeType ct; 1788*412e9a14SMatthew G. Knepley PetscInt *coneNew, *orntNew; 1789*412e9a14SMatthew G. Knepley PetscInt maxConeSize = 0, pStart, pEnd, p, pNew; 1790*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1791*412e9a14SMatthew G. Knepley 1792*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1793*412e9a14SMatthew G. Knepley for (p = 0; p < DM_NUM_POLYTOPES; ++p) maxConeSize = PetscMax(maxConeSize, DMPolytopeTypeGetConeSize((DMPolytopeType) p)); 1794*412e9a14SMatthew G. Knepley ierr = PetscMalloc2(maxConeSize, &coneNew, maxConeSize, &orntNew);CHKERRQ(ierr); 1795*412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 1796*412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 1797*412e9a14SMatthew G. Knepley const PetscInt *cone, *ornt; 1798*412e9a14SMatthew G. Knepley PetscInt coff, ooff, c; 1799*412e9a14SMatthew G. Knepley DMPolytopeType *rct; 1800*412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 1801*412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 1802*412e9a14SMatthew G. Knepley 1803*412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 1804*412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 1805*412e9a14SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &ornt);CHKERRQ(ierr); 1806*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 1807*412e9a14SMatthew G. Knepley for (n = 0, coff = 0, ooff = 0; n < Nct; ++n) { 1808*412e9a14SMatthew G. Knepley const DMPolytopeType ctNew = rct[n]; 1809*412e9a14SMatthew G. Knepley const PetscInt csizeNew = DMPolytopeTypeGetConeSize(ctNew); 1810*412e9a14SMatthew G. Knepley 1811*412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 1812*412e9a14SMatthew G. Knepley /* pNew is a subcell produced by subdividing p */ 1813*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 1814*412e9a14SMatthew G. Knepley for (c = 0; c < csizeNew; ++c) { 1815*412e9a14SMatthew G. Knepley PetscInt ppp = -1; /* Parent Parent point: Parent of point pp */ 1816*412e9a14SMatthew G. Knepley PetscInt pp = p; /* Parent point: Point in the original mesh producing new cone point */ 1817*412e9a14SMatthew G. Knepley PetscInt po = 0; /* Orientation of parent point pp in parent parent point ppp */ 1818*412e9a14SMatthew G. Knepley DMPolytopeType pct = ct; /* Parent type: Cell type for parent of new cone point */ 1819*412e9a14SMatthew G. Knepley const PetscInt *pcone = cone; /* Parent cone: Cone of parent point pp */ 1820*412e9a14SMatthew G. Knepley PetscInt pr = -1; /* Replica number of pp that produces new cone point */ 1821*412e9a14SMatthew G. Knepley const DMPolytopeType ft = (DMPolytopeType) rcone[coff++]; /* Cell type for new cone point of pNew */ 1822*412e9a14SMatthew G. Knepley const PetscInt fn = rcone[coff++]; /* Number of cones of p that need to be taken when producing new cone point */ 1823*412e9a14SMatthew G. Knepley PetscInt fo = rornt[ooff++]; /* Orientation of new cone point in pNew */ 1824*412e9a14SMatthew G. Knepley PetscInt lc; 1825*412e9a14SMatthew G. Knepley 1826*412e9a14SMatthew G. Knepley /* Get the type (pct) and point number (pp) of the parent point in the original mesh which produces this cone point */ 1827*412e9a14SMatthew G. Knepley for (lc = 0; lc < fn; ++lc) { 1828*412e9a14SMatthew G. Knepley const PetscInt *ppornt; 1829*412e9a14SMatthew G. Knepley PetscInt pcp; 1830*412e9a14SMatthew G. Knepley 1831*412e9a14SMatthew G. Knepley ierr = DMPolytopeMapCell(pct, po, rcone[coff++], &pcp);CHKERRQ(ierr); 1832*412e9a14SMatthew G. Knepley ppp = pp; 1833*412e9a14SMatthew G. Knepley pp = pcone[pcp]; 1834*412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, pp, &pct);CHKERRQ(ierr); 1835*412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, pp, &pcone);CHKERRQ(ierr); 1836*412e9a14SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, ppp, &ppornt);CHKERRQ(ierr); 1837*412e9a14SMatthew G. Knepley po = ppornt[pcp]; 1838*412e9a14SMatthew G. Knepley } 1839*412e9a14SMatthew G. Knepley pr = rcone[coff++]; 1840*412e9a14SMatthew G. Knepley /* Orientation po of pp maps (pr, fo) -> (pr', fo') */ 1841*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapSubcells(cr, pct, po, ft, pr, fo, &pr, &fo);CHKERRQ(ierr); 1842*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, pct, ft, pp, pr, &coneNew[c]);CHKERRQ(ierr); 1843*412e9a14SMatthew G. Knepley orntNew[c] = fo; 1844*412e9a14SMatthew G. Knepley } 1845*412e9a14SMatthew G. Knepley ierr = DMPlexSetCone(rdm, pNew, coneNew);CHKERRQ(ierr); 1846*412e9a14SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, pNew, orntNew);CHKERRQ(ierr); 1847*412e9a14SMatthew G. Knepley } 1848*412e9a14SMatthew G. Knepley } 1849*412e9a14SMatthew G. Knepley } 1850*412e9a14SMatthew G. Knepley ierr = PetscFree2(coneNew, orntNew);CHKERRQ(ierr); 1851*412e9a14SMatthew G. Knepley ierr = DMPlexSymmetrize(rdm);CHKERRQ(ierr); 1852*412e9a14SMatthew G. Knepley ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 1853*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1854*412e9a14SMatthew G. Knepley } 1855*412e9a14SMatthew G. Knepley 1856*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCoordinateFE(DMPlexCellRefiner cr, DMPolytopeType ct, PetscFE *fe) 1857*412e9a14SMatthew G. Knepley { 1858*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1859*412e9a14SMatthew G. Knepley 1860*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1861*412e9a14SMatthew G. Knepley if (!cr->coordFE[ct]) { 1862*412e9a14SMatthew G. Knepley PetscInt dim, cdim; 1863*412e9a14SMatthew G. Knepley PetscBool isSimplex; 1864*412e9a14SMatthew G. Knepley 1865*412e9a14SMatthew G. Knepley switch (ct) { 1866*412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: dim = 1; isSimplex = PETSC_TRUE; break; 1867*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: dim = 2; isSimplex = PETSC_TRUE; break; 1868*412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: dim = 2; isSimplex = PETSC_FALSE; break; 1869*412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: dim = 3; isSimplex = PETSC_TRUE; break; 1870*412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: dim = 3; isSimplex = PETSC_FALSE; break; 1871*412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No coordinate FE for cell type %s", DMPolytopeTypes[ct]); 1872*412e9a14SMatthew G. Knepley } 1873*412e9a14SMatthew G. Knepley ierr = DMGetCoordinateDim(cr->dm, &cdim);CHKERRQ(ierr); 1874*412e9a14SMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, cdim, isSimplex, 1, PETSC_DETERMINE, &cr->coordFE[ct]);CHKERRQ(ierr); 1875*412e9a14SMatthew G. Knepley { 1876*412e9a14SMatthew G. Knepley PetscDualSpace dsp; 1877*412e9a14SMatthew G. Knepley PetscQuadrature quad; 1878*412e9a14SMatthew G. Knepley DM K; 1879*412e9a14SMatthew G. Knepley PetscFEGeom *cg; 1880*412e9a14SMatthew G. Knepley PetscReal *Xq, *xq, *wq; 1881*412e9a14SMatthew G. Knepley PetscInt Nq, q; 1882*412e9a14SMatthew G. Knepley 1883*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCellVertices(cr, ct, &Nq, &Xq);CHKERRQ(ierr); 1884*412e9a14SMatthew G. Knepley ierr = PetscMalloc1(Nq*cdim, &xq);CHKERRQ(ierr); 1885*412e9a14SMatthew G. Knepley for (q = 0; q < Nq*cdim; ++q) xq[q] = Xq[q]; 1886*412e9a14SMatthew G. Knepley ierr = PetscMalloc1(Nq, &wq);CHKERRQ(ierr); 1887*412e9a14SMatthew G. Knepley for (q = 0; q < Nq; ++q) wq[q] = 1.0; 1888*412e9a14SMatthew G. Knepley ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &quad);CHKERRQ(ierr); 1889*412e9a14SMatthew G. Knepley ierr = PetscQuadratureSetData(quad, dim, 1, Nq, xq, wq);CHKERRQ(ierr); 1890*412e9a14SMatthew G. Knepley ierr = PetscFESetQuadrature(cr->coordFE[ct], quad);CHKERRQ(ierr); 1891*412e9a14SMatthew G. Knepley 1892*412e9a14SMatthew G. Knepley ierr = PetscFEGetDualSpace(cr->coordFE[ct], &dsp);CHKERRQ(ierr); 1893*412e9a14SMatthew G. Knepley ierr = PetscDualSpaceGetDM(dsp, &K);CHKERRQ(ierr); 1894*412e9a14SMatthew G. Knepley ierr = PetscFEGeomCreate(quad, 1, cdim, PETSC_FALSE, &cr->refGeom[ct]);CHKERRQ(ierr); 1895*412e9a14SMatthew G. Knepley cg = cr->refGeom[ct]; 1896*412e9a14SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(K, 0, NULL, cg->v, cg->J, cg->invJ, cg->detJ);CHKERRQ(ierr); 1897*412e9a14SMatthew G. Knepley ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr); 1898*412e9a14SMatthew G. Knepley } 1899*412e9a14SMatthew G. Knepley } 1900*412e9a14SMatthew G. Knepley *fe = cr->coordFE[ct]; 1901*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1902*412e9a14SMatthew G. Knepley } 1903*412e9a14SMatthew G. Knepley 1904*412e9a14SMatthew G. Knepley /* 1905*412e9a14SMatthew G. Knepley DMPlexCellRefinerMapLocalizedCoordinates - Given a cell of type ct with localized coordinates x, we generate localized coordinates xr for subcell r of type rct. 1906*412e9a14SMatthew G. Knepley 1907*412e9a14SMatthew G. Knepley Not collective 1908*412e9a14SMatthew G. Knepley 1909*412e9a14SMatthew G. Knepley Input Parameters: 1910*412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner 1911*412e9a14SMatthew G. Knepley . ct - The type of the parent cell 1912*412e9a14SMatthew G. Knepley . rct - The type of the produced cell 1913*412e9a14SMatthew G. Knepley . r - The index of the produced cell 1914*412e9a14SMatthew G. Knepley - x - The localized coordinates for the parent cell 1915*412e9a14SMatthew G. Knepley 1916*412e9a14SMatthew G. Knepley Output Parameter: 1917*412e9a14SMatthew G. Knepley . xr - The localized coordinates for the produced cell 1918*412e9a14SMatthew G. Knepley 1919*412e9a14SMatthew G. Knepley Level: developer 1920*412e9a14SMatthew G. Knepley 1921*412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerSetCoordinates() 1922*412e9a14SMatthew G. Knepley */ 1923*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapLocalizedCoordinates(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, const PetscScalar x[], PetscScalar xr[]) 1924*412e9a14SMatthew G. Knepley { 1925*412e9a14SMatthew G. Knepley PetscFE fe = NULL; 1926*412e9a14SMatthew G. Knepley PetscInt cdim, Nv, v, *subcellV; 1927*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1928*412e9a14SMatthew G. Knepley 1929*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1930*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCoordinateFE(cr, ct, &fe);CHKERRQ(ierr); 1931*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetSubcellVertices(cr, ct, rct, r, &Nv, &subcellV);CHKERRQ(ierr); 1932*412e9a14SMatthew G. Knepley ierr = PetscFEGetNumComponents(fe, &cdim);CHKERRQ(ierr); 1933*412e9a14SMatthew G. Knepley for (v = 0; v < Nv; ++v) { 1934*412e9a14SMatthew G. Knepley ierr = PetscFEInterpolate_Static(fe, x, cr->refGeom[ct], subcellV[v], &xr[v*cdim]);CHKERRQ(ierr); 1935*412e9a14SMatthew G. Knepley } 1936*412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1937*412e9a14SMatthew G. Knepley } 1938*412e9a14SMatthew G. Knepley 1939*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCoordinates(DMPlexCellRefiner cr, DM rdm) 1940*412e9a14SMatthew G. Knepley { 1941*412e9a14SMatthew G. Knepley DM dm = cr->dm, cdm; 1942*412e9a14SMatthew G. Knepley PetscSection coordSection, coordSectionNew; 1943*412e9a14SMatthew G. Knepley Vec coordsLocal, coordsLocalNew; 1944*412e9a14SMatthew G. Knepley const PetscScalar *coords; 1945*412e9a14SMatthew G. Knepley PetscScalar *coordsNew; 1946*412e9a14SMatthew G. Knepley const DMBoundaryType *bd; 1947*412e9a14SMatthew G. Knepley const PetscReal *maxCell, *L; 1948*412e9a14SMatthew G. Knepley PetscBool isperiodic, localizeVertices = PETSC_FALSE, localizeCells = PETSC_FALSE; 1949*412e9a14SMatthew G. Knepley PetscInt dE, d, cStart, cEnd, c, vStartNew, vEndNew, v, pStart, pEnd, p, ocStart, ocEnd; 1950*412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1951*412e9a14SMatthew G. Knepley 1952*412e9a14SMatthew G. Knepley PetscFunctionBegin; 1953*412e9a14SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 195490b157c4SStefano Zampini ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 195590b157c4SStefano Zampini /* Determine if we need to localize coordinates when generating them */ 1956b9ccc978SStefano Zampini if (isperiodic) { 1957*412e9a14SMatthew G. Knepley localizeVertices = PETSC_TRUE; 1958*412e9a14SMatthew G. Knepley if (!maxCell) { 1959*412e9a14SMatthew G. Knepley PetscBool localized; 1960*412e9a14SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 1961*412e9a14SMatthew G. Knepley if (!localized) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Cannot refine a periodic mesh if coordinates have not been localized"); 1962*412e9a14SMatthew G. Knepley localizeCells = PETSC_TRUE; 1963b9ccc978SStefano Zampini } 1964b9ccc978SStefano Zampini } 1965b9ccc978SStefano Zampini 1966b9ccc978SStefano Zampini ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 1967*412e9a14SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &dE);CHKERRQ(ierr); 1968*412e9a14SMatthew G. Knepley if (maxCell) { 1969*412e9a14SMatthew G. Knepley PetscReal maxCellNew[3]; 1970*412e9a14SMatthew G. Knepley 1971*412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) maxCellNew[d] = maxCell[d]/2.0; 1972*412e9a14SMatthew G. Knepley ierr = DMSetPeriodicity(rdm, isperiodic, maxCellNew, L, bd);CHKERRQ(ierr); 1973*412e9a14SMatthew G. Knepley } else { 1974*412e9a14SMatthew G. Knepley ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 1975*412e9a14SMatthew G. Knepley } 1976b9ccc978SStefano Zampini ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &coordSectionNew);CHKERRQ(ierr); 1977b9ccc978SStefano Zampini ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 1978*412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dE);CHKERRQ(ierr); 1979*412e9a14SMatthew G. Knepley ierr = DMPlexGetDepthStratum(rdm, 0, &vStartNew, &vEndNew);CHKERRQ(ierr); 1980*412e9a14SMatthew G. Knepley if (localizeCells) {ierr = PetscSectionSetChart(coordSectionNew, 0, vEndNew);CHKERRQ(ierr);} 1981*412e9a14SMatthew G. Knepley else {ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vEndNew);CHKERRQ(ierr);} 1982b9ccc978SStefano Zampini 1983*412e9a14SMatthew G. Knepley /* Localization should be inherited */ 1984*412e9a14SMatthew G. Knepley /* Stefano calculates parent cells for each new cell for localization */ 1985*412e9a14SMatthew G. Knepley /* Localized cells need coordinates of closure */ 1986*412e9a14SMatthew G. Knepley for (v = vStartNew; v < vEndNew; ++v) { 1987*412e9a14SMatthew G. Knepley ierr = PetscSectionSetDof(coordSectionNew, v, dE);CHKERRQ(ierr); 1988*412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dE);CHKERRQ(ierr); 1989*412e9a14SMatthew G. Knepley } 1990*412e9a14SMatthew G. Knepley if (localizeCells) { 1991*412e9a14SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1992*412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1993*412e9a14SMatthew G. Knepley PetscInt dof; 199490b157c4SStefano Zampini 1995*412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, c, &dof); CHKERRQ(ierr); 1996*412e9a14SMatthew G. Knepley if (dof) { 1997*412e9a14SMatthew G. Knepley DMPolytopeType ct; 1998*412e9a14SMatthew G. Knepley DMPolytopeType *rct; 1999*412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2000*412e9a14SMatthew G. Knepley PetscInt dim, cNew, Nct, n, r; 200190b157c4SStefano Zampini 2002*412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 2003*412e9a14SMatthew G. Knepley dim = DMPolytopeTypeGetDim(ct); 2004*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2005*412e9a14SMatthew G. Knepley /* This allows for different cell types */ 2006*412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2007*412e9a14SMatthew G. Knepley if (dim != DMPolytopeTypeGetDim(rct[n])) continue; 2008*412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2009*412e9a14SMatthew G. Knepley PetscInt *closure = NULL; 2010*412e9a14SMatthew G. Knepley PetscInt clSize, cl, Nv = 0; 201190b157c4SStefano Zampini 2012*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], c, r, &cNew);CHKERRQ(ierr); 2013*412e9a14SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 2014*412e9a14SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) {if ((closure[cl] >= vStartNew) && (closure[cl] < vEndNew)) ++Nv;} 2015*412e9a14SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 2016*412e9a14SMatthew G. Knepley ierr = PetscSectionSetDof(coordSectionNew, cNew, Nv * dE);CHKERRQ(ierr); 2017*412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSectionNew, cNew, 0, Nv * dE);CHKERRQ(ierr); 20189fc2a3f3SStefano Zampini } 201990b157c4SStefano Zampini } 202090b157c4SStefano Zampini } 2021*412e9a14SMatthew G. Knepley } 202275d3a19aSMatthew G. Knepley } 202375d3a19aSMatthew G. Knepley ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 2024*412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-coarse_dm_view");CHKERRQ(ierr); 202546e270d4SMatthew G. Knepley ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 2026*412e9a14SMatthew G. Knepley { 2027*412e9a14SMatthew G. Knepley VecType vtype; 2028*412e9a14SMatthew G. Knepley PetscInt coordSizeNew, bs; 2029*412e9a14SMatthew G. Knepley const char *name; 2030*412e9a14SMatthew G. Knepley 2031*412e9a14SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); 2032*412e9a14SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordsLocalNew);CHKERRQ(ierr); 203375d3a19aSMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 2034*412e9a14SMatthew G. Knepley ierr = VecSetSizes(coordsLocalNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 2035*412e9a14SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) coordsLocal, &name);CHKERRQ(ierr); 2036*412e9a14SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordsLocalNew, name);CHKERRQ(ierr); 2037*412e9a14SMatthew G. Knepley ierr = VecGetBlockSize(coordsLocal, &bs);CHKERRQ(ierr); 2038*412e9a14SMatthew G. Knepley ierr = VecSetBlockSize(coordsLocalNew, bs);CHKERRQ(ierr); 2039*412e9a14SMatthew G. Knepley ierr = VecGetType(coordsLocal, &vtype);CHKERRQ(ierr); 2040*412e9a14SMatthew G. Knepley ierr = VecSetType(coordsLocalNew, vtype);CHKERRQ(ierr); 2041b5da9499SMatthew G. Knepley } 2042*412e9a14SMatthew G. Knepley ierr = VecGetArrayRead(coordsLocal, &coords);CHKERRQ(ierr); 2043*412e9a14SMatthew G. Knepley ierr = VecGetArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr); 2044*412e9a14SMatthew G. Knepley ierr = PetscSectionGetChart(coordSection, &ocStart, &ocEnd);CHKERRQ(ierr); 2045*412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2046*412e9a14SMatthew G. Knepley /* First set coordinates for vertices*/ 2047*412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2048*412e9a14SMatthew G. Knepley DMPolytopeType ct; 2049*412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2050*412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2051*412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2052*412e9a14SMatthew G. Knepley PetscBool hasVertex = PETSC_FALSE, isLocalized = PETSC_FALSE; 205390b157c4SStefano Zampini 2054*412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2055*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2056*412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2057*412e9a14SMatthew G. Knepley if (rct[n] == DM_POLYTOPE_POINT) {hasVertex = PETSC_TRUE; break;} 2058*412e9a14SMatthew G. Knepley } 2059*412e9a14SMatthew G. Knepley if (localizeVertices && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) { 2060*412e9a14SMatthew G. Knepley PetscInt dof; 2061*412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, p, &dof); CHKERRQ(ierr); 2062*412e9a14SMatthew G. Knepley if (dof) isLocalized = PETSC_TRUE; 2063*412e9a14SMatthew G. Knepley } 2064*412e9a14SMatthew G. Knepley if (hasVertex) { 2065*412e9a14SMatthew G. Knepley PetscScalar *pcoords = NULL; 2066*412e9a14SMatthew G. Knepley PetscScalar vcoords[3] = {0., 0., 0.}; 2067*412e9a14SMatthew G. Knepley PetscInt Nc, Nv, v, d; 206890b157c4SStefano Zampini 2069*412e9a14SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr); 2070*412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_POINT) { 2071*412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) vcoords[d] = pcoords[d]; 20729fc2a3f3SStefano Zampini } else { 2073*412e9a14SMatthew G. Knepley if (localizeVertices) { 2074*412e9a14SMatthew G. Knepley PetscScalar anchor[3]; 207590b157c4SStefano Zampini 2076*412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) anchor[d] = pcoords[d]; 2077*412e9a14SMatthew G. Knepley if (!isLocalized) { 2078*412e9a14SMatthew G. Knepley Nv = Nc/dE; 2079*412e9a14SMatthew G. Knepley for (v = 0; v < Nv; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], vcoords);CHKERRQ(ierr);} 2080*412e9a14SMatthew G. Knepley } else { 2081*412e9a14SMatthew G. Knepley Nv = Nc/(2*dE); 2082*412e9a14SMatthew G. Knepley for (v = Nv; v < Nv*2; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], vcoords);CHKERRQ(ierr);} 208390b157c4SStefano Zampini } 208490b157c4SStefano Zampini } else { 2085*412e9a14SMatthew G. Knepley Nv = Nc/dE; 2086*412e9a14SMatthew G. Knepley for (v = 0; v < Nv; ++v) for (d = 0; d < dE; ++d) vcoords[d] += pcoords[v*dE+d]; 2087b5da9499SMatthew G. Knepley } 2088*412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) vcoords[d] /= Nv; 208990b157c4SStefano Zampini } 2090*412e9a14SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr); 2091*412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2092*412e9a14SMatthew G. Knepley if (rct[n] != DM_POLYTOPE_POINT) continue; 2093*412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2094*412e9a14SMatthew G. Knepley PetscInt vNew, off; 2095b5da9499SMatthew G. Knepley 2096*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &vNew);CHKERRQ(ierr); 2097*412e9a14SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, vNew, &off);CHKERRQ(ierr); 2098*412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) coordsNew[off+d] = vcoords[d]; 2099b5da9499SMatthew G. Knepley } 21009fc2a3f3SStefano Zampini } 2101*412e9a14SMatthew G. Knepley } 2102*412e9a14SMatthew G. Knepley } 2103*412e9a14SMatthew G. Knepley /* Then set coordinates for cells by localizing */ 2104*412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2105*412e9a14SMatthew G. Knepley DMPolytopeType ct; 2106*412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2107*412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2108*412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2109*412e9a14SMatthew G. Knepley PetscBool isLocalized = PETSC_FALSE; 211090b157c4SStefano Zampini 2111*412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2112*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2113*412e9a14SMatthew G. Knepley if (localizeCells && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) { 2114*412e9a14SMatthew G. Knepley PetscInt dof; 2115*412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, p, &dof); CHKERRQ(ierr); 2116*412e9a14SMatthew G. Knepley if (dof) isLocalized = PETSC_TRUE; 2117b5da9499SMatthew G. Knepley } 2118*412e9a14SMatthew G. Knepley if (isLocalized) { 2119*412e9a14SMatthew G. Knepley const PetscScalar *pcoords; 21209fc2a3f3SStefano Zampini 2121*412e9a14SMatthew G. Knepley ierr = DMPlexPointLocalRead(cdm, p, coords, &pcoords);CHKERRQ(ierr); 2122*412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2123*412e9a14SMatthew G. Knepley const PetscInt Nr = rsize[n]; 212490b157c4SStefano Zampini 2125*412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ct) != DMPolytopeTypeGetDim(rct[n])) continue; 2126*412e9a14SMatthew G. Knepley for (r = 0; r < Nr; ++r) { 2127*412e9a14SMatthew G. Knepley PetscInt pNew, offNew; 212890b157c4SStefano Zampini 2129*412e9a14SMatthew G. Knepley /* It looks like Stefano and Lisandro are allowing localized coordinates without defining the periodic boundary, which means that 2130*412e9a14SMatthew G. Knepley DMLocalizeCoordinate_Internal() will not work. Localized coordinates will have to have obtained by the affine map of the larger 2131*412e9a14SMatthew G. Knepley cell to the ones it produces. */ 2132*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 2133*412e9a14SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, pNew, &offNew);CHKERRQ(ierr); 2134*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapLocalizedCoordinates(cr, ct, rct[n], r, pcoords, &coordsNew[offNew]);CHKERRQ(ierr); 213590b157c4SStefano Zampini } 213690b157c4SStefano Zampini } 213790b157c4SStefano Zampini } 213890b157c4SStefano Zampini } 2139*412e9a14SMatthew G. Knepley ierr = VecRestoreArrayRead(coordsLocal, &coords);CHKERRQ(ierr); 2140*412e9a14SMatthew G. Knepley ierr = VecRestoreArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr); 2141*412e9a14SMatthew G. Knepley ierr = DMSetCoordinatesLocal(rdm, coordsLocalNew);CHKERRQ(ierr); 2142*412e9a14SMatthew G. Knepley /* TODO Stefano has a final reduction if some hybrid coordinates cannot be found. (needcoords) Should not be needed. */ 2143*412e9a14SMatthew G. Knepley ierr = VecDestroy(&coordsLocalNew);CHKERRQ(ierr); 214475d3a19aSMatthew G. Knepley ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 2145*412e9a14SMatthew G. Knepley if (!localizeCells) {ierr = DMLocalizeCoordinates(rdm);CHKERRQ(ierr);} 214675d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 214775d3a19aSMatthew G. Knepley } 214875d3a19aSMatthew G. Knepley 2149963fc26aSMatthew G. Knepley /*@ 2150963fc26aSMatthew G. Knepley DMPlexCreateProcessSF - Create an SF which just has process connectivity 2151963fc26aSMatthew G. Knepley 2152d083f849SBarry Smith Collective on dm 2153963fc26aSMatthew G. Knepley 2154963fc26aSMatthew G. Knepley Input Parameters: 2155963fc26aSMatthew G. Knepley + dm - The DM 2156963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity 2157963fc26aSMatthew G. Knepley 2158963fc26aSMatthew G. Knepley Output Parameters: 2159963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL 2160963fc26aSMatthew G. Knepley - sfProcess - An SF encoding the process connectivity, or NULL 2161963fc26aSMatthew G. Knepley 2162963fc26aSMatthew G. Knepley Level: developer 2163963fc26aSMatthew G. Knepley 2164963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 2165963fc26aSMatthew G. Knepley @*/ 2166963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 216775d3a19aSMatthew G. Knepley { 216875d3a19aSMatthew G. Knepley PetscInt numRoots, numLeaves, l; 216975d3a19aSMatthew G. Knepley const PetscInt *localPoints; 217075d3a19aSMatthew G. Knepley const PetscSFNode *remotePoints; 217175d3a19aSMatthew G. Knepley PetscInt *localPointsNew; 217275d3a19aSMatthew G. Knepley PetscSFNode *remotePointsNew; 217375d3a19aSMatthew G. Knepley PetscInt *ranks, *ranksNew; 21749852e123SBarry Smith PetscMPIInt size; 217575d3a19aSMatthew G. Knepley PetscErrorCode ierr; 217675d3a19aSMatthew G. Knepley 217775d3a19aSMatthew G. Knepley PetscFunctionBegin; 2178963fc26aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2179963fc26aSMatthew G. Knepley PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 2180963fc26aSMatthew G. Knepley if (processRanks) {PetscValidPointer(processRanks, 3);} 2181963fc26aSMatthew G. Knepley if (sfProcess) {PetscValidPointer(sfProcess, 4);} 21829852e123SBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 218375d3a19aSMatthew G. Knepley ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 2184785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 218575d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 218675d3a19aSMatthew G. Knepley ranks[l] = remotePoints[l].rank; 218775d3a19aSMatthew G. Knepley } 218875d3a19aSMatthew G. Knepley ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 2189785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 2190785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 2191785e854fSJed Brown ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 219275d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 219375d3a19aSMatthew G. Knepley ranksNew[l] = ranks[l]; 219475d3a19aSMatthew G. Knepley localPointsNew[l] = l; 219575d3a19aSMatthew G. Knepley remotePointsNew[l].index = 0; 219675d3a19aSMatthew G. Knepley remotePointsNew[l].rank = ranksNew[l]; 219775d3a19aSMatthew G. Knepley } 219875d3a19aSMatthew G. Knepley ierr = PetscFree(ranks);CHKERRQ(ierr); 2199963fc26aSMatthew G. Knepley if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 2200963fc26aSMatthew G. Knepley else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 2201963fc26aSMatthew G. Knepley if (sfProcess) { 220275d3a19aSMatthew G. Knepley ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 2203963fc26aSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 220475d3a19aSMatthew G. Knepley ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 22059852e123SBarry Smith ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 2206963fc26aSMatthew G. Knepley } 220775d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 220875d3a19aSMatthew G. Knepley } 220975d3a19aSMatthew G. Knepley 2210*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateSF(DMPlexCellRefiner cr, DM rdm) 221175d3a19aSMatthew G. Knepley { 2212*412e9a14SMatthew G. Knepley DM dm = cr->dm; 2213*412e9a14SMatthew G. Knepley DMPlexCellRefiner *crRem; 221475d3a19aSMatthew G. Knepley PetscSF sf, sfNew, sfProcess; 221575d3a19aSMatthew G. Knepley IS processRanks; 2216*412e9a14SMatthew G. Knepley MPI_Datatype ctType; 221775d3a19aSMatthew G. Knepley PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 221875d3a19aSMatthew G. Knepley const PetscInt *localPoints, *neighbors; 221975d3a19aSMatthew G. Knepley const PetscSFNode *remotePoints; 222075d3a19aSMatthew G. Knepley PetscInt *localPointsNew; 222175d3a19aSMatthew G. Knepley PetscSFNode *remotePointsNew; 2222*412e9a14SMatthew G. Knepley PetscInt *ctStartRem, *ctStartNewRem; 2223*412e9a14SMatthew G. Knepley PetscInt ctSize = DM_NUM_POLYTOPES+1, numNeighbors, n, pStartNew, pEndNew, pNew, pNewRem; 222475d3a19aSMatthew G. Knepley PetscErrorCode ierr; 222575d3a19aSMatthew G. Knepley 222675d3a19aSMatthew G. Knepley PetscFunctionBegin; 222775d3a19aSMatthew G. Knepley ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 222875d3a19aSMatthew G. Knepley ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 222975d3a19aSMatthew G. Knepley ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 2230add09238SMatthew G. Knepley /* Calculate size of new SF */ 223175d3a19aSMatthew G. Knepley ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 223275d3a19aSMatthew G. Knepley if (numRoots < 0) PetscFunctionReturn(0); 223375d3a19aSMatthew G. Knepley for (l = 0; l < numLeaves; ++l) { 223475d3a19aSMatthew G. Knepley const PetscInt p = localPoints[l]; 2235*412e9a14SMatthew G. Knepley DMPolytopeType ct; 2236*412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2237*412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2238*412e9a14SMatthew G. Knepley PetscInt Nct, n; 223975d3a19aSMatthew G. Knepley 2240*412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2241*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2242*412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) numLeavesNew += rsize[n]; 22430314a74cSLawrence Mitchell } 2244*412e9a14SMatthew G. Knepley /* Communicate ctStart and cStartNew for each remote rank */ 224575d3a19aSMatthew G. Knepley ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 224675d3a19aSMatthew G. Knepley ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 2247*412e9a14SMatthew G. Knepley ierr = PetscMalloc2(ctSize*numNeighbors, &ctStartRem, ctSize*numNeighbors, &ctStartNewRem);CHKERRQ(ierr); 2248*412e9a14SMatthew G. Knepley ierr = MPI_Type_contiguous(ctSize, MPIU_INT, &ctType);CHKERRQ(ierr); 2249*412e9a14SMatthew G. Knepley ierr = MPI_Type_commit(&ctType);CHKERRQ(ierr); 2250*412e9a14SMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr); 2251*412e9a14SMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr); 2252*412e9a14SMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr); 2253*412e9a14SMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr); 2254*412e9a14SMatthew G. Knepley ierr = MPI_Type_free(&ctType);CHKERRQ(ierr); 225575d3a19aSMatthew G. Knepley ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 2256*412e9a14SMatthew G. Knepley ierr = PetscMalloc1(numNeighbors, &crRem);CHKERRQ(ierr); 2257*412e9a14SMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) { 2258*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &crRem[n]);CHKERRQ(ierr); 2259*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetStarts(crRem[n], &ctStartRem[n*ctSize], &ctStartNewRem[n*ctSize]); 2260*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(crRem[n]);CHKERRQ(ierr); 2261*412e9a14SMatthew G. Knepley } 2262*412e9a14SMatthew G. Knepley ierr = PetscFree2(ctStartRem, ctStartNewRem);CHKERRQ(ierr); 226375d3a19aSMatthew G. Knepley /* Calculate new point SF */ 2264785e854fSJed Brown ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 2265785e854fSJed Brown ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 226675d3a19aSMatthew G. Knepley ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 226775d3a19aSMatthew G. Knepley for (l = 0, m = 0; l < numLeaves; ++l) { 226875d3a19aSMatthew G. Knepley PetscInt p = localPoints[l]; 2269*412e9a14SMatthew G. Knepley PetscInt pRem = remotePoints[l].index; 2270*412e9a14SMatthew G. Knepley PetscMPIInt rankRem = remotePoints[l].rank; 2271*412e9a14SMatthew G. Knepley DMPolytopeType ct; 2272*412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2273*412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2274*412e9a14SMatthew G. Knepley PetscInt neighbor, Nct, n, r; 227575d3a19aSMatthew G. Knepley 2276*412e9a14SMatthew G. Knepley ierr = PetscFindInt(rankRem, numNeighbors, neighbors, &neighbor);CHKERRQ(ierr); 2277*412e9a14SMatthew G. Knepley if (neighbor < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rankRem); 2278*412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2279*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2280*412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2281*412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2282*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 2283*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(crRem[neighbor], ct, rct[n], pRem, r, &pNewRem);CHKERRQ(ierr); 2284*412e9a14SMatthew G. Knepley localPointsNew[m] = pNew; 2285*412e9a14SMatthew G. Knepley remotePointsNew[m].index = pNewRem; 2286*412e9a14SMatthew G. Knepley remotePointsNew[m].rank = rankRem; 22870314a74cSLawrence Mitchell ++m; 22880314a74cSLawrence Mitchell } 22896ce3c06aSMatthew G. Knepley } 22906ce3c06aSMatthew G. Knepley } 2291*412e9a14SMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) {ierr = DMPlexCellRefinerDestroy(&crRem[n]);CHKERRQ(ierr);} 2292*412e9a14SMatthew G. Knepley ierr = PetscFree(crRem);CHKERRQ(ierr); 2293d7eabd03SStefano Zampini if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew); 229475d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 229575d3a19aSMatthew G. Knepley ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 2296ba3c3d50SMatthew G. Knepley { 2297ba3c3d50SMatthew G. Knepley PetscSFNode *rp, *rtmp; 2298ba3c3d50SMatthew G. Knepley PetscInt *lp, *idx, *ltmp, i; 2299ba3c3d50SMatthew G. Knepley 2300ba3c3d50SMatthew G. Knepley /* SF needs sorted leaves to correct calculate Gather */ 2301ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &idx);CHKERRQ(ierr); 2302ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 2303ba3c3d50SMatthew G. Knepley ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 2304c7c54c77SMatthew G. Knepley for (i = 0; i < numLeavesNew; ++i) { 2305d7eabd03SStefano 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); 2306c7c54c77SMatthew G. Knepley idx[i] = i; 2307c7c54c77SMatthew G. Knepley } 2308ba3c3d50SMatthew G. Knepley ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 2309ba3c3d50SMatthew G. Knepley for (i = 0; i < numLeavesNew; ++i) { 2310ba3c3d50SMatthew G. Knepley lp[i] = localPointsNew[idx[i]]; 2311ba3c3d50SMatthew G. Knepley rp[i] = remotePointsNew[idx[i]]; 2312ba3c3d50SMatthew G. Knepley } 2313ba3c3d50SMatthew G. Knepley ltmp = localPointsNew; 2314ba3c3d50SMatthew G. Knepley localPointsNew = lp; 2315ba3c3d50SMatthew G. Knepley rtmp = remotePointsNew; 2316ba3c3d50SMatthew G. Knepley remotePointsNew = rp; 2317ba3c3d50SMatthew G. Knepley ierr = PetscFree(idx);CHKERRQ(ierr); 2318ba3c3d50SMatthew G. Knepley ierr = PetscFree(ltmp);CHKERRQ(ierr); 2319ba3c3d50SMatthew G. Knepley ierr = PetscFree(rtmp);CHKERRQ(ierr); 2320ba3c3d50SMatthew G. Knepley } 232175d3a19aSMatthew G. Knepley ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 232275d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 232375d3a19aSMatthew G. Knepley } 232475d3a19aSMatthew G. Knepley 2325*412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateLabels(DMPlexCellRefiner cr, DM rdm) 232675d3a19aSMatthew G. Knepley { 2327*412e9a14SMatthew G. Knepley DM dm = cr->dm; 232875d3a19aSMatthew G. Knepley PetscInt numLabels, l; 2329*412e9a14SMatthew G. Knepley PetscInt pNew; 233075d3a19aSMatthew G. Knepley PetscErrorCode ierr; 233175d3a19aSMatthew G. Knepley 233275d3a19aSMatthew G. Knepley PetscFunctionBegin; 2333c58f1c22SToby Isaac ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 233475d3a19aSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 233575d3a19aSMatthew G. Knepley DMLabel label, labelNew; 233675d3a19aSMatthew G. Knepley const char *lname; 2337ba2698f1SMatthew G. Knepley PetscBool isDepth, isCellType; 233875d3a19aSMatthew G. Knepley IS valueIS; 233975d3a19aSMatthew G. Knepley const PetscInt *values; 23405aa44df4SToby Isaac PetscInt defVal; 234175d3a19aSMatthew G. Knepley PetscInt numValues, val; 234275d3a19aSMatthew G. Knepley 2343c58f1c22SToby Isaac ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 234475d3a19aSMatthew G. Knepley ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 234575d3a19aSMatthew G. Knepley if (isDepth) continue; 2346ba2698f1SMatthew G. Knepley ierr = PetscStrcmp(lname, "celltype", &isCellType);CHKERRQ(ierr); 2347ba2698f1SMatthew G. Knepley if (isCellType) continue; 2348c58f1c22SToby Isaac ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 2349c58f1c22SToby Isaac ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 2350c58f1c22SToby Isaac ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 23515aa44df4SToby Isaac ierr = DMLabelGetDefaultValue(label, &defVal);CHKERRQ(ierr); 23525aa44df4SToby Isaac ierr = DMLabelSetDefaultValue(labelNew, defVal);CHKERRQ(ierr); 235375d3a19aSMatthew G. Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 235475d3a19aSMatthew G. Knepley ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 235575d3a19aSMatthew G. Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 235675d3a19aSMatthew G. Knepley for (val = 0; val < numValues; ++val) { 235775d3a19aSMatthew G. Knepley IS pointIS; 235875d3a19aSMatthew G. Knepley const PetscInt *points; 2359*412e9a14SMatthew G. Knepley PetscInt numPoints, p; 236075d3a19aSMatthew G. Knepley 23612bc5314cSMichael Lange /* Ensure refined label is created with same number of strata as 23622bc5314cSMichael Lange * original (even if no entries here). */ 2363ad8374ffSToby Isaac ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 2364*412e9a14SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 2365*412e9a14SMatthew G. Knepley ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 2366*412e9a14SMatthew G. Knepley ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 2367*412e9a14SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 2368*412e9a14SMatthew G. Knepley const PetscInt point = points[p]; 2369*412e9a14SMatthew G. Knepley DMPolytopeType ct; 2370*412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2371*412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2372*412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2373*412e9a14SMatthew G. Knepley 2374*412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, point, &ct);CHKERRQ(ierr); 2375*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2376*412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2377*412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2378*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], point, r, &pNew);CHKERRQ(ierr); 2379*412e9a14SMatthew G. Knepley ierr = DMLabelSetValue(labelNew, pNew, values[val]);CHKERRQ(ierr); 238027fcede3SMatthew G. Knepley } 238175d3a19aSMatthew G. Knepley } 238275d3a19aSMatthew G. Knepley } 238375d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 238475d3a19aSMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 238575d3a19aSMatthew G. Knepley } 238675d3a19aSMatthew G. Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 238775d3a19aSMatthew G. Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 238875d3a19aSMatthew G. Knepley } 238975d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 239075d3a19aSMatthew G. Knepley } 239175d3a19aSMatthew G. Knepley 239275d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */ 2393*412e9a14SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform(DM dm, DMPlexCellRefiner cr, DM *dmRefined) 239475d3a19aSMatthew G. Knepley { 239575d3a19aSMatthew G. Knepley DM rdm; 2396*412e9a14SMatthew G. Knepley PetscInt dim, embedDim, depth; 239775d3a19aSMatthew G. Knepley PetscErrorCode ierr; 239875d3a19aSMatthew G. Knepley 239975d3a19aSMatthew G. Knepley PetscFunctionBegin; 2400*412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 240175d3a19aSMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 240275d3a19aSMatthew G. Knepley ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 2403c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 2404c73cfb54SMatthew G. Knepley ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 24056dcbd917SStefano Zampini ierr = DMGetCoordinateDim(dm, &embedDim);CHKERRQ(ierr); 24066dcbd917SStefano Zampini ierr = DMSetCoordinateDim(rdm, embedDim);CHKERRQ(ierr); 240775d3a19aSMatthew G. Knepley /* Calculate number of new points of each depth */ 240875d3a19aSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 24091e573d11SMatthew G. Knepley if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 241075d3a19aSMatthew G. Knepley /* Step 1: Set chart */ 2411*412e9a14SMatthew G. Knepley ierr = DMPlexSetChart(rdm, 0, cr->ctStartNew[cr->ctOrder[DM_NUM_POLYTOPES]]);CHKERRQ(ierr); 24126d7373e8SToby Isaac /* Step 2: Set cone/support sizes (automatically stratifies) */ 2413*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetConeSizes(cr, rdm);CHKERRQ(ierr); 241475d3a19aSMatthew G. Knepley /* Step 3: Setup refined DM */ 241575d3a19aSMatthew G. Knepley ierr = DMSetUp(rdm);CHKERRQ(ierr); 24166d7373e8SToby Isaac /* Step 4: Set cones and supports (automatically symmetrizes) */ 2417*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetCones(cr, rdm);CHKERRQ(ierr); 24186d7373e8SToby Isaac /* Step 5: Create pointSF */ 2419*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreateSF(cr, rdm);CHKERRQ(ierr); 24206d7373e8SToby Isaac /* Step 6: Create labels */ 2421*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreateLabels(cr, rdm);CHKERRQ(ierr); 24226d7373e8SToby Isaac /* Step 7: Set coordinates */ 2423*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetCoordinates(cr, rdm);CHKERRQ(ierr); 242475d3a19aSMatthew G. Knepley *dmRefined = rdm; 242575d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 242675d3a19aSMatthew G. Knepley } 242775d3a19aSMatthew G. Knepley 24282389894bSMatthew G. Knepley /*@ 24292389894bSMatthew G. Knepley DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 24302389894bSMatthew G. Knepley 24312389894bSMatthew G. Knepley Input Parameter: 24322389894bSMatthew G. Knepley . dm - The coarse DM 24332389894bSMatthew G. Knepley 24342389894bSMatthew G. Knepley Output Parameter: 24352389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh 24362389894bSMatthew G. Knepley 24372389894bSMatthew G. Knepley Level: developer 24382389894bSMatthew G. Knepley 24392389894bSMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 24402389894bSMatthew G. Knepley @*/ 24412389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 24422389894bSMatthew G. Knepley { 2443*412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 2444*412e9a14SMatthew G. Knepley PetscInt *fpoints; 2445*412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p, vStart, vEnd, v, vNew; 24462389894bSMatthew G. Knepley PetscErrorCode ierr; 24472389894bSMatthew G. Knepley 24482389894bSMatthew G. Knepley PetscFunctionBegin; 24492389894bSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 24502389894bSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 2451*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr); 2452*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 24532389894bSMatthew G. Knepley ierr = PetscMalloc1(pEnd-pStart, &fpoints);CHKERRQ(ierr); 24542389894bSMatthew G. Knepley for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 2455*412e9a14SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 2456*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, DM_POLYTOPE_POINT, DM_POLYTOPE_POINT, p, 0, &vNew);CHKERRQ(ierr); 2457*412e9a14SMatthew G. Knepley fpoints[v-pStart] = vNew; 24582389894bSMatthew G. Knepley } 2459*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 24602389894bSMatthew G. Knepley ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 24612389894bSMatthew G. Knepley PetscFunctionReturn(0); 24622389894bSMatthew G. Knepley } 24632389894bSMatthew G. Knepley 24640e2b6761SMatthew G. Knepley /*@ 24650e2b6761SMatthew G. Knepley DMPlexSetRefinementUniform - Set the flag for uniform refinement 24660e2b6761SMatthew G. Knepley 24670e2b6761SMatthew G. Knepley Input Parameters: 24680e2b6761SMatthew G. Knepley + dm - The DM 24690e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement 24700e2b6761SMatthew G. Knepley 24710e2b6761SMatthew G. Knepley Level: developer 24720e2b6761SMatthew G. Knepley 24730e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 24740e2b6761SMatthew G. Knepley @*/ 247575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 247675d3a19aSMatthew G. Knepley { 247775d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 247875d3a19aSMatthew G. Knepley 247975d3a19aSMatthew G. Knepley PetscFunctionBegin; 248075d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 248175d3a19aSMatthew G. Knepley mesh->refinementUniform = refinementUniform; 248275d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 248375d3a19aSMatthew G. Knepley } 248475d3a19aSMatthew G. Knepley 24850e2b6761SMatthew G. Knepley /*@ 24860e2b6761SMatthew G. Knepley DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 24870e2b6761SMatthew G. Knepley 24880e2b6761SMatthew G. Knepley Input Parameter: 24890e2b6761SMatthew G. Knepley . dm - The DM 24900e2b6761SMatthew G. Knepley 24910e2b6761SMatthew G. Knepley Output Parameter: 24920e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement 24930e2b6761SMatthew G. Knepley 24940e2b6761SMatthew G. Knepley Level: developer 24950e2b6761SMatthew G. Knepley 24960e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 24970e2b6761SMatthew G. Knepley @*/ 249875d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 249975d3a19aSMatthew G. Knepley { 250075d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 250175d3a19aSMatthew G. Knepley 250275d3a19aSMatthew G. Knepley PetscFunctionBegin; 250375d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 250475d3a19aSMatthew G. Knepley PetscValidPointer(refinementUniform, 2); 250575d3a19aSMatthew G. Knepley *refinementUniform = mesh->refinementUniform; 250675d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 250775d3a19aSMatthew G. Knepley } 250875d3a19aSMatthew G. Knepley 25090e2b6761SMatthew G. Knepley /*@ 25100e2b6761SMatthew G. Knepley DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 25110e2b6761SMatthew G. Knepley 25120e2b6761SMatthew G. Knepley Input Parameters: 25130e2b6761SMatthew G. Knepley + dm - The DM 25140e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh 25150e2b6761SMatthew G. Knepley 25160e2b6761SMatthew G. Knepley Level: developer 25170e2b6761SMatthew G. Knepley 25180e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 25190e2b6761SMatthew G. Knepley @*/ 252075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 252175d3a19aSMatthew G. Knepley { 252275d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 252375d3a19aSMatthew G. Knepley 252475d3a19aSMatthew G. Knepley PetscFunctionBegin; 252575d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 252675d3a19aSMatthew G. Knepley mesh->refinementLimit = refinementLimit; 252775d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 252875d3a19aSMatthew G. Knepley } 252975d3a19aSMatthew G. Knepley 25300e2b6761SMatthew G. Knepley /*@ 25310e2b6761SMatthew G. Knepley DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 25320e2b6761SMatthew G. Knepley 25330e2b6761SMatthew G. Knepley Input Parameter: 25340e2b6761SMatthew G. Knepley . dm - The DM 25350e2b6761SMatthew G. Knepley 25360e2b6761SMatthew G. Knepley Output Parameter: 25370e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh 25380e2b6761SMatthew G. Knepley 25390e2b6761SMatthew G. Knepley Level: developer 25400e2b6761SMatthew G. Knepley 25410e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 25420e2b6761SMatthew G. Knepley @*/ 254375d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 254475d3a19aSMatthew G. Knepley { 254575d3a19aSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 254675d3a19aSMatthew G. Knepley 254775d3a19aSMatthew G. Knepley PetscFunctionBegin; 254875d3a19aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 254975d3a19aSMatthew G. Knepley PetscValidPointer(refinementLimit, 2); 255075d3a19aSMatthew G. Knepley /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 255175d3a19aSMatthew G. Knepley *refinementLimit = mesh->refinementLimit; 255275d3a19aSMatthew G. Knepley PetscFunctionReturn(0); 255375d3a19aSMatthew G. Knepley } 255475d3a19aSMatthew G. Knepley 2555b28003e6SMatthew G. Knepley /*@ 2556b28003e6SMatthew G. Knepley DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 2557b28003e6SMatthew G. Knepley 2558b28003e6SMatthew G. Knepley Input Parameters: 2559b28003e6SMatthew G. Knepley + dm - The DM 2560b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh 2561b28003e6SMatthew G. Knepley 2562b28003e6SMatthew G. Knepley Note: The calling sequence is refinementFunc(coords, limit) 2563b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid 2564b28003e6SMatthew G. Knepley $ limit - The maximum cell volume for a cell containing this point 2565b28003e6SMatthew G. Knepley 2566b28003e6SMatthew G. Knepley Level: developer 2567b28003e6SMatthew G. Knepley 2568b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 2569b28003e6SMatthew G. Knepley @*/ 2570b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 2571b28003e6SMatthew G. Knepley { 2572b28003e6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2573b28003e6SMatthew G. Knepley 2574b28003e6SMatthew G. Knepley PetscFunctionBegin; 2575b28003e6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2576b28003e6SMatthew G. Knepley mesh->refinementFunc = refinementFunc; 2577b28003e6SMatthew G. Knepley PetscFunctionReturn(0); 2578b28003e6SMatthew G. Knepley } 2579b28003e6SMatthew G. Knepley 2580b28003e6SMatthew G. Knepley /*@ 2581b28003e6SMatthew G. Knepley DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 2582b28003e6SMatthew G. Knepley 2583b28003e6SMatthew G. Knepley Input Parameter: 2584b28003e6SMatthew G. Knepley . dm - The DM 2585b28003e6SMatthew G. Knepley 2586b28003e6SMatthew G. Knepley Output Parameter: 2587b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh 2588b28003e6SMatthew G. Knepley 2589b28003e6SMatthew G. Knepley Note: The calling sequence is refinementFunc(coords, limit) 2590b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid 2591b28003e6SMatthew G. Knepley $ limit - The maximum cell volume for a cell containing this point 2592b28003e6SMatthew G. Knepley 2593b28003e6SMatthew G. Knepley Level: developer 2594b28003e6SMatthew G. Knepley 2595b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 2596b28003e6SMatthew G. Knepley @*/ 2597b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 2598b28003e6SMatthew G. Knepley { 2599b28003e6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2600b28003e6SMatthew G. Knepley 2601b28003e6SMatthew G. Knepley PetscFunctionBegin; 2602b28003e6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2603b28003e6SMatthew G. Knepley PetscValidPointer(refinementFunc, 2); 2604b28003e6SMatthew G. Knepley *refinementFunc = mesh->refinementFunc; 2605b28003e6SMatthew G. Knepley PetscFunctionReturn(0); 2606b28003e6SMatthew G. Knepley } 2607b28003e6SMatthew G. Knepley 26080d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 26090d1cd5e0SMatthew G. Knepley { 2610492b8470SStefano Zampini PetscBool isUniform; 2611*412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 26120d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 26130d1cd5e0SMatthew G. Knepley 26140d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 26150d1cd5e0SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 2616*412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-initref_dm_view");CHKERRQ(ierr); 26170d1cd5e0SMatthew G. Knepley if (isUniform) { 2618492b8470SStefano Zampini PetscBool localized; 26190d1cd5e0SMatthew G. Knepley 2620*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr); 2621*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 2622492b8470SStefano Zampini ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 2623*412e9a14SMatthew G. Knepley ierr = DMPlexRefineUniform(dm, cr, dmRefined);CHKERRQ(ierr); 26249a7e3c0aSMatthew G. Knepley ierr = DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);CHKERRQ(ierr); 26250d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 26260d1cd5e0SMatthew G. Knepley if (localized) {ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr);} 2627*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 26280d1cd5e0SMatthew G. Knepley } else { 26290d1cd5e0SMatthew G. Knepley ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 26300d1cd5e0SMatthew G. Knepley } 26310d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 26320d1cd5e0SMatthew G. Knepley } 26330d1cd5e0SMatthew G. Knepley 26340d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 26350d1cd5e0SMatthew G. Knepley { 26360d1cd5e0SMatthew G. Knepley DM cdm = dm; 26370d1cd5e0SMatthew G. Knepley PetscInt r; 26380d1cd5e0SMatthew G. Knepley PetscBool isUniform, localized; 26390d1cd5e0SMatthew G. Knepley PetscErrorCode ierr; 26400d1cd5e0SMatthew G. Knepley 26410d1cd5e0SMatthew G. Knepley PetscFunctionBegin; 26420d1cd5e0SMatthew G. Knepley ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 26430d1cd5e0SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 26440d1cd5e0SMatthew G. Knepley if (isUniform) { 26450d1cd5e0SMatthew G. Knepley for (r = 0; r < nlevels; ++r) { 2646*412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 26470d1cd5e0SMatthew G. Knepley 2648*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(cdm, &cr);CHKERRQ(ierr); 2649*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 2650*412e9a14SMatthew G. Knepley ierr = DMPlexRefineUniform(cdm, cr, &dmRefined[r]);CHKERRQ(ierr); 26519a7e3c0aSMatthew G. Knepley ierr = DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);CHKERRQ(ierr); 26529a7e3c0aSMatthew G. Knepley ierr = DMSetRefineLevel(dmRefined[r], cdm->levelup+1);CHKERRQ(ierr); 26530d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 26540d1cd5e0SMatthew G. Knepley if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 26550d1cd5e0SMatthew G. Knepley ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 26560d1cd5e0SMatthew G. Knepley ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 26570d1cd5e0SMatthew G. Knepley cdm = dmRefined[r]; 2658*412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 26590d1cd5e0SMatthew G. Knepley } 26600d1cd5e0SMatthew G. Knepley } else { 26610d1cd5e0SMatthew G. Knepley for (r = 0; r < nlevels; ++r) { 26620d1cd5e0SMatthew G. Knepley ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 26630d1cd5e0SMatthew G. Knepley ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 26640d1cd5e0SMatthew G. Knepley if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 26650d1cd5e0SMatthew G. Knepley ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 26660d1cd5e0SMatthew G. Knepley cdm = dmRefined[r]; 26670d1cd5e0SMatthew G. Knepley } 26680d1cd5e0SMatthew G. Knepley } 26690d1cd5e0SMatthew G. Knepley PetscFunctionReturn(0); 26700d1cd5e0SMatthew G. Knepley } 2671