1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2412e9a14SMatthew G. Knepley #include <petsc/private/petscfeimpl.h> /* For PetscFEInterpolate_Static() */ 375d3a19aSMatthew G. Knepley #include <petscsf.h> 475d3a19aSMatthew G. Knepley 596ca5757SLisandro Dalcin const char * const DMPlexCellRefinerTypes[] = {"Regular", "ToBox", "ToSimplex", "DMPlexCellRefinerTypes", "DM_REFINER_", 0}; 675d3a19aSMatthew G. Knepley 709789c4cSMatthew G. Knepley /* 809789c4cSMatthew G. Knepley Note that j and invj are non-square: 909789c4cSMatthew G. Knepley v0 + j x_face = x_cell 1009789c4cSMatthew G. Knepley invj (x_cell - v0) = x_face 1109789c4cSMatthew G. Knepley */ 12412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[]) 1309789c4cSMatthew G. Knepley { 1409789c4cSMatthew G. Knepley /* 1509789c4cSMatthew G. Knepley 2 1609789c4cSMatthew G. Knepley |\ 1709789c4cSMatthew G. Knepley | \ 1809789c4cSMatthew G. Knepley | \ 1909789c4cSMatthew G. Knepley | \ 2009789c4cSMatthew G. Knepley | \ 2109789c4cSMatthew G. Knepley | \ 2209789c4cSMatthew G. Knepley | \ 2309789c4cSMatthew G. Knepley 2 1 2409789c4cSMatthew G. Knepley | \ 2509789c4cSMatthew G. Knepley | \ 2609789c4cSMatthew G. Knepley | \ 2709789c4cSMatthew G. Knepley 0---0-------1 28412e9a14SMatthew G. Knepley v0[Nf][dc]: 3 x 2 29412e9a14SMatthew G. Knepley J[Nf][df][dc]: 3 x 1 x 2 30412e9a14SMatthew G. Knepley invJ[Nf][dc][df]: 3 x 2 x 1 31412e9a14SMatthew G. Knepley detJ[Nf]: 3 3209789c4cSMatthew G. Knepley */ 33412e9a14SMatthew G. Knepley static PetscReal tri_v0[] = {0.0, -1.0, 0.0, 0.0, -1.0, 0.0}; 34412e9a14SMatthew G. Knepley static PetscReal tri_J[] = {1.0, 0.0, -1.0, 1.0, 0.0, -1.0}; 35412e9a14SMatthew G. Knepley static PetscReal tri_invJ[] = {1.0, 0.0, -0.5, 0.5, 0.0, -1.0}; 36412e9a14SMatthew G. Knepley static PetscReal tri_detJ[] = {1.0, 1.414213562373095, 1.0}; 3709789c4cSMatthew G. Knepley /* 3809789c4cSMatthew G. Knepley 3---------2---------2 3909789c4cSMatthew G. Knepley | | 4009789c4cSMatthew G. Knepley | | 4109789c4cSMatthew G. Knepley | | 4209789c4cSMatthew G. Knepley 3 1 4309789c4cSMatthew G. Knepley | | 4409789c4cSMatthew G. Knepley | | 4509789c4cSMatthew G. Knepley | | 4609789c4cSMatthew G. Knepley 0---------0---------1 47412e9a14SMatthew G. Knepley 48412e9a14SMatthew G. Knepley v0[Nf][dc]: 4 x 2 49412e9a14SMatthew G. Knepley J[Nf][df][dc]: 4 x 1 x 2 50412e9a14SMatthew G. Knepley invJ[Nf][dc][df]: 4 x 2 x 1 51412e9a14SMatthew G. Knepley detJ[Nf]: 4 5209789c4cSMatthew G. Knepley */ 53412e9a14SMatthew G. Knepley static PetscReal quad_v0[] = {0.0, -1.0, 1.0, 0.0, 0.0, 1.0 -1.0, 0.0}; 54412e9a14SMatthew G. Knepley static PetscReal quad_J[] = {1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, -1.0}; 55412e9a14SMatthew G. Knepley static PetscReal quad_invJ[] = {1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, -1.0}; 56412e9a14SMatthew G. Knepley static PetscReal quad_detJ[] = {1.0, 1.0, 1.0, 1.0}; 57412e9a14SMatthew G. Knepley 58412e9a14SMatthew G. Knepley PetscFunctionBegin; 59412e9a14SMatthew G. Knepley switch (ct) { 60412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: if (Nf) *Nf = 3; if (v0) *v0 = tri_v0; if (J) *J = tri_J; if (invJ) *invJ = tri_invJ; if (detJ) *detJ = tri_detJ; break; 61412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: if (Nf) *Nf = 4; if (v0) *v0 = quad_v0; if (J) *J = quad_J; if (invJ) *invJ = quad_invJ; if (detJ) *detJ = quad_detJ; break; 6209789c4cSMatthew G. Knepley default: 63412e9a14SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 6409789c4cSMatthew G. Knepley } 6509789c4cSMatthew G. Knepley PetscFunctionReturn(0); 6609789c4cSMatthew G. Knepley } 6709789c4cSMatthew G. Knepley 68bed052eaSMatthew G. Knepley /* Gets the affine map from the original cell to each subcell */ 69412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetAffineTransforms_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[]) 70bed052eaSMatthew G. Knepley { 71260b6d3fSMatthew G. Knepley /* 72260b6d3fSMatthew G. Knepley 2 73260b6d3fSMatthew G. Knepley |\ 74260b6d3fSMatthew G. Knepley | \ 75260b6d3fSMatthew G. Knepley | \ 76260b6d3fSMatthew G. Knepley | \ 77260b6d3fSMatthew G. Knepley | C \ 78260b6d3fSMatthew G. Knepley | \ 79260b6d3fSMatthew G. Knepley | \ 80260b6d3fSMatthew G. Knepley 2---1---1 81260b6d3fSMatthew G. Knepley |\ D / \ 82260b6d3fSMatthew G. Knepley | 2 0 \ 83260b6d3fSMatthew G. Knepley |A \ / B \ 84260b6d3fSMatthew G. Knepley 0---0-------1 85260b6d3fSMatthew G. Knepley */ 86412e9a14SMatthew G. Knepley static PetscReal tri_v0[] = {-1.0, -1.0, 0.0, -1.0, -1.0, 0.0, 0.0, -1.0}; 87412e9a14SMatthew G. Knepley static PetscReal tri_J[] = {0.5, 0.0, 88412e9a14SMatthew G. Knepley 0.0, 0.5, 89412e9a14SMatthew G. Knepley 90412e9a14SMatthew G. Knepley 0.5, 0.0, 91412e9a14SMatthew G. Knepley 0.0, 0.5, 92412e9a14SMatthew G. Knepley 93412e9a14SMatthew G. Knepley 0.5, 0.0, 94412e9a14SMatthew G. Knepley 0.0, 0.5, 95412e9a14SMatthew G. Knepley 96412e9a14SMatthew G. Knepley 0.0, -0.5, 97412e9a14SMatthew G. Knepley 0.5, 0.5}; 98412e9a14SMatthew G. Knepley static PetscReal tri_invJ[] = {2.0, 0.0, 99412e9a14SMatthew G. Knepley 0.0, 2.0, 100412e9a14SMatthew G. Knepley 101412e9a14SMatthew G. Knepley 2.0, 0.0, 102412e9a14SMatthew G. Knepley 0.0, 2.0, 103412e9a14SMatthew G. Knepley 104412e9a14SMatthew G. Knepley 2.0, 0.0, 105412e9a14SMatthew G. Knepley 0.0, 2.0, 106412e9a14SMatthew G. Knepley 107412e9a14SMatthew G. Knepley 2.0, 2.0, 108412e9a14SMatthew G. Knepley -2.0, 0.0}; 109260b6d3fSMatthew G. Knepley /* 110260b6d3fSMatthew G. Knepley 3---------2---------2 111260b6d3fSMatthew G. Knepley | | | 112260b6d3fSMatthew G. Knepley | D 2 C | 113260b6d3fSMatthew G. Knepley | | | 114260b6d3fSMatthew G. Knepley 3----3----0----1----1 115260b6d3fSMatthew G. Knepley | | | 116260b6d3fSMatthew G. Knepley | A 0 B | 117260b6d3fSMatthew G. Knepley | | | 118260b6d3fSMatthew G. Knepley 0---------0---------1 119260b6d3fSMatthew G. Knepley */ 120412e9a14SMatthew G. Knepley static PetscReal quad_v0[] = {-1.0, -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0}; 121412e9a14SMatthew G. Knepley static PetscReal quad_J[] = {0.5, 0.0, 122412e9a14SMatthew G. Knepley 0.0, 0.5, 123412e9a14SMatthew G. Knepley 124412e9a14SMatthew G. Knepley 0.5, 0.0, 125412e9a14SMatthew G. Knepley 0.0, 0.5, 126412e9a14SMatthew G. Knepley 127412e9a14SMatthew G. Knepley 0.5, 0.0, 128412e9a14SMatthew G. Knepley 0.0, 0.5, 129412e9a14SMatthew G. Knepley 130412e9a14SMatthew G. Knepley 0.5, 0.0, 131412e9a14SMatthew G. Knepley 0.0, 0.5}; 132412e9a14SMatthew G. Knepley static PetscReal quad_invJ[] = {2.0, 0.0, 133412e9a14SMatthew G. Knepley 0.0, 2.0, 134412e9a14SMatthew G. Knepley 135412e9a14SMatthew G. Knepley 2.0, 0.0, 136412e9a14SMatthew G. Knepley 0.0, 2.0, 137412e9a14SMatthew G. Knepley 138412e9a14SMatthew G. Knepley 2.0, 0.0, 139412e9a14SMatthew G. Knepley 0.0, 2.0, 140412e9a14SMatthew G. Knepley 141412e9a14SMatthew G. Knepley 2.0, 0.0, 142412e9a14SMatthew G. Knepley 0.0, 2.0}; 143c1879b55SMatthew G. Knepley /* 144c1879b55SMatthew G. Knepley Bottom (viewed from top) Top 145c1879b55SMatthew G. Knepley 1---------2---------2 7---------2---------6 146c1879b55SMatthew G. Knepley | | | | | | 147c1879b55SMatthew G. Knepley | B 2 C | | H 2 G | 148c1879b55SMatthew G. Knepley | | | | | | 149c1879b55SMatthew G. Knepley 3----3----0----1----1 3----3----0----1----1 150c1879b55SMatthew G. Knepley | | | | | | 151c1879b55SMatthew G. Knepley | A 0 D | | E 0 F | 152c1879b55SMatthew G. Knepley | | | | | | 153c1879b55SMatthew G. Knepley 0---------0---------3 4---------0---------5 154c1879b55SMatthew G. Knepley */ 155412e9a14SMatthew G. Knepley static PetscReal hex_v0[] = {-1.0, -1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0, -1.0, 156412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0}; 157412e9a14SMatthew G. Knepley static PetscReal hex_J[] = {0.5, 0.0, 0.0, 158412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 159412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 160bed052eaSMatthew G. Knepley 161412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 162412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 163412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 164412e9a14SMatthew G. Knepley 165412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 166412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 167412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 168412e9a14SMatthew G. Knepley 169412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 170412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 171412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 172412e9a14SMatthew G. Knepley 173412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 174412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 175412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 176412e9a14SMatthew G. Knepley 177412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 178412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 179412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 180412e9a14SMatthew G. Knepley 181412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 182412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 183412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5, 184412e9a14SMatthew G. Knepley 185412e9a14SMatthew G. Knepley 0.5, 0.0, 0.0, 186412e9a14SMatthew G. Knepley 0.0, 0.5, 0.0, 187412e9a14SMatthew G. Knepley 0.0, 0.0, 0.5}; 188412e9a14SMatthew G. Knepley static PetscReal hex_invJ[] = {2.0, 0.0, 0.0, 189412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 190412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 191412e9a14SMatthew G. Knepley 192412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 193412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 194412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 195412e9a14SMatthew G. Knepley 196412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 197412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 198412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 199412e9a14SMatthew G. Knepley 200412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 201412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 202412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 203412e9a14SMatthew G. Knepley 204412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 205412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 206412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 207412e9a14SMatthew G. Knepley 208412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 209412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 210412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 211412e9a14SMatthew G. Knepley 212412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 213412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 214412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0, 215412e9a14SMatthew G. Knepley 216412e9a14SMatthew G. Knepley 2.0, 0.0, 0.0, 217412e9a14SMatthew G. Knepley 0.0, 2.0, 0.0, 218412e9a14SMatthew G. Knepley 0.0, 0.0, 2.0}; 219bed052eaSMatthew G. Knepley 220bed052eaSMatthew G. Knepley PetscFunctionBegin; 221412e9a14SMatthew G. Knepley switch (ct) { 222412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: if (Nc) *Nc = 4; if (v0) *v0 = tri_v0; if (J) *J = tri_J; if (invJ) *invJ = tri_invJ; break; 223412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: if (Nc) *Nc = 4; if (v0) *v0 = quad_v0; if (J) *J = quad_J; if (invJ) *invJ = quad_invJ; break; 224412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: if (Nc) *Nc = 8; if (v0) *v0 = hex_v0; if (J) *J = hex_J; if (invJ) *invJ = hex_invJ; break; 225412e9a14SMatthew G. Knepley default: 226412e9a14SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 227412e9a14SMatthew G. Knepley } 228bed052eaSMatthew G. Knepley PetscFunctionReturn(0); 229bed052eaSMatthew G. Knepley } 230bed052eaSMatthew G. Knepley 23180389061SMatthew G. Knepley /* Should this be here or in the DualSpace somehow? */ 232412e9a14SMatthew G. Knepley PetscErrorCode CellRefinerInCellTest_Internal(DMPolytopeType ct, const PetscReal point[], PetscBool *inside) 23380389061SMatthew G. Knepley { 23480389061SMatthew G. Knepley PetscReal sum = 0.0; 23580389061SMatthew G. Knepley PetscInt d; 23680389061SMatthew G. Knepley 23780389061SMatthew G. Knepley PetscFunctionBegin; 23880389061SMatthew G. Knepley *inside = PETSC_TRUE; 239412e9a14SMatthew G. Knepley switch (ct) { 240412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 241412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 242412e9a14SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) { 24380389061SMatthew G. Knepley if (point[d] < -1.0) {*inside = PETSC_FALSE; break;} 24480389061SMatthew G. Knepley sum += point[d]; 24580389061SMatthew G. Knepley } 246412e9a14SMatthew G. Knepley if (sum > PETSC_SMALL) {*inside = PETSC_FALSE; break;} 24780389061SMatthew G. Knepley break; 248412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 249412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 250412e9a14SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) 251412e9a14SMatthew G. Knepley if (PetscAbsReal(point[d]) > 1.+PETSC_SMALL) {*inside = PETSC_FALSE; break;} 25294339e62SJed Brown break; 25380389061SMatthew G. Knepley default: 254412e9a14SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 25580389061SMatthew G. Knepley } 25680389061SMatthew G. Knepley PetscFunctionReturn(0); 25780389061SMatthew G. Knepley } 25880389061SMatthew G. Knepley 259412e9a14SMatthew G. Knepley /* Regular Refinment of Hybrid Meshes 26075d3a19aSMatthew G. Knepley 261412e9a14SMatthew G. Knepley We would like to express regular refinement as a small set of rules that can be applied on every point of the Plex 262412e9a14SMatthew G. Knepley to automatically generate a refined Plex. In fact, we would like these rules to be general enough to encompass other 263412e9a14SMatthew G. Knepley transformations, such as changing from one type of cell to another, as simplex to hex. 26475d3a19aSMatthew G. Knepley 265412e9a14SMatthew G. Knepley To start, we can create a function that takes an original cell type and returns the number of new cells replacing it 266412e9a14SMatthew G. Knepley and the types of the new cells. 267518a8359SMatthew G. Knepley 268412e9a14SMatthew G. Knepley We need the group multiplication table for group actions from the dihedral group for each cell type. 26942525629SMatthew G. Knepley 270412e9a14SMatthew G. Knepley We need an operator which takes in a cell, and produces a new set of cells with new faces and correct orientations. I think 271412e9a14SMatthew G. Knepley we can just write this operator for faces with identity, and then compose the face orientation actions to get the actual 272412e9a14SMatthew G. Knepley (face, orient) pairs for each subcell. 273412e9a14SMatthew G. Knepley */ 2740314a74cSLawrence Mitchell 27575d3a19aSMatthew G. Knepley /* 276412e9a14SMatthew G. Knepley Input Parameters: 277412e9a14SMatthew G. Knepley + ct - The type of the input cell 278412e9a14SMatthew G. Knepley . co - The orientation of this cell in it parent 279412e9a14SMatthew G. Knepley - cp - The requested cone point of this cell assuming orientation 0 280412e9a14SMatthew G. Knepley 281412e9a14SMatthew G. Knepley Output Parameters: 282412e9a14SMatthew G. Knepley . cpnew - The new cone point, taking inout account the orientation co 283412e9a14SMatthew G. Knepley */ 284412e9a14SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPolytopeMapCell(DMPolytopeType ct, PetscInt co, PetscInt cp, PetscInt *cpnew) 285412e9a14SMatthew G. Knepley { 286412e9a14SMatthew G. Knepley const PetscInt csize = DMPolytopeTypeGetConeSize(ct); 287412e9a14SMatthew G. Knepley 288412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 289412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_POINT) {*cpnew = cp;} 290412e9a14SMatthew G. Knepley else {*cpnew = (co < 0 ? -(co+1)-cp+csize : co+cp)%csize;} 291412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 292412e9a14SMatthew G. Knepley } 293412e9a14SMatthew G. Knepley 294412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCellVertices_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 295412e9a14SMatthew G. Knepley { 296412e9a14SMatthew G. Knepley static PetscReal seg_v[] = {-1.0, 0.0, 1.0}; 297412e9a14SMatthew G. Knepley static PetscReal tri_v[] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0}; 298412e9a14SMatthew G. Knepley static PetscReal quad_v[] = {-1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0}; 299412e9a14SMatthew G. Knepley static PetscReal tet_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 300412e9a14SMatthew G. Knepley -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, -1.0, 1.0, -1.0, 301412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, -1.0, 1.0}; 302412e9a14SMatthew G. Knepley static PetscReal hex_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 303412e9a14SMatthew G. Knepley -1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0, -1.0, 304412e9a14SMatthew G. Knepley -1.0, 1.0, -1.0, 0.0, 1.0, -1.0, 1.0, 1.0, -1.0, 305412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0, -1.0, 0.0, 306412e9a14SMatthew G. Knepley -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 307412e9a14SMatthew G. Knepley -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 308412e9a14SMatthew G. Knepley -1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 1.0, -1.0, 1.0, 309412e9a14SMatthew G. Knepley -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 310412e9a14SMatthew G. Knepley -1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0}; 311412e9a14SMatthew G. Knepley 312412e9a14SMatthew G. Knepley PetscFunctionBegin; 313412e9a14SMatthew G. Knepley switch (ct) { 314412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nv = 3; *subcellV = seg_v; break; 315412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 6; *subcellV = tri_v; break; 316412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nv = 9; *subcellV = quad_v; break; 317412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 10; *subcellV = tet_v; break; 318412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nv = 27; *subcellV = hex_v; break; 319412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 320412e9a14SMatthew G. Knepley } 321412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 322412e9a14SMatthew G. Knepley } 323412e9a14SMatthew G. Knepley 32496ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerGetCellVertices_ToBox(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 325412e9a14SMatthew G. Knepley { 326412e9a14SMatthew G. Knepley static PetscReal tri_v[] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0/3.0, -1.0/3.0}; 327412e9a14SMatthew G. Knepley static PetscReal tet_v[] = {-1.0, -1.0, -1.0, 0.0, -1.0, -1.0, 1.0, -1.0, -1.0, 328412e9a14SMatthew G. Knepley -1.0, 0.0, -1.0, -1.0/3.0, -1.0/3.0, -1.0, 0.0, 0.0, -1.0, -1.0, 1.0, -1.0, 329412e9a14SMatthew G. Knepley -1.0, -1.0, 0.0, -1.0/3.0, -1.0, -1.0/3.0, 0.0, -1.0, 0.0, 330412e9a14SMatthew G. Knepley -1.0, -1.0/3.0, -1.0/3.0, -1.0/3.0, -1.0/3.0, -1.0/3.0, -1.0, 0.0, 0.0, 331412e9a14SMatthew G. Knepley -1.0, -1.0, 1.0, -0.5, -0.5, -0.5}; 332412e9a14SMatthew G. Knepley PetscErrorCode ierr; 333412e9a14SMatthew G. Knepley 334412e9a14SMatthew G. Knepley PetscFunctionBegin; 335412e9a14SMatthew G. Knepley switch (ct) { 336412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 337412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 338412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 339412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCellVertices_Regular(cr, ct, Nv, subcellV);CHKERRQ(ierr);break; 340412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 7; *subcellV = tri_v; break; 341412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 15; *subcellV = tet_v; break; 342412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 343412e9a14SMatthew G. Knepley } 344412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 345412e9a14SMatthew G. Knepley } 346412e9a14SMatthew G. Knepley 347412e9a14SMatthew G. Knepley /* 348412e9a14SMatthew G. Knepley DMPlexCellRefinerGetCellVertices - Get the set of refined vertices lying in the closure of a reference cell of given type 349412e9a14SMatthew G. Knepley 350412e9a14SMatthew G. Knepley Input Parameters: 351412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 352412e9a14SMatthew G. Knepley - ct - The cell type 353412e9a14SMatthew G. Knepley 354412e9a14SMatthew G. Knepley Output Parameters: 355412e9a14SMatthew G. Knepley + Nv - The number of refined vertices in the closure of the reference cell of given type 356412e9a14SMatthew G. Knepley - subcellV - The coordinates of these vertices in the reference cell 357412e9a14SMatthew G. Knepley 358412e9a14SMatthew G. Knepley Level: developer 359412e9a14SMatthew G. Knepley 360412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetSubcellVertices() 361412e9a14SMatthew G. Knepley */ 362412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCellVertices(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[]) 363412e9a14SMatthew G. Knepley { 364412e9a14SMatthew G. Knepley PetscErrorCode ierr; 365412e9a14SMatthew G. Knepley 366412e9a14SMatthew G. Knepley PetscFunctionBegin; 367412e9a14SMatthew G. Knepley ierr = (*cr->ops->getcellvertices)(cr, ct, Nv, subcellV);CHKERRQ(ierr); 368412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 369412e9a14SMatthew G. Knepley } 370412e9a14SMatthew G. Knepley 371412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 372412e9a14SMatthew G. Knepley { 373412e9a14SMatthew G. Knepley static PetscInt seg_v[] = {0, 1, 1, 2}; 374412e9a14SMatthew G. Knepley static PetscInt tri_v[] = {0, 3, 5, 3, 1, 4, 5, 4, 2, 3, 4, 5}; 375412e9a14SMatthew G. Knepley static PetscInt quad_v[] = {0, 4, 8, 7, 4, 1, 5, 8, 8, 5, 2, 6, 7, 8, 6, 3}; 376412e9a14SMatthew G. Knepley static PetscInt tet_v[] = {0, 3, 1, 6, 3, 2, 4, 8, 1, 4, 5, 7, 6, 8, 7, 9, 377412e9a14SMatthew G. Knepley 1, 6, 3, 7, 8, 4, 3, 7, 7, 3, 1, 4, 7, 3, 8, 6}; 378412e9a14SMatthew G. Knepley static PetscInt hex_v[] = {0, 3, 4, 1, 9, 10, 13, 12, 3, 6, 7, 4, 12, 13, 16, 15, 4, 7, 8, 5, 13, 14, 17, 16, 1, 4 , 5 , 2, 10, 11, 14, 13, 379412e9a14SMatthew G. Knepley 9, 12, 13, 10, 18, 19, 22, 21, 10, 13, 14, 11, 19, 20, 23, 22, 13, 16, 17, 14, 22, 23, 26, 25, 12, 15, 16, 13, 21, 22, 25, 24}; 380412e9a14SMatthew G. Knepley 381412e9a14SMatthew G. Knepley PetscFunctionBegin; 382412e9a14SMatthew G. Knepley if (ct != rct) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Cell type %s does not produce %s", DMPolytopeTypes[ct], DMPolytopeTypes[rct]); 383412e9a14SMatthew G. Knepley switch (ct) { 384412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nv = 2; *subcellV = &seg_v[r*(*Nv)]; break; 385412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nv = 3; *subcellV = &tri_v[r*(*Nv)]; break; 386412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nv = 4; *subcellV = &quad_v[r*(*Nv)]; break; 387412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nv = 4; *subcellV = &tet_v[r*(*Nv)]; break; 388412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nv = 8; *subcellV = &hex_v[r*(*Nv)]; break; 389412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 390412e9a14SMatthew G. Knepley } 391412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 392412e9a14SMatthew G. Knepley } 393412e9a14SMatthew G. Knepley 39496ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerGetSubcellVertices_ToBox(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 395412e9a14SMatthew G. Knepley { 396412e9a14SMatthew G. Knepley static PetscInt tri_v[] = {0, 3, 6, 5, 3, 1, 4, 6, 5, 6, 4, 2}; 397412e9a14SMatthew G. Knepley static PetscInt tet_v[] = {0, 3, 4, 1, 7, 8, 14, 10, 6, 12, 11, 5, 3, 4, 14, 10, 2, 5, 11, 9, 1, 8, 14, 4, 13, 12 , 10, 7, 9, 8, 14, 11}; 398412e9a14SMatthew G. Knepley PetscErrorCode ierr; 399412e9a14SMatthew G. Knepley 400412e9a14SMatthew G. Knepley PetscFunctionBegin; 401412e9a14SMatthew G. Knepley switch (ct) { 402412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 403412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 404412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 405412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetSubcellVertices_Regular(cr, ct, rct, r, Nv, subcellV);CHKERRQ(ierr);break; 406412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 407412e9a14SMatthew G. Knepley if (rct != DM_POLYTOPE_QUADRILATERAL) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Cell type %s does not produce %s", DMPolytopeTypes[ct], DMPolytopeTypes[rct]); 408412e9a14SMatthew G. Knepley *Nv = 4; *subcellV = &tri_v[r*(*Nv)]; break; 409412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 410412e9a14SMatthew G. Knepley if (rct != DM_POLYTOPE_HEXAHEDRON) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Cell type %s does not produce %s", DMPolytopeTypes[ct], DMPolytopeTypes[rct]); 411412e9a14SMatthew G. Knepley *Nv = 8; *subcellV = &tet_v[r*(*Nv)]; break; 412412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]); 413412e9a14SMatthew G. Knepley } 414412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 415412e9a14SMatthew G. Knepley } 416412e9a14SMatthew G. Knepley 417412e9a14SMatthew G. Knepley /* 418412e9a14SMatthew G. Knepley DMPlexCellRefinerGetSubcellVertices - Get the set of refined vertices defining a subcell in the reference cell of given type 419412e9a14SMatthew G. Knepley 420412e9a14SMatthew G. Knepley Input Parameters: 421412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 422412e9a14SMatthew G. Knepley . ct - The cell type 423412e9a14SMatthew G. Knepley . rct - The type of subcell 424412e9a14SMatthew G. Knepley - r - The subcell index 425412e9a14SMatthew G. Knepley 426412e9a14SMatthew G. Knepley Output Parameters: 427412e9a14SMatthew G. Knepley + Nv - The number of refined vertices in the subcell 428412e9a14SMatthew G. Knepley - subcellV - The indices of these vertices in the set of vertices returned by DMPlexCellRefinerGetCellVertices() 429412e9a14SMatthew G. Knepley 430412e9a14SMatthew G. Knepley Level: developer 431412e9a14SMatthew G. Knepley 432412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetCellVertices() 433412e9a14SMatthew G. Knepley */ 434412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[]) 435412e9a14SMatthew G. Knepley { 436412e9a14SMatthew G. Knepley PetscErrorCode ierr; 437412e9a14SMatthew G. Knepley 438412e9a14SMatthew G. Knepley PetscFunctionBegin; 439412e9a14SMatthew G. Knepley ierr = (*cr->ops->getsubcellvertices)(cr, ct, rct, r, Nv, subcellV);CHKERRQ(ierr); 440412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 441412e9a14SMatthew G. Knepley } 442412e9a14SMatthew G. Knepley 443412e9a14SMatthew G. Knepley /* 444412e9a14SMatthew G. Knepley Input Parameters: 445412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner 446412e9a14SMatthew G. Knepley . pct - The cell type of the parent, from whom the new cell is being produced 447412e9a14SMatthew G. Knepley . po - The orientation of the parent cell in its enclosing parent 448412e9a14SMatthew G. Knepley . ct - The type being produced 449412e9a14SMatthew G. Knepley . r - The replica number requested for the produced cell type 450412e9a14SMatthew G. Knepley - o - The relative orientation of the replica 451412e9a14SMatthew G. Knepley 452412e9a14SMatthew G. Knepley Output Parameters: 453412e9a14SMatthew G. Knepley + rnew - The replica number, given the orientation of of the parent 454412e9a14SMatthew G. Knepley - onew - The replica orientation, given the orientation of the parent 455412e9a14SMatthew G. Knepley */ 456412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 457412e9a14SMatthew G. Knepley { 458412e9a14SMatthew G. Knepley PetscErrorCode ierr; 459412e9a14SMatthew G. Knepley 460412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 461412e9a14SMatthew G. Knepley ierr = (*cr->ops->mapsubcells)(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 462412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 463412e9a14SMatthew G. Knepley } 464412e9a14SMatthew G. Knepley 465412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_Regular(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 466412e9a14SMatthew G. Knepley { 467412e9a14SMatthew G. Knepley /* We shift any input orientation in order to make it non-negative 468412e9a14SMatthew 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) 469412e9a14SMatthew G. Knepley The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 470412e9a14SMatthew G. Knepley Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 471412e9a14SMatthew G. Knepley */ 472412e9a14SMatthew G. Knepley PetscInt tri_seg_o[] = {-2, 0, 473412e9a14SMatthew G. Knepley -2, 0, 474412e9a14SMatthew G. Knepley -2, 0, 475412e9a14SMatthew G. Knepley 0, -2, 476412e9a14SMatthew G. Knepley 0, -2, 477412e9a14SMatthew G. Knepley 0, -2}; 478412e9a14SMatthew G. Knepley PetscInt tri_seg_r[] = {1, 0, 2, 479412e9a14SMatthew G. Knepley 0, 2, 1, 480412e9a14SMatthew G. Knepley 2, 1, 0, 481412e9a14SMatthew G. Knepley 0, 1, 2, 482412e9a14SMatthew G. Knepley 1, 2, 0, 483412e9a14SMatthew G. Knepley 2, 0, 1}; 484412e9a14SMatthew G. Knepley PetscInt tri_tri_o[] = {0, 1, 2, -3, -2, -1, 485412e9a14SMatthew G. Knepley 2, 0, 1, -2, -1, -3, 486412e9a14SMatthew G. Knepley 1, 2, 0, -1, -3, -2, 487412e9a14SMatthew G. Knepley -3, -2, -1, 0, 1, 2, 488412e9a14SMatthew G. Knepley -1, -3, -2, 1, 2, 0, 489412e9a14SMatthew G. Knepley -2, -1, -3, 2, 0, 1}; 490412e9a14SMatthew G. Knepley /* orientation if the replica is the center triangle */ 491412e9a14SMatthew G. Knepley PetscInt tri_tri_o_c[] = {2, 0, 1, -2, -1, -3, 492412e9a14SMatthew G. Knepley 1, 2, 0, -1, -3, -2, 493412e9a14SMatthew G. Knepley 0, 1, 2, -3, -2, -1, 494412e9a14SMatthew G. Knepley -3, -2, -1, 0, 1, 2, 495412e9a14SMatthew G. Knepley -1, -3, -2, 1, 2, 0, 496412e9a14SMatthew G. Knepley -2, -1, -3, 2, 0, 1}; 497412e9a14SMatthew G. Knepley PetscInt tri_tri_r[] = {0, 2, 1, 3, 498412e9a14SMatthew G. Knepley 2, 1, 0, 3, 499412e9a14SMatthew G. Knepley 1, 0, 2, 3, 500412e9a14SMatthew G. Knepley 0, 1, 2, 3, 501412e9a14SMatthew G. Knepley 1, 2, 0, 3, 502412e9a14SMatthew G. Knepley 2, 0, 1, 3}; 503412e9a14SMatthew G. Knepley PetscInt quad_seg_r[] = {3, 2, 1, 0, 504412e9a14SMatthew G. Knepley 2, 1, 0, 3, 505412e9a14SMatthew G. Knepley 1, 0, 3, 2, 506412e9a14SMatthew G. Knepley 0, 3, 2, 1, 507412e9a14SMatthew G. Knepley 0, 1, 2, 3, 508412e9a14SMatthew G. Knepley 1, 2, 3, 0, 509412e9a14SMatthew G. Knepley 2, 3, 0, 1, 510412e9a14SMatthew G. Knepley 3, 0, 1, 2}; 511412e9a14SMatthew G. Knepley PetscInt quad_quad_o[] = { 0, 1, 2, 3, -4, -3, -2, -1, 512412e9a14SMatthew G. Knepley 4, 0, 1, 2, -3, -2, -1, -4, 513412e9a14SMatthew G. Knepley 3, 4, 0, 1, -2, -1, -4, -3, 514412e9a14SMatthew G. Knepley 2, 3, 4, 0, -1, -4, -3, -2, 515412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 516412e9a14SMatthew G. Knepley -1, -4, -3, -2, 1, 2, 3, 0, 517412e9a14SMatthew G. Knepley -2, -1, -4, -3, 2, 3, 0, 1, 518412e9a14SMatthew G. Knepley -3, -2, -1, -4, 3, 0, 1, 2}; 519412e9a14SMatthew G. Knepley PetscInt quad_quad_r[] = {0, 3, 2, 1, 520412e9a14SMatthew G. Knepley 3, 2, 1, 0, 521412e9a14SMatthew G. Knepley 2, 1, 0, 3, 522412e9a14SMatthew G. Knepley 1, 0, 3, 2, 523412e9a14SMatthew G. Knepley 0, 1, 2, 3, 524412e9a14SMatthew G. Knepley 1, 2, 3, 0, 525412e9a14SMatthew G. Knepley 2, 3, 0, 1, 526412e9a14SMatthew G. Knepley 3, 0, 1, 2}; 527412e9a14SMatthew G. Knepley PetscInt tquad_tquad_o[] = { 0, 1, -2, -1, 528412e9a14SMatthew G. Knepley 1, 0, -1, -2, 529412e9a14SMatthew G. Knepley -2, -1, 0, 1, 530412e9a14SMatthew G. Knepley -1, -2, 1, 0}; 531412e9a14SMatthew G. Knepley PetscInt tquad_tquad_r[] = {1, 0, 532412e9a14SMatthew G. Knepley 1, 0, 533412e9a14SMatthew G. Knepley 0, 1, 534412e9a14SMatthew G. Knepley 0, 1}; 535412e9a14SMatthew G. Knepley 536412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 537412e9a14SMatthew G. Knepley /* The default is no transformation */ 538412e9a14SMatthew G. Knepley *rnew = r; 539412e9a14SMatthew G. Knepley *onew = o; 540412e9a14SMatthew G. Knepley switch (pct) { 541412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 542412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_SEGMENT) { 543412e9a14SMatthew G. Knepley if (po == 0 || po == -1) {*rnew = r; *onew = o;} 544412e9a14SMatthew G. Knepley else if (po == 1 || po == -2) {*rnew = (r+1)%2; *onew = (o == 0 || o == -1) ? -2 : 0;} 545412e9a14SMatthew G. Knepley else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid orientation %D for segment", po); 546412e9a14SMatthew G. Knepley } 547412e9a14SMatthew G. Knepley break; 548412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 549412e9a14SMatthew G. Knepley switch (ct) { 550412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 551412e9a14SMatthew G. Knepley if (o == -1) o = 0; 552412e9a14SMatthew G. Knepley if (o == -2) o = 1; 553412e9a14SMatthew G. Knepley *onew = tri_seg_o[(po+3)*2+o]; 554412e9a14SMatthew G. Knepley *rnew = tri_seg_r[(po+3)*3+r]; 555412e9a14SMatthew G. Knepley break; 556412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 557412e9a14SMatthew 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]; 558412e9a14SMatthew G. Knepley *rnew = tri_tri_r[(po+3)*4+r]; 559412e9a14SMatthew G. Knepley break; 560412e9a14SMatthew G. Knepley default: break; 561412e9a14SMatthew G. Knepley } 562412e9a14SMatthew G. Knepley break; 563412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 564412e9a14SMatthew G. Knepley switch (ct) { 565412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 566412e9a14SMatthew G. Knepley *onew = o; 567412e9a14SMatthew G. Knepley *rnew = quad_seg_r[(po+4)*4+r]; 568412e9a14SMatthew G. Knepley break; 569412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 570412e9a14SMatthew G. Knepley *onew = quad_quad_o[(po+4)*8+o+4]; 571412e9a14SMatthew G. Knepley *rnew = quad_quad_r[(po+4)*4+r]; 572412e9a14SMatthew G. Knepley break; 573412e9a14SMatthew G. Knepley default: break; 574412e9a14SMatthew G. Knepley } 575412e9a14SMatthew G. Knepley break; 576412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 577412e9a14SMatthew G. Knepley switch (ct) { 578412e9a14SMatthew G. Knepley /* DM_POLYTOPE_POINT_PRISM_TENSOR does not change */ 579412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 580412e9a14SMatthew G. Knepley *onew = tquad_tquad_o[(po+2)*4+o+2]; 581412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 582412e9a14SMatthew G. Knepley break; 583412e9a14SMatthew G. Knepley default: break; 584412e9a14SMatthew G. Knepley } 585412e9a14SMatthew G. Knepley break; 586412e9a14SMatthew G. Knepley default: break; 587412e9a14SMatthew G. Knepley } 588412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 589412e9a14SMatthew G. Knepley } 590412e9a14SMatthew G. Knepley 59196ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerMapSubcells_ToBox(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 592412e9a14SMatthew G. Knepley { 593412e9a14SMatthew G. Knepley PetscErrorCode ierr; 594412e9a14SMatthew G. Knepley /* We shift any input orientation in order to make it non-negative 595412e9a14SMatthew 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) 596412e9a14SMatthew G. Knepley The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po 597412e9a14SMatthew G. Knepley Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po 598412e9a14SMatthew G. Knepley */ 599412e9a14SMatthew G. Knepley PetscInt tri_seg_o[] = {0, -2, 600412e9a14SMatthew G. Knepley 0, -2, 601412e9a14SMatthew G. Knepley 0, -2, 602412e9a14SMatthew G. Knepley 0, -2, 603412e9a14SMatthew G. Knepley 0, -2, 604412e9a14SMatthew G. Knepley 0, -2}; 605412e9a14SMatthew G. Knepley PetscInt tri_seg_r[] = {2, 1, 0, 606412e9a14SMatthew G. Knepley 1, 0, 2, 607412e9a14SMatthew G. Knepley 0, 2, 1, 608412e9a14SMatthew G. Knepley 0, 1, 2, 609412e9a14SMatthew G. Knepley 1, 2, 0, 610412e9a14SMatthew G. Knepley 2, 0, 1}; 611412e9a14SMatthew G. Knepley PetscInt tri_tri_o[] = {0, 1, 2, 3, -4, -3, -2, -1, 612412e9a14SMatthew G. Knepley 3, 0, 1, 2, -3, -2, -1, -4, 613412e9a14SMatthew G. Knepley 1, 2, 3, 0, -1, -4, -3, -2, 614412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 615412e9a14SMatthew G. Knepley -1, -4, -3, -2, 1, 2, 3, 0, 616412e9a14SMatthew G. Knepley -3, -2, -1, -4, 3, 0, 1, 2}; 617412e9a14SMatthew G. Knepley PetscInt tri_tri_r[] = {0, 2, 1, 618412e9a14SMatthew G. Knepley 2, 1, 0, 619412e9a14SMatthew G. Knepley 1, 0, 2, 620412e9a14SMatthew G. Knepley 0, 1, 2, 621412e9a14SMatthew G. Knepley 1, 2, 0, 622412e9a14SMatthew G. Knepley 2, 0, 1}; 623412e9a14SMatthew G. Knepley PetscInt tquad_tquad_o[] = { 0, 1, -2, -1, 624412e9a14SMatthew G. Knepley 1, 0, -1, -2, 625412e9a14SMatthew G. Knepley -2, -1, 0, 1, 626412e9a14SMatthew G. Knepley -1, -2, 1, 0}; 627412e9a14SMatthew G. Knepley PetscInt tquad_tquad_r[] = {1, 0, 628412e9a14SMatthew G. Knepley 1, 0, 629412e9a14SMatthew G. Knepley 0, 1, 630412e9a14SMatthew G. Knepley 0, 1}; 631412e9a14SMatthew G. Knepley PetscInt tquad_quad_o[] = {-2, -1, -4, -3, 2, 3, 0, 1, 632412e9a14SMatthew G. Knepley 1, 2, 3, 0, -1, -4, -3, -2, 633412e9a14SMatthew G. Knepley -4, -3, -2, -1, 0, 1, 2, 3, 634412e9a14SMatthew G. Knepley 1, 0, 3, 2, -3, -4, -1, -2}; 635412e9a14SMatthew G. Knepley 636412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 637412e9a14SMatthew G. Knepley *rnew = r; 638412e9a14SMatthew G. Knepley *onew = o; 639412e9a14SMatthew G. Knepley switch (pct) { 640412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 641412e9a14SMatthew G. Knepley switch (ct) { 642412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 643412e9a14SMatthew G. Knepley if (o == -1) o = 0; 644412e9a14SMatthew G. Knepley if (o == -2) o = 1; 645412e9a14SMatthew G. Knepley *onew = tri_seg_o[(po+3)*2+o]; 646412e9a14SMatthew G. Knepley *rnew = tri_seg_r[(po+3)*3+r]; 647412e9a14SMatthew G. Knepley break; 648412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 649412e9a14SMatthew G. Knepley *onew = tri_tri_o[(po+3)*8+o+4]; 650412e9a14SMatthew G. Knepley /* TODO See sheet, for fixing po == 1 and 2 */ 651412e9a14SMatthew G. Knepley if (po == 2 && r == 2 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+3)%4)+4]; 652412e9a14SMatthew G. Knepley if (po == 2 && r == 2 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+5)%4)]; 653412e9a14SMatthew G. Knepley if (po == 1 && r == 1 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+1)%4)+4]; 654412e9a14SMatthew G. Knepley if (po == 1 && r == 1 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+7)%4)]; 655412e9a14SMatthew G. Knepley if (po == -1 && r == 2 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+3)%4)+4]; 656412e9a14SMatthew G. Knepley if (po == -1 && r == 2 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+5)%4)]; 657412e9a14SMatthew G. Knepley if (po == -2 && r == 1 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+1)%4)+4]; 658412e9a14SMatthew G. Knepley if (po == -2 && r == 1 && o < 0) *onew = tri_tri_o[(po+3)*8+((o+7)%4)]; 659412e9a14SMatthew G. Knepley *rnew = tri_tri_r[(po+3)*3+r]; 660412e9a14SMatthew G. Knepley break; 661412e9a14SMatthew G. Knepley default: break; 662412e9a14SMatthew G. Knepley } 663412e9a14SMatthew G. Knepley break; 664412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 665412e9a14SMatthew G. Knepley switch (ct) { 666412e9a14SMatthew G. Knepley /* DM_POLYTOPE_POINT_PRISM_TENSOR does not change */ 667412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 668412e9a14SMatthew G. Knepley *onew = tquad_tquad_o[(po+2)*4+o+2]; 669412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 670412e9a14SMatthew G. Knepley break; 671412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 672412e9a14SMatthew G. Knepley *onew = tquad_quad_o[(po+2)*8+o+4]; 673412e9a14SMatthew G. Knepley *rnew = tquad_tquad_r[(po+2)*2+r]; 674412e9a14SMatthew G. Knepley break; 675412e9a14SMatthew G. Knepley default: break; 676412e9a14SMatthew G. Knepley } 677412e9a14SMatthew G. Knepley break; 678412e9a14SMatthew G. Knepley default: 679412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapSubcells_Regular(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr); 680412e9a14SMatthew G. Knepley } 681412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 682412e9a14SMatthew G. Knepley } 683412e9a14SMatthew G. Knepley 684412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew) 685412e9a14SMatthew G. Knepley { 686412e9a14SMatthew G. Knepley return DMPlexCellRefinerMapSubcells_Regular(cr, pct, po, ct, r, o, rnew, onew); 687412e9a14SMatthew G. Knepley } 688412e9a14SMatthew G. Knepley 689412e9a14SMatthew G. Knepley /*@ 690412e9a14SMatthew G. Knepley DMPlexCellRefinerRefine - Return a description of the refinement for a given cell type 691412e9a14SMatthew G. Knepley 692412e9a14SMatthew G. Knepley Input Parameter: 693412e9a14SMatthew G. Knepley . source - The cell type for a source point 694412e9a14SMatthew G. Knepley 695412e9a14SMatthew G. Knepley Output Parameter: 696412e9a14SMatthew G. Knepley + Nt - The number of cell types generated by refinement 697412e9a14SMatthew G. Knepley . target - The cell types generated 698412e9a14SMatthew G. Knepley . size - The number of subcells of each type, ordered by dimension 699412e9a14SMatthew G. Knepley . cone - A list of the faces for each subcell of the same type as source 700412e9a14SMatthew G. Knepley - ornt - A list of the face orientations for each subcell of the same type as source 701412e9a14SMatthew G. Knepley 702412e9a14SMatthew G. Knepley Note: The cone array gives the cone of each subcell listed by the first three outputs. For the each cone point, we 703412e9a14SMatthew G. Knepley need the cell type, point identifier, and orientation within the subcell. The orientation is with respect to the canonical 704412e9a14SMatthew G. Knepley division (described in these outputs) of the cell in the original mesh. The point identifier is given by 705412e9a14SMatthew G. Knepley $ the number of cones to be taken, or 0 for the current cell 706412e9a14SMatthew G. Knepley $ the cell cone point number at each level from which it is subdivided 707412e9a14SMatthew G. Knepley $ the replica number r of the subdivision. 708412e9a14SMatthew G. Knepley The orientation is with respect to the canonical cone orientation. For example, the prescription for edge division is 709412e9a14SMatthew G. Knepley $ Nt = 2 710412e9a14SMatthew G. Knepley $ target = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT} 711412e9a14SMatthew G. Knepley $ size = {1, 2} 712412e9a14SMatthew 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} 713412e9a14SMatthew G. Knepley $ ornt = { 0, 0, 0, 0} 714412e9a14SMatthew G. Knepley 715412e9a14SMatthew G. Knepley Level: developer 716412e9a14SMatthew G. Knepley 71796ca5757SLisandro Dalcin .seealso: DMPlexCellRefinerCreate(), DMPlexRefineUniform() 718412e9a14SMatthew G. Knepley @*/ 719412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerRefine(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 720412e9a14SMatthew G. Knepley { 721412e9a14SMatthew G. Knepley PetscErrorCode ierr; 722412e9a14SMatthew G. Knepley 723412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 724412e9a14SMatthew G. Knepley ierr = (*cr->ops->refine)(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 725412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 726412e9a14SMatthew G. Knepley } 727412e9a14SMatthew G. Knepley 728412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Regular(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 729412e9a14SMatthew G. Knepley { 730412e9a14SMatthew G. Knepley /* All vertices remain in the refined mesh */ 731412e9a14SMatthew G. Knepley static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT}; 732412e9a14SMatthew G. Knepley static PetscInt vertexS[] = {1}; 733412e9a14SMatthew G. Knepley static PetscInt vertexC[] = {0}; 734412e9a14SMatthew G. Knepley static PetscInt vertexO[] = {0}; 735412e9a14SMatthew G. Knepley /* Split all edges with a new vertex, making two new 2 edges 736412e9a14SMatthew G. Knepley 0--0--0--1--1 737412e9a14SMatthew G. Knepley */ 738412e9a14SMatthew G. Knepley static DMPolytopeType edgeT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT}; 739412e9a14SMatthew G. Knepley static PetscInt edgeS[] = {1, 2}; 740412e9a14SMatthew 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}; 741412e9a14SMatthew G. Knepley static PetscInt edgeO[] = { 0, 0, 0, 0}; 742412e9a14SMatthew G. Knepley /* Do not split tensor edges */ 743412e9a14SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR}; 744412e9a14SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 745412e9a14SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 746412e9a14SMatthew G. Knepley static PetscInt tedgeO[] = { 0, 0}; 747412e9a14SMatthew 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 | \ 752412e9a14SMatthew G. Knepley 0 1 75375d3a19aSMatthew G. Knepley | C \ 75475d3a19aSMatthew G. Knepley | \ 75575d3a19aSMatthew G. Knepley | \ 75675d3a19aSMatthew G. Knepley 2---1---1 75775d3a19aSMatthew G. Knepley |\ D / \ 758412e9a14SMatthew G. Knepley 1 2 0 0 75975d3a19aSMatthew G. Knepley |A \ / B \ 760412e9a14SMatthew G. Knepley 0-0-0---1---1 76175d3a19aSMatthew G. Knepley */ 762412e9a14SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE}; 763412e9a14SMatthew G. Knepley static PetscInt triS[] = {3, 4}; 764412e9a14SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 765412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 1, 2, 0, 766412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 0, 0, 767412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 768412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 0, 769412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, 770412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2}; 771412e9a14SMatthew G. Knepley static PetscInt triO[] = {0, 0, 772412e9a14SMatthew G. Knepley 0, 0, 773412e9a14SMatthew G. Knepley 0, 0, 774412e9a14SMatthew G. Knepley 0, -2, 0, 775412e9a14SMatthew G. Knepley 0, 0, -2, 776412e9a14SMatthew G. Knepley -2, 0, 0, 777412e9a14SMatthew G. Knepley 0, 0, 0}; 778412e9a14SMatthew G. Knepley /* Add a vertex in the center of each quadrilateral, and 4 edges inside, making 4 new quads. 779412e9a14SMatthew G. Knepley 3----1----2----0----2 780412e9a14SMatthew G. Knepley | | | 781412e9a14SMatthew G. Knepley 0 D 2 C 1 782412e9a14SMatthew G. Knepley | | | 783412e9a14SMatthew G. Knepley 3----3----0----1----1 784412e9a14SMatthew G. Knepley | | | 785412e9a14SMatthew G. Knepley 1 A 0 B 0 786412e9a14SMatthew G. Knepley | | | 787412e9a14SMatthew G. Knepley 0----0----0----1----1 788412e9a14SMatthew G. Knepley */ 789412e9a14SMatthew G. Knepley static DMPolytopeType quadT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 790412e9a14SMatthew G. Knepley static PetscInt quadS[] = {1, 4, 4}; 791412e9a14SMatthew G. Knepley static PetscInt quadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 792412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 793412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 794412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 795412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, 796412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 797412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, 798412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0}; 799412e9a14SMatthew G. Knepley static PetscInt quadO[] = {0, 0, 800412e9a14SMatthew G. Knepley 0, 0, 801412e9a14SMatthew G. Knepley 0, 0, 802412e9a14SMatthew G. Knepley 0, 0, 803412e9a14SMatthew G. Knepley 0, 0, -2, 0, 804412e9a14SMatthew G. Knepley 0, 0, 0, -2, 805412e9a14SMatthew G. Knepley -2, 0, 0, 0, 806412e9a14SMatthew G. Knepley 0, -2, 0, 0}; 807412e9a14SMatthew G. Knepley /* Add 1 edge inside every tensor quad, making 2 new tensor quads 808412e9a14SMatthew G. Knepley 2----2----1----3----3 809412e9a14SMatthew G. Knepley | | | 810412e9a14SMatthew G. Knepley | | | 811412e9a14SMatthew G. Knepley | | | 812412e9a14SMatthew G. Knepley 4 A 6 B 5 813412e9a14SMatthew G. Knepley | | | 814412e9a14SMatthew G. Knepley | | | 815412e9a14SMatthew G. Knepley | | | 816412e9a14SMatthew G. Knepley 0----0----0----1----1 817412e9a14SMatthew G. Knepley */ 818412e9a14SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR}; 819412e9a14SMatthew G. Knepley static PetscInt tquadS[] = {1, 2}; 820412e9a14SMatthew G. Knepley static PetscInt tquadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 821412e9a14SMatthew 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, 822412e9a14SMatthew 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}; 823412e9a14SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 824412e9a14SMatthew G. Knepley 0, 0, 0, 0, 825412e9a14SMatthew G. Knepley 0, 0, 0, 0}; 826412e9a14SMatthew G. Knepley /* Add 1 edge and 8 triangles inside every cell, making 8 new tets 827412e9a14SMatthew 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 828412e9a14SMatthew 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] 829412e9a14SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 830412e9a14SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 831412e9a14SMatthew G. Knepley The first four tets just cut off the corners, using the replica notation for new vertices, 832412e9a14SMatthew G. Knepley [v0, (e0, 0), (e2, 0), (e3, 0)] 833412e9a14SMatthew G. Knepley [(e0, 0), v1, (e1, 0), (e4, 0)] 834412e9a14SMatthew G. Knepley [(e2, 0), (e1, 0), v2, (e5, 0)] 835412e9a14SMatthew G. Knepley [(e3, 0), (e4, 0), (e5, 0), v3 ] 836412e9a14SMatthew G. Knepley The next four tets match a vertex to the newly created faces from cutting off those first tets. 837412e9a14SMatthew G. Knepley [(e2, 0), (e3, 0), (e0, 0), (e5, 0)] 838412e9a14SMatthew G. Knepley [(e4, 0), (e1, 0), (e0, 0), (e5, 0)] 839412e9a14SMatthew G. Knepley [(e5, 0), (e0, 0), (e2, 0), (e1, 0)] 840412e9a14SMatthew G. Knepley [(e5, 0), (e0, 0), (e4, 0), (e3, 0)] 841412e9a14SMatthew 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 842412e9a14SMatthew G. Knepley [(e2, 0), (e0, 0), (e3, 0)] 843412e9a14SMatthew G. Knepley [(e0, 0), (e1, 0), (e4, 0)] 844412e9a14SMatthew G. Knepley [(e2, 0), (e5, 0), (e1, 0)] 845412e9a14SMatthew G. Knepley [(e3, 0), (e4, 0), (e5, 0)] 846412e9a14SMatthew G. Knepley The next four, from the second group of tets, are 847412e9a14SMatthew G. Knepley [(e2, 0), (e0, 0), (e5, 0)] 848412e9a14SMatthew G. Knepley [(e4, 0), (e0, 0), (e5, 0)] 849412e9a14SMatthew G. Knepley [(e0, 0), (e1, 0), (e5, 0)] 850412e9a14SMatthew G. Knepley [(e5, 0), (e3, 0), (e0, 0)] 851412e9a14SMatthew G. Knepley I could write a program to generate these orientations by comparing the faces from GetRawFaces() with my existing table. 852412e9a14SMatthew G. Knepley */ 853412e9a14SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON}; 854412e9a14SMatthew G. Knepley static PetscInt tetS[] = {1, 8, 8}; 855412e9a14SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 2, 2, 1, 0, 856412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 2, 2, 857412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 1, 1, 858412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 1, 0, 1, 859412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 2, 1, 860412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0, 861412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, 862412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 0, 863412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0, 0, 864412e9a14SMatthew 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, 865412e9a14SMatthew 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, 866412e9a14SMatthew 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, 867412e9a14SMatthew 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, 868412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 2, 3, DM_POLYTOPE_TRIANGLE, 0, 4, DM_POLYTOPE_TRIANGLE, 0, 7, 869412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 1, 3, 3, DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 6, 870412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 4, DM_POLYTOPE_TRIANGLE, 0, 6, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 1, 0, 3, 871412e9a14SMatthew G. Knepley DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 7, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 1, 1, 3}; 872412e9a14SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 873412e9a14SMatthew G. Knepley 0, 0, 0, 874412e9a14SMatthew G. Knepley 0, 0, 0, 875412e9a14SMatthew G. Knepley 0, 0, 0, 876412e9a14SMatthew G. Knepley 0, 0, 0, 877412e9a14SMatthew G. Knepley 0, 0, -2, 878412e9a14SMatthew G. Knepley 0, 0, -2, 879412e9a14SMatthew G. Knepley 0, -2, -2, 880412e9a14SMatthew G. Knepley 0, -2, 0, 881412e9a14SMatthew G. Knepley 0, 0, 0, 0, 882412e9a14SMatthew G. Knepley 0, 0, 0, 0, 883412e9a14SMatthew G. Knepley 0, 0, 0, 0, 884412e9a14SMatthew G. Knepley 0, 0, 0, 0, 885412e9a14SMatthew G. Knepley -3, 0, 0, -2, 886412e9a14SMatthew G. Knepley -2, 1, 0, 0, 887412e9a14SMatthew G. Knepley -2, -2, -1, 2, 888412e9a14SMatthew G. Knepley -2, 0, -2, 1}; 889412e9a14SMatthew G. Knepley /* Add a vertex in the center of each cell, add 6 edges and 12 quads inside every cell, making 8 new hexes 890412e9a14SMatthew 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 891412e9a14SMatthew G. Knepley [v0, v1, v2, v3] f0 bottom 892412e9a14SMatthew G. Knepley [v4, v5, v6, v7] f1 top 893412e9a14SMatthew G. Knepley [v0, v3, v5, v4] f2 front 894412e9a14SMatthew G. Knepley [v2, v1, v7, v6] f3 back 895412e9a14SMatthew G. Knepley [v3, v2, v6, v5] f4 right 896412e9a14SMatthew G. Knepley [v0, v4, v7, v1] f5 left 897412e9a14SMatthew G. Knepley The eight hexes are divided into four on the bottom, and four on the top, 898412e9a14SMatthew G. Knepley [v0, (e0, 0), (f0, 0), (e3, 0), (e9, 0), (f2, 0), (c0, 0), (f5, 0)] 899412e9a14SMatthew G. Knepley [(e0, 0), v1, (e1, 0), (f0, 0), (f5, 0), (c0, 0), (f3, 0), (e10, 0)] 900412e9a14SMatthew G. Knepley [(f0, 0), (e1, 0), v2, (e2, 0), (c0, 0), (f4, 0), (e11, 0), (f3, 0)] 901412e9a14SMatthew G. Knepley [(e3, 0), (f0, 0), (e2, 0), v3, (f2, 0), (e8, 0), (f4, 0), (c0, 0)] 902412e9a14SMatthew G. Knepley [(e9, 0), (f5, 0), (c0, 0), (f2, 0), v4, (e4, 0), (f1, 0), (e7, 0)] 903412e9a14SMatthew G. Knepley [(f2, 0), (c0, 0), (f4, 0), (e8, 0), (e4, 0), v5, (e5, 0), (f1, 0)] 904412e9a14SMatthew G. Knepley [(c0, 0), (f3, 0), (e11, 0), (f4, 0), (f1, 0), (e5, 0), v6, (e6, 0)] 905412e9a14SMatthew G. Knepley [(f5, 0), (e10, 0), (f3, 0), (c0, 0), (e7, 0), (f1, 0), (e6, 0), v7] 906412e9a14SMatthew 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, 907412e9a14SMatthew G. Knepley [(e9, 0), (f2, 0), (c0, 0), (f5, 0)] 908412e9a14SMatthew G. Knepley [(f5, 0), (c0, 0), (f3, 0), (e10, 0)] 909412e9a14SMatthew G. Knepley [(c0, 0), (f4, 0), (e11, 0), (f3, 0)] 910412e9a14SMatthew G. Knepley [(f2, 0), (e8, 0), (f4, 0), (c0, 0)] 911412e9a14SMatthew G. Knepley and on the x-z plane, 912412e9a14SMatthew G. Knepley [(f0, 0), (e0, 0), (f5, 0), (c0, 0)] 913412e9a14SMatthew G. Knepley [(c0, 0), (f5, 0), (e7, 0), (f1, 0)] 914412e9a14SMatthew G. Knepley [(f4, 0), (c0, 0), (f1, 0), (e5, 0)] 915412e9a14SMatthew G. Knepley [(e2, 0), (f0, 0), (c0, 0), (f4, 0)] 916412e9a14SMatthew G. Knepley and on the y-z plane, 917412e9a14SMatthew G. Knepley [(e3, 0), (f2, 0), (c0, 0), (f0, 0)] 918412e9a14SMatthew G. Knepley [(f2, 0), (e4, 0), (f1, 0), (c0, 0)] 919412e9a14SMatthew G. Knepley [(c0, 0), (f1, 0), (e6, 0), (f3, 0)] 920412e9a14SMatthew G. Knepley [(f0, 0), (c0, 0), (f3, 0), (e1, 0)] 921412e9a14SMatthew G. Knepley */ 922412e9a14SMatthew G. Knepley static DMPolytopeType hexT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 923412e9a14SMatthew G. Knepley static PetscInt hexS[] = {1, 6, 12, 8}; 924412e9a14SMatthew G. Knepley static PetscInt hexC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 925412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 926412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 927412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 928412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0, 929412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 5, 0, DM_POLYTOPE_POINT, 0, 0, 930412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 1, 5, 0, 931412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 5, 2, 932412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 3, 933412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 2, 934412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 5, 3, DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 0, 0, 935412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 5, DM_POLYTOPE_SEGMENT, 1, 5, 1, DM_POLYTOPE_SEGMENT, 1, 1, 3, DM_POLYTOPE_SEGMENT, 0, 1, 936412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 4, 2, 937412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 0, 938412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 0, 3, 939412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 940412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 3, 941412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1, 942412e9a14SMatthew 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, 943412e9a14SMatthew 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, 944412e9a14SMatthew 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, 945412e9a14SMatthew 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, 946412e9a14SMatthew 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, 947412e9a14SMatthew 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, 948412e9a14SMatthew 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, 949412e9a14SMatthew 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}; 950412e9a14SMatthew G. Knepley static PetscInt hexO[] = {0, 0, 951412e9a14SMatthew G. Knepley 0, 0, 952412e9a14SMatthew G. Knepley 0, 0, 953412e9a14SMatthew G. Knepley 0, 0, 954412e9a14SMatthew G. Knepley 0, 0, 955412e9a14SMatthew G. Knepley 0, 0, 956412e9a14SMatthew G. Knepley 0, 0, -2, -2, 957412e9a14SMatthew G. Knepley 0, -2, -2, 0, 958412e9a14SMatthew G. Knepley -2, -2, 0, 0, 959412e9a14SMatthew G. Knepley -2, 0, 0, -2, 960412e9a14SMatthew G. Knepley -2, 0, 0, -2, 961412e9a14SMatthew G. Knepley -2, -2, 0, 0, 962412e9a14SMatthew G. Knepley 0, -2, -2, 0, 963412e9a14SMatthew G. Knepley 0, 0, -2, -2, 964412e9a14SMatthew G. Knepley 0, 0, -2, -2, 965412e9a14SMatthew G. Knepley -2, 0, 0, -2, 966412e9a14SMatthew G. Knepley -2, -2, 0, 0, 967412e9a14SMatthew G. Knepley 0, -2, -2, 0, 968412e9a14SMatthew G. Knepley 0, 0, 0, 0, -4, 0, 969412e9a14SMatthew G. Knepley 0, 0, -1, 0, -4, 0, 970412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 971412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 972412e9a14SMatthew G. Knepley -4, 0, 0, 0, -4, 0, 973412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, 0, 974412e9a14SMatthew G. Knepley -4, 0, -1, 0, 0, 0, 975412e9a14SMatthew G. Knepley -4, 0, -1, 0, -4, 0}; 976412e9a14SMatthew G. Knepley /* Add 3 quads inside every triangular prism, making 4 new prisms. */ 977412e9a14SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_TRI_PRISM}; 978412e9a14SMatthew G. Knepley static PetscInt tripS[] = {3, 4, 6, 8}; 979412e9a14SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 3, 0, 980412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 1, 4, 0, 981412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 1, 2, 0, 982412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 4, 1, 983412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 0, 984412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, 985412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 2, 986412e9a14SMatthew 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, 987412e9a14SMatthew 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, 988412e9a14SMatthew 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, 989412e9a14SMatthew 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, 990412e9a14SMatthew 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, 991412e9a14SMatthew 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, 992412e9a14SMatthew 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, 993412e9a14SMatthew 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, 994412e9a14SMatthew 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, 995412e9a14SMatthew 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, 996412e9a14SMatthew 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, 997412e9a14SMatthew 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, 998412e9a14SMatthew 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, 999412e9a14SMatthew 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}; 1000412e9a14SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 1001412e9a14SMatthew G. Knepley 0, 0, 1002412e9a14SMatthew G. Knepley 0, 0, 1003412e9a14SMatthew G. Knepley 0, -2, -2, 1004412e9a14SMatthew G. Knepley -2, 0, -2, 1005412e9a14SMatthew G. Knepley -2, -2, 0, 1006412e9a14SMatthew G. Knepley 0, 0, 0, 1007412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1008412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1009412e9a14SMatthew G. Knepley -2, 0, -2, -2, 1010412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1011412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1012412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1013412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1014412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1015412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 1016412e9a14SMatthew G. Knepley 2, 0, 0, 0, 0, 1017412e9a14SMatthew G. Knepley -3, 0, 0, -1, 0, 1018412e9a14SMatthew G. Knepley -3, 0, 0, 0, -1, 1019412e9a14SMatthew G. Knepley -3, 0, -1, 0, 0, 1020412e9a14SMatthew G. Knepley -3, 0, 0, 0, 0}; 1021412e9a14SMatthew G. Knepley /* Add 3 tensor quads inside every tensor triangular prism, making 4 new prisms. 1022412e9a14SMatthew G. Knepley 2 1023412e9a14SMatthew G. Knepley |\ 1024412e9a14SMatthew G. Knepley | \ 1025412e9a14SMatthew G. Knepley | \ 1026412e9a14SMatthew G. Knepley 0---1 102775d3a19aSMatthew G. Knepley 1028412e9a14SMatthew G. Knepley 2 102975d3a19aSMatthew G. Knepley 1030412e9a14SMatthew G. Knepley 0 1 103175d3a19aSMatthew G. Knepley 1032412e9a14SMatthew G. Knepley 2 1033412e9a14SMatthew G. Knepley |\ 1034412e9a14SMatthew G. Knepley | \ 1035412e9a14SMatthew G. Knepley | \ 1036412e9a14SMatthew G. Knepley 0---1 1037412e9a14SMatthew G. Knepley */ 1038412e9a14SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_TRI_PRISM_TENSOR}; 1039412e9a14SMatthew G. Knepley static PetscInt ttripS[] = {3, 4}; 1040412e9a14SMatthew 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, 1041412e9a14SMatthew 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, 1042412e9a14SMatthew 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, 1043412e9a14SMatthew 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, 1044412e9a14SMatthew 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, 1045412e9a14SMatthew 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, 1046412e9a14SMatthew 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}; 1047412e9a14SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 0, 0, 1048412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1049412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1050412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1051412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1052412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 1053412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0}; 1054412e9a14SMatthew G. Knepley /* Add 1 edge and 4 tensor quads inside every tensor quad prism, making 4 new prisms. */ 1055412e9a14SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1056412e9a14SMatthew G. Knepley static PetscInt tquadpS[] = {1, 4, 4}; 1057412e9a14SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1058412e9a14SMatthew 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, 1059412e9a14SMatthew 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, 1060412e9a14SMatthew 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, 1061412e9a14SMatthew 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, 1062412e9a14SMatthew 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, 1063412e9a14SMatthew 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, 1064412e9a14SMatthew 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, 1065412e9a14SMatthew 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}; 1066412e9a14SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 1067412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1068412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1069412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1070412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1071412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1072412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1073412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1074412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 107575d3a19aSMatthew G. Knepley 1076412e9a14SMatthew G. Knepley PetscFunctionBegin; 1077412e9a14SMatthew G. Knepley switch (source) { 1078412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break; 1079412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: *Nt = 2; *target = edgeT; *size = edgeS; *cone = edgeC; *ornt = edgeO; break; 1080412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 1081412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 2; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1082412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: *Nt = 3; *target = quadT; *size = quadS; *cone = quadC; *ornt = quadO; break; 1083412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 2; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 1084412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 3; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1085412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: *Nt = 4; *target = hexT; *size = hexS; *cone = hexC; *ornt = hexO; break; 1086412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1087412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 2; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 1088412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 1089412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1090412e9a14SMatthew G. Knepley } 1091412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1092412e9a14SMatthew G. Knepley } 109375d3a19aSMatthew G. Knepley 109496ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerRefine_ToBox(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 1095412e9a14SMatthew G. Knepley { 1096412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1097412e9a14SMatthew G. Knepley /* Change tensor edges to segments */ 1098412e9a14SMatthew G. Knepley static DMPolytopeType tedgeT[] = {DM_POLYTOPE_SEGMENT}; 1099412e9a14SMatthew G. Knepley static PetscInt tedgeS[] = {1}; 1100412e9a14SMatthew G. Knepley static PetscInt tedgeC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}; 1101412e9a14SMatthew G. Knepley static PetscInt tedgeO[] = { 0, 0}; 1102412e9a14SMatthew 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 | \ 1108412e9a14SMatthew G. Knepley 0 1 1109412e9a14SMatthew G. Knepley | \ 1110e5337592SStefano Zampini | \ 1111e5337592SStefano Zampini 2 1 1112e5337592SStefano Zampini |\ / \ 1113e5337592SStefano Zampini | 2 1 \ 1114e5337592SStefano Zampini | \ / \ 1115412e9a14SMatthew G. Knepley 1 | 0 1116e5337592SStefano Zampini | 0 \ 1117e5337592SStefano Zampini | | \ 1118412e9a14SMatthew G. Knepley | | \ 1119412e9a14SMatthew G. Knepley 0-0-0-----1-----1 1120e5337592SStefano Zampini */ 1121412e9a14SMatthew G. Knepley static DMPolytopeType triT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 1122412e9a14SMatthew G. Knepley static PetscInt triS[] = {1, 3, 3}; 1123412e9a14SMatthew G. Knepley static PetscInt triC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1124412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1125412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1126412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 1127412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1128412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0}; 1129412e9a14SMatthew G. Knepley static PetscInt triO[] = {0, 0, 1130412e9a14SMatthew G. Knepley 0, 0, 1131412e9a14SMatthew G. Knepley 0, 0, 1132412e9a14SMatthew G. Knepley 0, 0, -2, 0, 1133412e9a14SMatthew G. Knepley 0, 0, 0, -2, 1134412e9a14SMatthew G. Knepley 0, -2, 0, 0}; 1135412e9a14SMatthew G. Knepley /* Add 1 edge inside every tensor quad, making 2 new quadrilaterals 1136412e9a14SMatthew G. Knepley 2----2----1----3----3 11374330a3fcSStefano Zampini | | | 11384330a3fcSStefano Zampini | | | 11394330a3fcSStefano Zampini | | | 1140412e9a14SMatthew G. Knepley 4 A 6 B 5 11414330a3fcSStefano Zampini | | | 1142412e9a14SMatthew G. Knepley | | | 1143412e9a14SMatthew G. Knepley | | | 1144412e9a14SMatthew G. Knepley 0----0----0----1----1 11454330a3fcSStefano Zampini */ 1146412e9a14SMatthew G. Knepley static DMPolytopeType tquadT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL}; 1147412e9a14SMatthew G. Knepley static PetscInt tquadS[] = {1, 2}; 1148412e9a14SMatthew G. Knepley static PetscInt tquadC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1149412e9a14SMatthew G. Knepley /* TODO Fix these */ 1150412e9a14SMatthew 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, 1151412e9a14SMatthew 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}; 1152412e9a14SMatthew G. Knepley static PetscInt tquadO[] = {0, 0, 1153412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1154412e9a14SMatthew G. Knepley 0, 0, -2, -2}; 1155412e9a14SMatthew G. Knepley /* Add 6 triangles inside every cell, making 4 new hexs 1156412e9a14SMatthew G. Knepley TODO: Need different SubcellMap(). Need to make a struct with the function pointers in it 1157412e9a14SMatthew 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 1158412e9a14SMatthew 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] 1159412e9a14SMatthew G. Knepley called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are 1160412e9a14SMatthew G. Knepley [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3] 1161412e9a14SMatthew G. Knepley We make a new hex in each corner 1162412e9a14SMatthew G. Knepley [v0, (e0, 0), (f0, 0), (e2, 0), (e3, 0), (f2, 0), (c0, 0), (f1, 0)] 1163412e9a14SMatthew G. Knepley [v1, (e4, 0), (f3, 0), (e1, 0), (e0, 0), (f0, 0), (c0, 0), (f1, 0)] 1164412e9a14SMatthew G. Knepley [v2, (e1, 0), (f3, 0), (e5, 0), (e2, 0), (f2, 0), (c0, 0), (f0, 0)] 1165412e9a14SMatthew G. Knepley [v3, (e4, 0), (f1, 0), (e3, 0), (e5, 0), (f2, 0), (c0, 0), (f3, 0)] 1166412e9a14SMatthew G. Knepley We create a new face for each edge 1167412e9a14SMatthew G. Knepley [(e3, 0), (f2, 0), (c0, 0), (f1, 0)] 1168412e9a14SMatthew G. Knepley [(f0, 0), (e0, 0), (f1, 0), (c0, 0)] 1169412e9a14SMatthew G. Knepley [(e2, 0), (f0, 0), (c0, 0), (f2, 0)] 1170412e9a14SMatthew G. Knepley [(f3, 0), (e4, 0), (f1, 0), (c0, 0)] 1171412e9a14SMatthew G. Knepley [(e1, 0), (f3, 0), (c0, 0), (f0, 0)] 1172412e9a14SMatthew G. Knepley [(e5, 0), (f3, 0), (c0, 0), (f2, 0)] 1173412e9a14SMatthew 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 */ 1175412e9a14SMatthew G. Knepley static DMPolytopeType tetT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1176412e9a14SMatthew G. Knepley static PetscInt tetS[] = {1, 4, 6, 4}; 1177412e9a14SMatthew G. Knepley static PetscInt tetC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1178412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1179412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1180412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1181412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, 1182412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, 1183412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1184412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 3, 1185412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1, 1186412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 1, 1187412e9a14SMatthew 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, 1188412e9a14SMatthew 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, 1189412e9a14SMatthew 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, 1190412e9a14SMatthew 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}; 1191412e9a14SMatthew G. Knepley static PetscInt tetO[] = {0, 0, 1192412e9a14SMatthew G. Knepley 0, 0, 1193412e9a14SMatthew G. Knepley 0, 0, 1194412e9a14SMatthew G. Knepley 0, 0, 1195412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1196412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1197412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1198412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1199412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1200412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1201412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, 0, 1202412e9a14SMatthew G. Knepley 1, -1, 1, 0, 0, 3, 1203412e9a14SMatthew G. Knepley 0, -4, 1, -1, 0, 3, 1204412e9a14SMatthew G. Knepley 1, -4, 3, -2, -4, 3}; 1205412e9a14SMatthew G. Knepley /* Add 3 quads inside every triangular prism, making 4 new prisms. */ 1206412e9a14SMatthew G. Knepley static DMPolytopeType tripT[] = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1207412e9a14SMatthew G. Knepley static PetscInt tripS[] = {1, 5, 9, 6}; 1208412e9a14SMatthew G. Knepley static PetscInt tripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0, 1209412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0, 1210412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0, 1211412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0, 1212412e9a14SMatthew G. Knepley DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0, 1213412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 1, 1214412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 2, 1215412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, 1216412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 0, 1217412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 1, 3, 0, 1218412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 1, 4, 0, 1219412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 2, 1220412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 3, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 3, 2, 1221412e9a14SMatthew G. Knepley DM_POLYTOPE_SEGMENT, 0, 4, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 4, 2, 1222412e9a14SMatthew 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, 1223412e9a14SMatthew 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, 1224412e9a14SMatthew 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, 1225412e9a14SMatthew 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, 1226412e9a14SMatthew 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, 1227412e9a14SMatthew 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}; 1228412e9a14SMatthew G. Knepley static PetscInt tripO[] = {0, 0, 1229412e9a14SMatthew G. Knepley 0, 0, 1230412e9a14SMatthew G. Knepley 0, 0, 1231412e9a14SMatthew G. Knepley 0, 0, 1232412e9a14SMatthew G. Knepley 0, 0, 1233412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1234412e9a14SMatthew G. Knepley -2, 0, 0, -2, 1235412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1236412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1237412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1238412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1239412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1240412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1241412e9a14SMatthew G. Knepley 0, -2, -2, 0, 1242412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 1, 1243412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -4, 1244412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 1, 1245412e9a14SMatthew G. Knepley -4, 0, 0, -1, 0, 1, 1246412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, -4, 1247412e9a14SMatthew G. Knepley -4, 0, 0, 0, -1, 1}; 1248412e9a14SMatthew G. Knepley /* Add 3 tensor quads inside every tensor triangular prism, making 4 new tensor triangular prisms. 1249412e9a14SMatthew G. Knepley 2 1250412e9a14SMatthew G. Knepley |\ 1251412e9a14SMatthew G. Knepley | \ 1252412e9a14SMatthew G. Knepley | \ 1253412e9a14SMatthew G. Knepley 0---1 125475d3a19aSMatthew G. Knepley 1255412e9a14SMatthew G. Knepley 2 125675d3a19aSMatthew G. Knepley 1257412e9a14SMatthew G. Knepley 0 1 125875d3a19aSMatthew G. Knepley 1259412e9a14SMatthew G. Knepley 2 1260412e9a14SMatthew G. Knepley |\ 1261412e9a14SMatthew G. Knepley | \ 1262412e9a14SMatthew G. Knepley | \ 1263412e9a14SMatthew G. Knepley 0---1 126475d3a19aSMatthew G. Knepley */ 1265412e9a14SMatthew G. Knepley static DMPolytopeType ttripT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1266412e9a14SMatthew G. Knepley static PetscInt ttripS[] = {1, 3, 3}; 1267412e9a14SMatthew G. Knepley static PetscInt ttripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1268412e9a14SMatthew 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, 1269412e9a14SMatthew 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, 1270412e9a14SMatthew 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, 1271412e9a14SMatthew 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, 1272412e9a14SMatthew 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, 1273412e9a14SMatthew 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}; 1274412e9a14SMatthew G. Knepley static PetscInt ttripO[] = {0, 0, 1275412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1276412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1277412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1278412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1279412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1280412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 1281412e9a14SMatthew G. Knepley /* TODO Add 3 quads inside every tensor triangular prism, making 4 new triangular prisms. 1282412e9a14SMatthew G. Knepley 2 1283412e9a14SMatthew G. Knepley |\ 1284412e9a14SMatthew G. Knepley | \ 1285412e9a14SMatthew G. Knepley | \ 1286412e9a14SMatthew G. Knepley 0---1 128775d3a19aSMatthew G. Knepley 1288412e9a14SMatthew G. Knepley 2 128975d3a19aSMatthew G. Knepley 1290412e9a14SMatthew G. Knepley 0 1 129175d3a19aSMatthew G. Knepley 1292412e9a14SMatthew G. Knepley 2 1293412e9a14SMatthew G. Knepley |\ 1294412e9a14SMatthew G. Knepley | \ 1295412e9a14SMatthew G. Knepley | \ 1296412e9a14SMatthew G. Knepley 0---1 1297a97b51b8SMatthew G. Knepley */ 1298412e9a14SMatthew G. Knepley static DMPolytopeType ctripT[] = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON}; 1299412e9a14SMatthew G. Knepley static PetscInt ctripS[] = {1, 3, 3}; 1300412e9a14SMatthew G. Knepley static PetscInt ctripC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1301412e9a14SMatthew 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, 1302412e9a14SMatthew 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, 1303412e9a14SMatthew 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, 1304412e9a14SMatthew 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, 1305412e9a14SMatthew 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, 1306412e9a14SMatthew 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}; 1307412e9a14SMatthew G. Knepley static PetscInt ctripO[] = {0, 0, 1308412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1309412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1310412e9a14SMatthew G. Knepley 0, 0, -2, -2, 1311412e9a14SMatthew G. Knepley -4, 0, 0, -1, 0, 1, 1312412e9a14SMatthew G. Knepley -4, 0, 0, 0, 0, -4, 1313412e9a14SMatthew G. Knepley -4, 0, 0, 0, -1, 1}; 1314412e9a14SMatthew G. Knepley /* Add 1 edge and 4 quads inside every tensor quad prism, making 4 new hexahedra. */ 1315412e9a14SMatthew G. Knepley static DMPolytopeType tquadpT[] = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR}; 1316412e9a14SMatthew G. Knepley static PetscInt tquadpS[] = {1, 4, 4}; 1317412e9a14SMatthew G. Knepley static PetscInt tquadpC[] = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0, 1318412e9a14SMatthew 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, 1319412e9a14SMatthew 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, 1320412e9a14SMatthew 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, 1321412e9a14SMatthew 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, 1322412e9a14SMatthew 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, 1323412e9a14SMatthew 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, 1324412e9a14SMatthew 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, 1325412e9a14SMatthew 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}; 1326412e9a14SMatthew G. Knepley static PetscInt tquadpO[] = {0, 0, 1327412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1328412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1329412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1330412e9a14SMatthew G. Knepley 0, 0, 0, 0, 1331412e9a14SMatthew G. Knepley 0, 0, 0, 0, -1, 0, 1332412e9a14SMatthew G. Knepley 0, 0, 0, 0, 0, -1, 1333412e9a14SMatthew G. Knepley 0, 0, -1, 0, 0, 0, 1334412e9a14SMatthew G. Knepley 0, 0, 0, -1, 0, 0}; 1335412e9a14SMatthew G. Knepley PetscBool convertTensor = PETSC_TRUE; 1336a97b51b8SMatthew G. Knepley 1337412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 1338412e9a14SMatthew G. Knepley if (convertTensor) { 1339412e9a14SMatthew G. Knepley switch (source) { 1340412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1341412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1342412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1343412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1344412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1345a97b51b8SMatthew G. Knepley break; 1346412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT; *size = tedgeS; *cone = tedgeC; *ornt = tedgeO; break; 1347412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: *Nt = 2; *target = tquadT; *size = tquadS; *cone = tquadC; *ornt = tquadO; break; 1348412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 3; *target = ctripT; *size = ctripS; *cone = ctripC; *ornt = ctripO; break; 1349412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break; 1350412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1351412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1352412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1353412e9a14SMatthew 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 { 1356412e9a14SMatthew G. Knepley switch (source) { 1357412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1358412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1359412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1360412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1361412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1362412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1363412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1364412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1365b5da9499SMatthew G. Knepley break; 1366412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: *Nt = 3; *target = triT; *size = triS; *cone = triC; *ornt = triO; break; 1367412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: *Nt = 4; *target = tetT; *size = tetS; *cone = tetC; *ornt = tetO; break; 1368412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: *Nt = 4; *target = tripT; *size = tripS; *cone = tripC; *ornt = tripO; break; 1369412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: *Nt = 3; *target = ttripT; *size = ttripS; *cone = ttripC; *ornt = ttripO; break; 1370412e9a14SMatthew 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 1376412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[]) 137775d3a19aSMatthew G. Knepley { 1378412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1379412e9a14SMatthew G. Knepley 1380412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 1381412e9a14SMatthew G. Knepley switch (source) { 1382412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT: 1383412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1384412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1385412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1386412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 1387412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1388412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 1389412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1390412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 1391412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1392412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1393412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr); 1394412e9a14SMatthew G. Knepley break; 1395412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]); 1396412e9a14SMatthew G. Knepley } 1397412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1398412e9a14SMatthew G. Knepley } 1399412e9a14SMatthew G. Knepley 1400412e9a14SMatthew G. Knepley static PetscErrorCode CellRefinerCreateOffset_Internal(DMPlexCellRefiner cr, PetscInt ctOrder[], PetscInt ctStart[], PetscInt **offset) 1401412e9a14SMatthew G. Knepley { 1402412e9a14SMatthew G. Knepley PetscInt c, cN, *off; 140375d3a19aSMatthew G. Knepley PetscErrorCode ierr; 140475d3a19aSMatthew G. Knepley 140575d3a19aSMatthew G. Knepley PetscFunctionBegin; 1406412e9a14SMatthew G. Knepley ierr = PetscCalloc1(DM_NUM_POLYTOPES*DM_NUM_POLYTOPES, &off);CHKERRQ(ierr); 1407412e9a14SMatthew G. Knepley for (c = DM_POLYTOPE_POINT; c < DM_NUM_POLYTOPES; ++c) { 1408412e9a14SMatthew G. Knepley const DMPolytopeType ct = (DMPolytopeType) c; 1409412e9a14SMatthew G. Knepley for (cN = DM_POLYTOPE_POINT; cN < DM_NUM_POLYTOPES; ++cN) { 1410412e9a14SMatthew G. Knepley const DMPolytopeType ctNew = (DMPolytopeType) cN; 1411412e9a14SMatthew G. Knepley DMPolytopeType *rct; 1412412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 1413412e9a14SMatthew G. Knepley PetscInt Nct, n, i; 1414412e9a14SMatthew G. Knepley 1415412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ct) < 0 || DMPolytopeTypeGetDim(ctNew) < 0) {off[ct*DM_NUM_POLYTOPES+ctNew] = -1; break;} 1416412e9a14SMatthew G. Knepley off[ct*DM_NUM_POLYTOPES+ctNew] = 0; 1417412e9a14SMatthew G. Knepley for (i = DM_POLYTOPE_POINT; i < DM_NUM_POLYTOPES; ++i) { 1418412e9a14SMatthew G. Knepley const DMPolytopeType ict = (DMPolytopeType) ctOrder[i]; 1419412e9a14SMatthew G. Knepley const DMPolytopeType ictn = (DMPolytopeType) ctOrder[i+1]; 1420412e9a14SMatthew G. Knepley 1421412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ict, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 1422412e9a14SMatthew G. Knepley if (ict == ct) { 1423412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) break; 1424412e9a14SMatthew G. Knepley if (n == Nct) off[ct*DM_NUM_POLYTOPES+ctNew] = -1; 1425412e9a14SMatthew G. Knepley break; 1426412e9a14SMatthew G. Knepley } 1427412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) off[ct*DM_NUM_POLYTOPES+ctNew] += (ctStart[ictn]-ctStart[ict]) * rsize[n]; 1428412e9a14SMatthew G. Knepley } 1429412e9a14SMatthew G. Knepley } 1430412e9a14SMatthew G. Knepley } 1431412e9a14SMatthew G. Knepley *offset = off; 1432412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1433412e9a14SMatthew G. Knepley } 1434412e9a14SMatthew G. Knepley 1435412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetStarts(DMPlexCellRefiner cr, const PetscInt ctStart[], const PetscInt ctStartNew[]) 1436412e9a14SMatthew G. Knepley { 1437412e9a14SMatthew G. Knepley const PetscInt ctSize = DM_NUM_POLYTOPES+1; 1438412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1439412e9a14SMatthew G. Knepley 1440412e9a14SMatthew G. Knepley PetscFunctionBegin; 1441412e9a14SMatthew G. Knepley if (cr->setupcalled) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_ARG_WRONGSTATE, "Must call this function before DMPlexCellRefinerSetUp()"); 1442412e9a14SMatthew G. Knepley ierr = PetscCalloc2(ctSize, &cr->ctStart, ctSize, &cr->ctStartNew);CHKERRQ(ierr); 1443412e9a14SMatthew G. Knepley ierr = PetscArraycpy(cr->ctStart, ctStart, ctSize);CHKERRQ(ierr); 1444412e9a14SMatthew G. Knepley ierr = PetscArraycpy(cr->ctStartNew, ctStartNew, ctSize);CHKERRQ(ierr); 1445412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1446412e9a14SMatthew G. Knepley } 1447412e9a14SMatthew G. Knepley 1448412e9a14SMatthew G. Knepley /* Construct cell type order since we must loop over cell types in depth order */ 1449412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCreateCellTypeOrder_Internal(DMPolytopeType ctCell, PetscInt *ctOrder[], PetscInt *ctOrderInv[]) 1450412e9a14SMatthew G. Knepley { 1451412e9a14SMatthew G. Knepley PetscInt *ctO, *ctOInv; 1452412e9a14SMatthew G. Knepley PetscInt c, d, off = 0; 1453412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1454412e9a14SMatthew G. Knepley 1455412e9a14SMatthew G. Knepley PetscFunctionBegin; 1456412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctO, DM_NUM_POLYTOPES+1, &ctOInv);CHKERRQ(ierr); 1457412e9a14SMatthew G. Knepley for (d = 3; d >= DMPolytopeTypeGetDim(ctCell); --d) { 1458412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1459412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue; 1460412e9a14SMatthew G. Knepley ctO[off++] = c; 1461412e9a14SMatthew G. Knepley } 1462412e9a14SMatthew G. Knepley } 1463412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ctCell) != 0) { 1464412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1465412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != 0) continue; 1466412e9a14SMatthew G. Knepley ctO[off++] = c; 1467412e9a14SMatthew G. Knepley } 1468412e9a14SMatthew G. Knepley } 1469412e9a14SMatthew G. Knepley for (d = DMPolytopeTypeGetDim(ctCell)-1; d > 0; --d) { 1470412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1471412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue; 1472412e9a14SMatthew G. Knepley ctO[off++] = c; 1473412e9a14SMatthew G. Knepley } 1474412e9a14SMatthew G. Knepley } 1475412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1476412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim((DMPolytopeType) c) >= 0) continue; 1477412e9a14SMatthew G. Knepley ctO[off++] = c; 1478412e9a14SMatthew G. Knepley } 1479412e9a14SMatthew G. Knepley if (off != DM_NUM_POLYTOPES+1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid offset %D for cell type order", off); 1480412e9a14SMatthew G. Knepley for (c = 0; c <= DM_NUM_POLYTOPES; ++c) { 1481412e9a14SMatthew G. Knepley ctOInv[ctO[c]] = c; 1482412e9a14SMatthew G. Knepley } 1483412e9a14SMatthew G. Knepley *ctOrder = ctO; 1484412e9a14SMatthew G. Knepley *ctOrderInv = ctOInv; 1485412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1486412e9a14SMatthew G. Knepley } 1487412e9a14SMatthew G. Knepley 1488412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerSetUp(DMPlexCellRefiner cr) 1489412e9a14SMatthew G. Knepley { 1490412e9a14SMatthew G. Knepley DM dm = cr->dm; 1491412e9a14SMatthew G. Knepley DMPolytopeType ctCell; 1492412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p, c; 1493412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1494412e9a14SMatthew G. Knepley 1495412e9a14SMatthew G. Knepley PetscFunctionBegin; 1496412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 1497412e9a14SMatthew G. Knepley if (cr->setupcalled) PetscFunctionReturn(0); 1498412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 1499412e9a14SMatthew G. Knepley if (pEnd > pStart) {ierr = DMPlexGetCellType(dm, 0, &ctCell);CHKERRQ(ierr);} 1500412e9a14SMatthew G. Knepley else { 1501412e9a14SMatthew G. Knepley PetscInt dim; 1502a57030b0SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1503412e9a14SMatthew G. Knepley switch (dim) { 1504412e9a14SMatthew G. Knepley case 0: ctCell = DM_POLYTOPE_POINT;break; 1505412e9a14SMatthew G. Knepley case 1: ctCell = DM_POLYTOPE_SEGMENT;break; 1506412e9a14SMatthew G. Knepley case 2: ctCell = DM_POLYTOPE_TRIANGLE;break; 1507412e9a14SMatthew G. Knepley case 3: ctCell = DM_POLYTOPE_TETRAHEDRON;break; 1508412e9a14SMatthew G. Knepley default: ctCell = DM_POLYTOPE_TETRAHEDRON; 1509412e9a14SMatthew G. Knepley } 1510412e9a14SMatthew G. Knepley } 1511412e9a14SMatthew G. Knepley ierr = DMPlexCreateCellTypeOrder_Internal(ctCell, &cr->ctOrder, &cr->ctOrderInv);CHKERRQ(ierr); 1512412e9a14SMatthew G. Knepley /* Construct sizes and offsets for each cell type */ 1513412e9a14SMatthew G. Knepley if (!cr->ctStart) { 1514412e9a14SMatthew G. Knepley PetscInt *ctS, *ctSN, *ctC, *ctCN; 1515412e9a14SMatthew G. Knepley 1516412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctS, DM_NUM_POLYTOPES+1, &ctSN);CHKERRQ(ierr); 1517412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctC, DM_NUM_POLYTOPES+1, &ctCN);CHKERRQ(ierr); 1518412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 1519412e9a14SMatthew G. Knepley DMPolytopeType ct; 1520412e9a14SMatthew G. Knepley DMPolytopeType *rct; 1521412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 1522412e9a14SMatthew G. Knepley PetscInt Nct, n; 1523412e9a14SMatthew G. Knepley 1524412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 1525412e9a14SMatthew G. Knepley if ((PetscInt) ct < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No cell type for point %D", p); 1526412e9a14SMatthew G. Knepley ++ctC[ct]; 1527412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 1528412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) ctCN[rct[n]] += rsize[n]; 1529412e9a14SMatthew G. Knepley } 1530412e9a14SMatthew G. Knepley for (c = 0; c < DM_NUM_POLYTOPES; ++c) { 1531412e9a14SMatthew G. Knepley const PetscInt ct = cr->ctOrder[c]; 1532412e9a14SMatthew G. Knepley const PetscInt ctn = cr->ctOrder[c+1]; 1533412e9a14SMatthew G. Knepley 1534412e9a14SMatthew G. Knepley ctS[ctn] = ctS[ct] + ctC[ct]; 1535412e9a14SMatthew G. Knepley ctSN[ctn] = ctSN[ct] + ctCN[ct]; 1536412e9a14SMatthew G. Knepley } 1537412e9a14SMatthew G. Knepley ierr = PetscFree2(ctC, ctCN);CHKERRQ(ierr); 1538412e9a14SMatthew G. Knepley cr->ctStart = ctS; 1539412e9a14SMatthew G. Knepley cr->ctStartNew = ctSN; 1540412e9a14SMatthew G. Knepley } 1541412e9a14SMatthew G. Knepley ierr = CellRefinerCreateOffset_Internal(cr, cr->ctOrder, cr->ctStart, &cr->offset);CHKERRQ(ierr); 1542412e9a14SMatthew G. Knepley cr->setupcalled = PETSC_TRUE; 1543412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1544412e9a14SMatthew G. Knepley } 1545412e9a14SMatthew G. Knepley 1546412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView_Ascii(DMPlexCellRefiner cr, PetscViewer v) 1547412e9a14SMatthew G. Knepley { 1548412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1549412e9a14SMatthew G. Knepley 1550412e9a14SMatthew G. Knepley PetscFunctionBegin; 1551412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(v, "Cell Refiner: %s\n", DMPlexCellRefinerTypes[cr->type]);CHKERRQ(ierr); 1552412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1553412e9a14SMatthew G. Knepley } 1554412e9a14SMatthew G. Knepley 1555412e9a14SMatthew G. Knepley /* 1556412e9a14SMatthew G. Knepley DMPlexCellRefinerView - Views a DMPlexCellRefiner object 1557412e9a14SMatthew G. Knepley 1558412e9a14SMatthew G. Knepley Collective on cr 1559412e9a14SMatthew G. Knepley 1560412e9a14SMatthew G. Knepley Input Parameters: 1561412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 1562412e9a14SMatthew G. Knepley - viewer - The PetscViewer object 1563412e9a14SMatthew G. Knepley 1564412e9a14SMatthew G. Knepley Level: beginner 1565412e9a14SMatthew G. Knepley 1566412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerCreate() 1567412e9a14SMatthew G. Knepley */ 1568412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView(DMPlexCellRefiner cr, PetscViewer viewer) 1569412e9a14SMatthew G. Knepley { 1570412e9a14SMatthew G. Knepley PetscBool iascii; 1571412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1572412e9a14SMatthew G. Knepley 1573412e9a14SMatthew G. Knepley PetscFunctionBegin; 1574412e9a14SMatthew G. Knepley PetscValidHeader(cr, 1); 1575412e9a14SMatthew G. Knepley if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1576412e9a14SMatthew G. Knepley if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) cr), &viewer);CHKERRQ(ierr);} 1577412e9a14SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1578412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1579412e9a14SMatthew G. Knepley if (iascii) {ierr = DMPlexCellRefinerView_Ascii(cr, viewer);CHKERRQ(ierr);} 1580412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1581412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1582412e9a14SMatthew G. Knepley } 1583412e9a14SMatthew G. Knepley 1584412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerDestroy(DMPlexCellRefiner *cr) 1585412e9a14SMatthew G. Knepley { 1586412e9a14SMatthew G. Knepley PetscInt c; 1587412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1588412e9a14SMatthew G. Knepley 1589412e9a14SMatthew G. Knepley PetscFunctionBegin; 1590412e9a14SMatthew G. Knepley if (!*cr) PetscFunctionReturn(0); 1591412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(*cr, DM_CLASSID, 1); 1592412e9a14SMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) (*cr)->dm);CHKERRQ(ierr); 1593412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->ctOrder, (*cr)->ctOrderInv);CHKERRQ(ierr); 1594412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->ctStart, (*cr)->ctStartNew);CHKERRQ(ierr); 1595412e9a14SMatthew G. Knepley ierr = PetscFree((*cr)->offset);CHKERRQ(ierr); 1596412e9a14SMatthew G. Knepley for (c = 0; c < DM_NUM_POLYTOPES; ++c) { 1597412e9a14SMatthew G. Knepley ierr = PetscFEDestroy(&(*cr)->coordFE[c]);CHKERRQ(ierr); 1598412e9a14SMatthew G. Knepley ierr = PetscFEGeomDestroy(&(*cr)->refGeom[c]);CHKERRQ(ierr); 1599412e9a14SMatthew G. Knepley } 1600412e9a14SMatthew G. Knepley ierr = PetscFree2((*cr)->coordFE, (*cr)->refGeom);CHKERRQ(ierr); 1601412e9a14SMatthew G. Knepley ierr = PetscHeaderDestroy(cr);CHKERRQ(ierr); 1602412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1603412e9a14SMatthew G. Knepley } 1604412e9a14SMatthew G. Knepley 1605412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerCreate(DM dm, DMPlexCellRefiner *cr) 1606412e9a14SMatthew G. Knepley { 1607412e9a14SMatthew G. Knepley DMPlexCellRefiner tmp; 1608412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1609412e9a14SMatthew G. Knepley 1610412e9a14SMatthew G. Knepley PetscFunctionBegin; 1611412e9a14SMatthew G. Knepley PetscValidPointer(cr, 2); 1612412e9a14SMatthew G. Knepley *cr = NULL; 1613412e9a14SMatthew G. Knepley ierr = PetscHeaderCreate(tmp, DM_CLASSID, "DMPlexCellRefiner", "Cell Refiner", "DMPlexCellRefiner", PETSC_COMM_SELF, DMPlexCellRefinerDestroy, DMPlexCellRefinerView);CHKERRQ(ierr); 1614412e9a14SMatthew G. Knepley tmp->setupcalled = PETSC_FALSE; 1615412e9a14SMatthew G. Knepley 1616412e9a14SMatthew G. Knepley tmp->dm = dm; 1617412e9a14SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); 1618412e9a14SMatthew G. Knepley ierr = DMPlexGetCellRefinerType(dm, &tmp->type);CHKERRQ(ierr); 1619412e9a14SMatthew G. Knepley switch (tmp->type) { 162096ca5757SLisandro Dalcin case DM_REFINER_REGULAR: 1621412e9a14SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_Regular; 1622412e9a14SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_Regular; 1623412e9a14SMatthew G. Knepley tmp->ops->getcellvertices = DMPlexCellRefinerGetCellVertices_Regular; 1624412e9a14SMatthew G. Knepley tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_Regular; 1625412e9a14SMatthew G. Knepley tmp->ops->getaffinetransforms = DMPlexCellRefinerGetAffineTransforms_Regular; 1626412e9a14SMatthew G. Knepley tmp->ops->getaffinefacetransforms = DMPlexCellRefinerGetAffineFaceTransforms_Regular; 1627412e9a14SMatthew G. Knepley break; 162896ca5757SLisandro Dalcin case DM_REFINER_TO_BOX: 162996ca5757SLisandro Dalcin tmp->ops->refine = DMPlexCellRefinerRefine_ToBox; 163096ca5757SLisandro Dalcin tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToBox; 163196ca5757SLisandro Dalcin tmp->ops->getcellvertices = DMPlexCellRefinerGetCellVertices_ToBox; 163296ca5757SLisandro Dalcin tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_ToBox; 1633412e9a14SMatthew G. Knepley break; 163496ca5757SLisandro Dalcin case DM_REFINER_TO_SIMPLEX: 1635412e9a14SMatthew G. Knepley tmp->ops->refine = DMPlexCellRefinerRefine_ToSimplex; 1636412e9a14SMatthew G. Knepley tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToSimplex; 1637412e9a14SMatthew G. Knepley break; 1638412e9a14SMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Invalid cell refiner type %s", DMPlexCellRefinerTypes[tmp->type]); 1639412e9a14SMatthew G. Knepley } 1640412e9a14SMatthew G. Knepley ierr = PetscCalloc2(DM_NUM_POLYTOPES, &tmp->coordFE, DM_NUM_POLYTOPES, &tmp->refGeom);CHKERRQ(ierr); 1641412e9a14SMatthew G. Knepley *cr = tmp; 1642412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1643412e9a14SMatthew G. Knepley } 1644412e9a14SMatthew G. Knepley 1645412e9a14SMatthew G. Knepley /*@ 1646412e9a14SMatthew G. Knepley DMPlexCellRefinerGetAffineTransforms - Gets the affine map from the reference cell to each subcell 1647412e9a14SMatthew G. Knepley 1648412e9a14SMatthew G. Knepley Input Parameters: 1649412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 1650412e9a14SMatthew G. Knepley - ct - The cell type 1651412e9a14SMatthew G. Knepley 1652412e9a14SMatthew G. Knepley Output Parameters: 1653412e9a14SMatthew G. Knepley + Nc - The number of subcells produced from this cell type 1654412e9a14SMatthew G. Knepley . v0 - The translation of the first vertex for each subcell 1655412e9a14SMatthew G. Knepley . J - The Jacobian for each subcell (map from reference cell to subcell) 1656412e9a14SMatthew G. Knepley - invJ - The inverse Jacobian for each subcell 1657412e9a14SMatthew G. Knepley 1658412e9a14SMatthew G. Knepley Level: developer 1659412e9a14SMatthew G. Knepley 1660412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineFaceTransforms(), Create() 1661412e9a14SMatthew G. Knepley @*/ 1662412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[]) 1663412e9a14SMatthew G. Knepley { 1664412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1665412e9a14SMatthew G. Knepley 1666412e9a14SMatthew G. Knepley PetscFunctionBegin; 1667412e9a14SMatthew G. Knepley if (!cr->ops->getaffinetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine transforms from this refiner"); 1668412e9a14SMatthew G. Knepley ierr = (*cr->ops->getaffinetransforms)(cr, ct, Nc, v0, J, invJ);CHKERRQ(ierr); 1669412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1670412e9a14SMatthew G. Knepley } 1671412e9a14SMatthew G. Knepley 1672412e9a14SMatthew G. Knepley /*@ 1673412e9a14SMatthew G. Knepley DMPlexCellRefinerGetAffineFaceTransforms - Gets the affine map from the reference face cell to each face in the given cell 1674412e9a14SMatthew G. Knepley 1675412e9a14SMatthew G. Knepley Input Parameters: 1676412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object 1677412e9a14SMatthew G. Knepley - ct - The cell type 1678412e9a14SMatthew G. Knepley 1679412e9a14SMatthew G. Knepley Output Parameters: 1680412e9a14SMatthew G. Knepley + Nf - The number of faces for this cell type 1681412e9a14SMatthew G. Knepley . v0 - The translation of the first vertex for each face 1682412e9a14SMatthew G. Knepley . J - The Jacobian for each face (map from original cell to subcell) 1683412e9a14SMatthew G. Knepley . invJ - The inverse Jacobian for each face 1684412e9a14SMatthew G. Knepley - detJ - The determinant of the Jacobian for each face 1685412e9a14SMatthew G. Knepley 1686412e9a14SMatthew G. Knepley Note: The Jacobian and inverse Jacboian will be rectangular, and the inverse is really a generalized inverse. 1687412e9a14SMatthew G. Knepley 1688412e9a14SMatthew G. Knepley Level: developer 1689412e9a14SMatthew G. Knepley 1690412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineTransforms(), Create() 1691412e9a14SMatthew G. Knepley @*/ 1692412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[]) 1693412e9a14SMatthew G. Knepley { 1694412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1695412e9a14SMatthew G. Knepley 1696412e9a14SMatthew G. Knepley PetscFunctionBegin; 1697412e9a14SMatthew G. Knepley if (!cr->ops->getaffinefacetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine face transforms from this refiner"); 1698412e9a14SMatthew G. Knepley ierr = (*cr->ops->getaffinefacetransforms)(cr, ct, Nf, v0, J, invJ, detJ);CHKERRQ(ierr); 1699412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1700412e9a14SMatthew G. Knepley } 1701412e9a14SMatthew G. Knepley 1702412e9a14SMatthew G. Knepley /* Numbering regularly refined meshes 1703412e9a14SMatthew G. Knepley 1704412e9a14SMatthew G. Knepley We want the numbering of the new mesh to respect the same depth stratification as the old mesh. We first compute 1705412e9a14SMatthew G. Knepley the number of new points at each depth. This means that offsets for each depth can be computed, making no assumptions 1706412e9a14SMatthew G. Knepley about the order of different cell types. 1707412e9a14SMatthew G. Knepley 1708412e9a14SMatthew G. Knepley However, when we want to order different depth strata, it will be very useful to make assumptions about contiguous 1709412e9a14SMatthew G. Knepley numbering of different cell types, especially if we want to compute new numberings without communication. Therefore, we 1710412e9a14SMatthew G. Knepley will require that cells are numbering contiguously for each cell type, and that those blocks come in the same order as 1711412e9a14SMatthew G. Knepley the cell type enumeration within a given depth stratum. 1712412e9a14SMatthew G. Knepley 1713412e9a14SMatthew 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 1714412e9a14SMatthew G. Knepley start at the new depth offset, run through all prior cell types incrementing by the total addition from that type, then 1715412e9a14SMatthew G. Knepley offset by the old cell type number and replica number for the insertion. 1716412e9a14SMatthew G. Knepley */ 1717412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetNewPoint(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType ctNew, PetscInt p, PetscInt r, PetscInt *pNew) 1718412e9a14SMatthew G. Knepley { 1719412e9a14SMatthew G. Knepley DMPolytopeType *rct; 1720412e9a14SMatthew G. Knepley PetscInt *rsize, *cone, *ornt; 1721412e9a14SMatthew G. Knepley PetscInt Nct, n; 1722412e9a14SMatthew G. Knepley PetscInt off = cr->offset[ct*DM_NUM_POLYTOPES+ctNew]; 1723412e9a14SMatthew G. Knepley PetscInt ctS = cr->ctStart[ct], ctE = cr->ctStart[cr->ctOrder[cr->ctOrderInv[ct]+1]]; 1724412e9a14SMatthew G. Knepley PetscInt ctSN = cr->ctStartNew[ctNew], ctEN = cr->ctStartNew[cr->ctOrder[cr->ctOrderInv[ctNew]+1]]; 1725412e9a14SMatthew G. Knepley PetscInt newp = ctSN; 1726412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1727412e9a14SMatthew G. Knepley 1728412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 1729412e9a14SMatthew 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); 1730412e9a14SMatthew 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]); 1731412e9a14SMatthew G. Knepley 1732412e9a14SMatthew G. Knepley newp += off; 1733412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr); 1734412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 1735412e9a14SMatthew G. Knepley if (rct[n] == ctNew) { 1736412e9a14SMatthew G. Knepley if (rsize[n] && r >= rsize[n]) 1737412e9a14SMatthew 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]); 1738412e9a14SMatthew G. Knepley newp += (p - ctS) * rsize[n] + r; 1739412e9a14SMatthew G. Knepley break; 1740412e9a14SMatthew G. Knepley } 1741412e9a14SMatthew G. Knepley } 1742412e9a14SMatthew G. Knepley 1743412e9a14SMatthew 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); 1744412e9a14SMatthew G. Knepley *pNew = newp; 1745412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1746412e9a14SMatthew G. Knepley } 1747412e9a14SMatthew G. Knepley 1748412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetConeSizes(DMPlexCellRefiner cr, DM rdm) 1749412e9a14SMatthew G. Knepley { 1750412e9a14SMatthew G. Knepley DM dm = cr->dm; 1751412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p, pNew; 1752412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1753412e9a14SMatthew G. Knepley 1754412e9a14SMatthew G. Knepley PetscFunctionBegin; 1755412e9a14SMatthew G. Knepley /* Must create the celltype label here so that we do not automatically try to compute the types */ 1756412e9a14SMatthew G. Knepley ierr = DMCreateLabel(rdm, "celltype");CHKERRQ(ierr); 1757412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 1758412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 1759412e9a14SMatthew G. Knepley DMPolytopeType ct; 1760412e9a14SMatthew G. Knepley DMPolytopeType *rct; 1761412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 1762412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 1763412e9a14SMatthew G. Knepley 1764412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 1765412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 1766412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 1767412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 1768412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 1769412e9a14SMatthew G. Knepley ierr = DMPlexSetConeSize(rdm, pNew, DMPolytopeTypeGetConeSize(rct[n]));CHKERRQ(ierr); 1770412e9a14SMatthew G. Knepley ierr = DMPlexSetCellType(rdm, pNew, rct[n]);CHKERRQ(ierr); 1771412e9a14SMatthew G. Knepley } 1772412e9a14SMatthew G. Knepley } 1773412e9a14SMatthew G. Knepley } 1774412e9a14SMatthew G. Knepley { 1775412e9a14SMatthew G. Knepley DMLabel ctLabel; 1776412e9a14SMatthew G. Knepley DM_Plex *plex = (DM_Plex *) rdm->data; 1777412e9a14SMatthew G. Knepley 1778412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(rdm, &ctLabel);CHKERRQ(ierr); 1779412e9a14SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) ctLabel, &plex->celltypeState);CHKERRQ(ierr); 1780412e9a14SMatthew G. Knepley } 1781412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1782412e9a14SMatthew G. Knepley } 1783412e9a14SMatthew G. Knepley 1784412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCones(DMPlexCellRefiner cr, DM rdm) 1785412e9a14SMatthew G. Knepley { 1786412e9a14SMatthew G. Knepley DM dm = cr->dm; 1787412e9a14SMatthew G. Knepley DMPolytopeType ct; 1788412e9a14SMatthew G. Knepley PetscInt *coneNew, *orntNew; 1789412e9a14SMatthew G. Knepley PetscInt maxConeSize = 0, pStart, pEnd, p, pNew; 1790412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1791412e9a14SMatthew G. Knepley 1792412e9a14SMatthew G. Knepley PetscFunctionBegin; 1793412e9a14SMatthew G. Knepley for (p = 0; p < DM_NUM_POLYTOPES; ++p) maxConeSize = PetscMax(maxConeSize, DMPolytopeTypeGetConeSize((DMPolytopeType) p)); 1794412e9a14SMatthew G. Knepley ierr = PetscMalloc2(maxConeSize, &coneNew, maxConeSize, &orntNew);CHKERRQ(ierr); 1795412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 1796412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 1797412e9a14SMatthew G. Knepley const PetscInt *cone, *ornt; 1798412e9a14SMatthew G. Knepley PetscInt coff, ooff, c; 1799412e9a14SMatthew G. Knepley DMPolytopeType *rct; 1800412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 1801412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 1802412e9a14SMatthew G. Knepley 1803412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 1804412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 1805412e9a14SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &ornt);CHKERRQ(ierr); 1806412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 1807412e9a14SMatthew G. Knepley for (n = 0, coff = 0, ooff = 0; n < Nct; ++n) { 1808412e9a14SMatthew G. Knepley const DMPolytopeType ctNew = rct[n]; 1809412e9a14SMatthew G. Knepley const PetscInt csizeNew = DMPolytopeTypeGetConeSize(ctNew); 1810412e9a14SMatthew G. Knepley 1811412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 1812412e9a14SMatthew G. Knepley /* pNew is a subcell produced by subdividing p */ 1813412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 1814412e9a14SMatthew G. Knepley for (c = 0; c < csizeNew; ++c) { 1815412e9a14SMatthew G. Knepley PetscInt ppp = -1; /* Parent Parent point: Parent of point pp */ 1816412e9a14SMatthew G. Knepley PetscInt pp = p; /* Parent point: Point in the original mesh producing new cone point */ 1817412e9a14SMatthew G. Knepley PetscInt po = 0; /* Orientation of parent point pp in parent parent point ppp */ 1818412e9a14SMatthew G. Knepley DMPolytopeType pct = ct; /* Parent type: Cell type for parent of new cone point */ 1819412e9a14SMatthew G. Knepley const PetscInt *pcone = cone; /* Parent cone: Cone of parent point pp */ 1820412e9a14SMatthew G. Knepley PetscInt pr = -1; /* Replica number of pp that produces new cone point */ 1821412e9a14SMatthew G. Knepley const DMPolytopeType ft = (DMPolytopeType) rcone[coff++]; /* Cell type for new cone point of pNew */ 1822412e9a14SMatthew G. Knepley const PetscInt fn = rcone[coff++]; /* Number of cones of p that need to be taken when producing new cone point */ 1823412e9a14SMatthew G. Knepley PetscInt fo = rornt[ooff++]; /* Orientation of new cone point in pNew */ 1824412e9a14SMatthew G. Knepley PetscInt lc; 1825412e9a14SMatthew G. Knepley 1826412e9a14SMatthew G. Knepley /* Get the type (pct) and point number (pp) of the parent point in the original mesh which produces this cone point */ 1827412e9a14SMatthew G. Knepley for (lc = 0; lc < fn; ++lc) { 1828412e9a14SMatthew G. Knepley const PetscInt *ppornt; 1829412e9a14SMatthew G. Knepley PetscInt pcp; 1830412e9a14SMatthew G. Knepley 1831412e9a14SMatthew G. Knepley ierr = DMPolytopeMapCell(pct, po, rcone[coff++], &pcp);CHKERRQ(ierr); 1832412e9a14SMatthew G. Knepley ppp = pp; 1833412e9a14SMatthew G. Knepley pp = pcone[pcp]; 1834412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, pp, &pct);CHKERRQ(ierr); 1835412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, pp, &pcone);CHKERRQ(ierr); 1836412e9a14SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, ppp, &ppornt);CHKERRQ(ierr); 1837412e9a14SMatthew G. Knepley po = ppornt[pcp]; 1838412e9a14SMatthew G. Knepley } 1839412e9a14SMatthew G. Knepley pr = rcone[coff++]; 1840412e9a14SMatthew G. Knepley /* Orientation po of pp maps (pr, fo) -> (pr', fo') */ 1841412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapSubcells(cr, pct, po, ft, pr, fo, &pr, &fo);CHKERRQ(ierr); 1842412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, pct, ft, pp, pr, &coneNew[c]);CHKERRQ(ierr); 1843412e9a14SMatthew G. Knepley orntNew[c] = fo; 1844412e9a14SMatthew G. Knepley } 1845412e9a14SMatthew G. Knepley ierr = DMPlexSetCone(rdm, pNew, coneNew);CHKERRQ(ierr); 1846412e9a14SMatthew G. Knepley ierr = DMPlexSetConeOrientation(rdm, pNew, orntNew);CHKERRQ(ierr); 1847412e9a14SMatthew G. Knepley } 1848412e9a14SMatthew G. Knepley } 1849412e9a14SMatthew G. Knepley } 1850412e9a14SMatthew G. Knepley ierr = PetscFree2(coneNew, orntNew);CHKERRQ(ierr); 1851412e9a14SMatthew G. Knepley ierr = DMPlexSymmetrize(rdm);CHKERRQ(ierr); 1852412e9a14SMatthew G. Knepley ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 1853412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1854412e9a14SMatthew G. Knepley } 1855412e9a14SMatthew G. Knepley 1856412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCoordinateFE(DMPlexCellRefiner cr, DMPolytopeType ct, PetscFE *fe) 1857412e9a14SMatthew G. Knepley { 1858412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1859412e9a14SMatthew G. Knepley 1860412e9a14SMatthew G. Knepley PetscFunctionBegin; 1861412e9a14SMatthew G. Knepley if (!cr->coordFE[ct]) { 1862412e9a14SMatthew G. Knepley PetscInt dim, cdim; 1863412e9a14SMatthew G. Knepley PetscBool isSimplex; 1864412e9a14SMatthew G. Knepley 1865412e9a14SMatthew G. Knepley switch (ct) { 1866412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: dim = 1; isSimplex = PETSC_TRUE; break; 1867412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: dim = 2; isSimplex = PETSC_TRUE; break; 1868412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: dim = 2; isSimplex = PETSC_FALSE; break; 1869412e9a14SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: dim = 3; isSimplex = PETSC_TRUE; break; 1870412e9a14SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: dim = 3; isSimplex = PETSC_FALSE; break; 1871412e9a14SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No coordinate FE for cell type %s", DMPolytopeTypes[ct]); 1872412e9a14SMatthew G. Knepley } 1873412e9a14SMatthew G. Knepley ierr = DMGetCoordinateDim(cr->dm, &cdim);CHKERRQ(ierr); 1874412e9a14SMatthew G. Knepley ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, cdim, isSimplex, 1, PETSC_DETERMINE, &cr->coordFE[ct]);CHKERRQ(ierr); 1875412e9a14SMatthew G. Knepley { 1876412e9a14SMatthew G. Knepley PetscDualSpace dsp; 1877412e9a14SMatthew G. Knepley PetscQuadrature quad; 1878412e9a14SMatthew G. Knepley DM K; 1879412e9a14SMatthew G. Knepley PetscFEGeom *cg; 1880412e9a14SMatthew G. Knepley PetscReal *Xq, *xq, *wq; 1881412e9a14SMatthew G. Knepley PetscInt Nq, q; 1882412e9a14SMatthew G. Knepley 1883412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCellVertices(cr, ct, &Nq, &Xq);CHKERRQ(ierr); 1884412e9a14SMatthew G. Knepley ierr = PetscMalloc1(Nq*cdim, &xq);CHKERRQ(ierr); 1885412e9a14SMatthew G. Knepley for (q = 0; q < Nq*cdim; ++q) xq[q] = Xq[q]; 1886412e9a14SMatthew G. Knepley ierr = PetscMalloc1(Nq, &wq);CHKERRQ(ierr); 1887412e9a14SMatthew G. Knepley for (q = 0; q < Nq; ++q) wq[q] = 1.0; 1888412e9a14SMatthew G. Knepley ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &quad);CHKERRQ(ierr); 1889412e9a14SMatthew G. Knepley ierr = PetscQuadratureSetData(quad, dim, 1, Nq, xq, wq);CHKERRQ(ierr); 1890412e9a14SMatthew G. Knepley ierr = PetscFESetQuadrature(cr->coordFE[ct], quad);CHKERRQ(ierr); 1891412e9a14SMatthew G. Knepley 1892412e9a14SMatthew G. Knepley ierr = PetscFEGetDualSpace(cr->coordFE[ct], &dsp);CHKERRQ(ierr); 1893412e9a14SMatthew G. Knepley ierr = PetscDualSpaceGetDM(dsp, &K);CHKERRQ(ierr); 1894412e9a14SMatthew G. Knepley ierr = PetscFEGeomCreate(quad, 1, cdim, PETSC_FALSE, &cr->refGeom[ct]);CHKERRQ(ierr); 1895412e9a14SMatthew G. Knepley cg = cr->refGeom[ct]; 1896412e9a14SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(K, 0, NULL, cg->v, cg->J, cg->invJ, cg->detJ);CHKERRQ(ierr); 1897412e9a14SMatthew G. Knepley ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr); 1898412e9a14SMatthew G. Knepley } 1899412e9a14SMatthew G. Knepley } 1900412e9a14SMatthew G. Knepley *fe = cr->coordFE[ct]; 1901412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1902412e9a14SMatthew G. Knepley } 1903412e9a14SMatthew G. Knepley 1904412e9a14SMatthew G. Knepley /* 1905412e9a14SMatthew G. Knepley DMPlexCellRefinerMapLocalizedCoordinates - Given a cell of type ct with localized coordinates x, we generate localized coordinates xr for subcell r of type rct. 1906412e9a14SMatthew G. Knepley 1907412e9a14SMatthew G. Knepley Not collective 1908412e9a14SMatthew G. Knepley 1909412e9a14SMatthew G. Knepley Input Parameters: 1910412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner 1911412e9a14SMatthew G. Knepley . ct - The type of the parent cell 1912412e9a14SMatthew G. Knepley . rct - The type of the produced cell 1913412e9a14SMatthew G. Knepley . r - The index of the produced cell 1914412e9a14SMatthew G. Knepley - x - The localized coordinates for the parent cell 1915412e9a14SMatthew G. Knepley 1916412e9a14SMatthew G. Knepley Output Parameter: 1917412e9a14SMatthew G. Knepley . xr - The localized coordinates for the produced cell 1918412e9a14SMatthew G. Knepley 1919412e9a14SMatthew G. Knepley Level: developer 1920412e9a14SMatthew G. Knepley 1921412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerSetCoordinates() 1922412e9a14SMatthew G. Knepley */ 1923412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapLocalizedCoordinates(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, const PetscScalar x[], PetscScalar xr[]) 1924412e9a14SMatthew G. Knepley { 1925412e9a14SMatthew G. Knepley PetscFE fe = NULL; 1926412e9a14SMatthew G. Knepley PetscInt cdim, Nv, v, *subcellV; 1927412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1928412e9a14SMatthew G. Knepley 1929412e9a14SMatthew G. Knepley PetscFunctionBegin; 1930412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetCoordinateFE(cr, ct, &fe);CHKERRQ(ierr); 1931412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetSubcellVertices(cr, ct, rct, r, &Nv, &subcellV);CHKERRQ(ierr); 1932412e9a14SMatthew G. Knepley ierr = PetscFEGetNumComponents(fe, &cdim);CHKERRQ(ierr); 1933412e9a14SMatthew G. Knepley for (v = 0; v < Nv; ++v) { 1934412e9a14SMatthew G. Knepley ierr = PetscFEInterpolate_Static(fe, x, cr->refGeom[ct], subcellV[v], &xr[v*cdim]);CHKERRQ(ierr); 1935412e9a14SMatthew G. Knepley } 1936412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1937412e9a14SMatthew G. Knepley } 1938412e9a14SMatthew G. Knepley 1939412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCoordinates(DMPlexCellRefiner cr, DM rdm) 1940412e9a14SMatthew G. Knepley { 1941412e9a14SMatthew G. Knepley DM dm = cr->dm, cdm; 1942412e9a14SMatthew G. Knepley PetscSection coordSection, coordSectionNew; 1943412e9a14SMatthew G. Knepley Vec coordsLocal, coordsLocalNew; 1944412e9a14SMatthew G. Knepley const PetscScalar *coords; 1945412e9a14SMatthew G. Knepley PetscScalar *coordsNew; 1946412e9a14SMatthew G. Knepley const DMBoundaryType *bd; 1947412e9a14SMatthew G. Knepley const PetscReal *maxCell, *L; 1948412e9a14SMatthew G. Knepley PetscBool isperiodic, localizeVertices = PETSC_FALSE, localizeCells = PETSC_FALSE; 1949412e9a14SMatthew G. Knepley PetscInt dE, d, cStart, cEnd, c, vStartNew, vEndNew, v, pStart, pEnd, p, ocStart, ocEnd; 1950412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1951412e9a14SMatthew G. Knepley 1952412e9a14SMatthew G. Knepley PetscFunctionBegin; 1953412e9a14SMatthew 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) { 1957412e9a14SMatthew G. Knepley localizeVertices = PETSC_TRUE; 1958412e9a14SMatthew G. Knepley if (!maxCell) { 1959412e9a14SMatthew G. Knepley PetscBool localized; 1960412e9a14SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 1961412e9a14SMatthew G. Knepley if (!localized) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Cannot refine a periodic mesh if coordinates have not been localized"); 1962412e9a14SMatthew G. Knepley localizeCells = PETSC_TRUE; 1963b9ccc978SStefano Zampini } 1964b9ccc978SStefano Zampini } 1965b9ccc978SStefano Zampini 1966b9ccc978SStefano Zampini ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 1967412e9a14SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &dE);CHKERRQ(ierr); 1968412e9a14SMatthew G. Knepley if (maxCell) { 1969412e9a14SMatthew G. Knepley PetscReal maxCellNew[3]; 1970412e9a14SMatthew G. Knepley 1971412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) maxCellNew[d] = maxCell[d]/2.0; 1972412e9a14SMatthew G. Knepley ierr = DMSetPeriodicity(rdm, isperiodic, maxCellNew, L, bd);CHKERRQ(ierr); 1973412e9a14SMatthew G. Knepley } else { 1974412e9a14SMatthew G. Knepley ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 1975412e9a14SMatthew G. Knepley } 1976b9ccc978SStefano Zampini ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &coordSectionNew);CHKERRQ(ierr); 1977b9ccc978SStefano Zampini ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 1978412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dE);CHKERRQ(ierr); 1979412e9a14SMatthew G. Knepley ierr = DMPlexGetDepthStratum(rdm, 0, &vStartNew, &vEndNew);CHKERRQ(ierr); 1980412e9a14SMatthew G. Knepley if (localizeCells) {ierr = PetscSectionSetChart(coordSectionNew, 0, vEndNew);CHKERRQ(ierr);} 1981412e9a14SMatthew G. Knepley else {ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vEndNew);CHKERRQ(ierr);} 1982b9ccc978SStefano Zampini 1983412e9a14SMatthew G. Knepley /* Localization should be inherited */ 1984412e9a14SMatthew G. Knepley /* Stefano calculates parent cells for each new cell for localization */ 1985412e9a14SMatthew G. Knepley /* Localized cells need coordinates of closure */ 1986412e9a14SMatthew G. Knepley for (v = vStartNew; v < vEndNew; ++v) { 1987412e9a14SMatthew G. Knepley ierr = PetscSectionSetDof(coordSectionNew, v, dE);CHKERRQ(ierr); 1988412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dE);CHKERRQ(ierr); 1989412e9a14SMatthew G. Knepley } 1990412e9a14SMatthew G. Knepley if (localizeCells) { 1991412e9a14SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1992412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1993412e9a14SMatthew G. Knepley PetscInt dof; 199490b157c4SStefano Zampini 1995412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, c, &dof); CHKERRQ(ierr); 1996412e9a14SMatthew G. Knepley if (dof) { 1997412e9a14SMatthew G. Knepley DMPolytopeType ct; 1998412e9a14SMatthew G. Knepley DMPolytopeType *rct; 1999412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2000412e9a14SMatthew G. Knepley PetscInt dim, cNew, Nct, n, r; 200190b157c4SStefano Zampini 2002412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 2003412e9a14SMatthew G. Knepley dim = DMPolytopeTypeGetDim(ct); 2004412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2005412e9a14SMatthew G. Knepley /* This allows for different cell types */ 2006412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2007412e9a14SMatthew G. Knepley if (dim != DMPolytopeTypeGetDim(rct[n])) continue; 2008412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2009412e9a14SMatthew G. Knepley PetscInt *closure = NULL; 2010412e9a14SMatthew G. Knepley PetscInt clSize, cl, Nv = 0; 201190b157c4SStefano Zampini 2012412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], c, r, &cNew);CHKERRQ(ierr); 2013412e9a14SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 2014412e9a14SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) {if ((closure[cl] >= vStartNew) && (closure[cl] < vEndNew)) ++Nv;} 2015412e9a14SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 2016412e9a14SMatthew G. Knepley ierr = PetscSectionSetDof(coordSectionNew, cNew, Nv * dE);CHKERRQ(ierr); 2017412e9a14SMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSectionNew, cNew, 0, Nv * dE);CHKERRQ(ierr); 20189fc2a3f3SStefano Zampini } 201990b157c4SStefano Zampini } 202090b157c4SStefano Zampini } 2021412e9a14SMatthew G. Knepley } 202275d3a19aSMatthew G. Knepley } 202375d3a19aSMatthew G. Knepley ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 2024412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-coarse_dm_view");CHKERRQ(ierr); 202546e270d4SMatthew G. Knepley ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 2026412e9a14SMatthew G. Knepley { 2027412e9a14SMatthew G. Knepley VecType vtype; 2028412e9a14SMatthew G. Knepley PetscInt coordSizeNew, bs; 2029412e9a14SMatthew G. Knepley const char *name; 2030412e9a14SMatthew G. Knepley 2031412e9a14SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); 2032412e9a14SMatthew G. Knepley ierr = VecCreate(PETSC_COMM_SELF, &coordsLocalNew);CHKERRQ(ierr); 203375d3a19aSMatthew G. Knepley ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 2034412e9a14SMatthew G. Knepley ierr = VecSetSizes(coordsLocalNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 2035412e9a14SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) coordsLocal, &name);CHKERRQ(ierr); 2036412e9a14SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) coordsLocalNew, name);CHKERRQ(ierr); 2037412e9a14SMatthew G. Knepley ierr = VecGetBlockSize(coordsLocal, &bs);CHKERRQ(ierr); 2038412e9a14SMatthew G. Knepley ierr = VecSetBlockSize(coordsLocalNew, bs);CHKERRQ(ierr); 2039412e9a14SMatthew G. Knepley ierr = VecGetType(coordsLocal, &vtype);CHKERRQ(ierr); 2040412e9a14SMatthew G. Knepley ierr = VecSetType(coordsLocalNew, vtype);CHKERRQ(ierr); 2041b5da9499SMatthew G. Knepley } 2042412e9a14SMatthew G. Knepley ierr = VecGetArrayRead(coordsLocal, &coords);CHKERRQ(ierr); 2043412e9a14SMatthew G. Knepley ierr = VecGetArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr); 2044412e9a14SMatthew G. Knepley ierr = PetscSectionGetChart(coordSection, &ocStart, &ocEnd);CHKERRQ(ierr); 2045412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2046412e9a14SMatthew G. Knepley /* First set coordinates for vertices*/ 2047412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2048412e9a14SMatthew G. Knepley DMPolytopeType ct; 2049412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2050412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2051412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2052412e9a14SMatthew G. Knepley PetscBool hasVertex = PETSC_FALSE, isLocalized = PETSC_FALSE; 205390b157c4SStefano Zampini 2054412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2055412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2056412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2057412e9a14SMatthew G. Knepley if (rct[n] == DM_POLYTOPE_POINT) {hasVertex = PETSC_TRUE; break;} 2058412e9a14SMatthew G. Knepley } 2059412e9a14SMatthew G. Knepley if (localizeVertices && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) { 2060412e9a14SMatthew G. Knepley PetscInt dof; 2061412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, p, &dof); CHKERRQ(ierr); 2062412e9a14SMatthew G. Knepley if (dof) isLocalized = PETSC_TRUE; 2063412e9a14SMatthew G. Knepley } 2064412e9a14SMatthew G. Knepley if (hasVertex) { 2065412e9a14SMatthew G. Knepley PetscScalar *pcoords = NULL; 2066412e9a14SMatthew G. Knepley PetscScalar vcoords[3] = {0., 0., 0.}; 2067412e9a14SMatthew G. Knepley PetscInt Nc, Nv, v, d; 206890b157c4SStefano Zampini 2069412e9a14SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr); 2070412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_POINT) { 2071412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) vcoords[d] = pcoords[d]; 20729fc2a3f3SStefano Zampini } else { 2073412e9a14SMatthew G. Knepley if (localizeVertices) { 2074412e9a14SMatthew G. Knepley PetscScalar anchor[3]; 207590b157c4SStefano Zampini 2076412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) anchor[d] = pcoords[d]; 2077412e9a14SMatthew G. Knepley if (!isLocalized) { 2078412e9a14SMatthew G. Knepley Nv = Nc/dE; 2079412e9a14SMatthew G. Knepley for (v = 0; v < Nv; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], vcoords);CHKERRQ(ierr);} 2080412e9a14SMatthew G. Knepley } else { 2081412e9a14SMatthew G. Knepley Nv = Nc/(2*dE); 2082412e9a14SMatthew 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 { 2085412e9a14SMatthew G. Knepley Nv = Nc/dE; 2086412e9a14SMatthew G. Knepley for (v = 0; v < Nv; ++v) for (d = 0; d < dE; ++d) vcoords[d] += pcoords[v*dE+d]; 2087b5da9499SMatthew G. Knepley } 2088412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) vcoords[d] /= Nv; 208990b157c4SStefano Zampini } 2090412e9a14SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr); 2091412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2092412e9a14SMatthew G. Knepley if (rct[n] != DM_POLYTOPE_POINT) continue; 2093412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2094412e9a14SMatthew G. Knepley PetscInt vNew, off; 2095b5da9499SMatthew G. Knepley 2096412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &vNew);CHKERRQ(ierr); 2097412e9a14SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, vNew, &off);CHKERRQ(ierr); 2098412e9a14SMatthew G. Knepley for (d = 0; d < dE; ++d) coordsNew[off+d] = vcoords[d]; 2099b5da9499SMatthew G. Knepley } 21009fc2a3f3SStefano Zampini } 2101412e9a14SMatthew G. Knepley } 2102412e9a14SMatthew G. Knepley } 2103412e9a14SMatthew G. Knepley /* Then set coordinates for cells by localizing */ 2104412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2105412e9a14SMatthew G. Knepley DMPolytopeType ct; 2106412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2107412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2108412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2109412e9a14SMatthew G. Knepley PetscBool isLocalized = PETSC_FALSE; 211090b157c4SStefano Zampini 2111412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2112412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2113412e9a14SMatthew G. Knepley if (localizeCells && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) { 2114412e9a14SMatthew G. Knepley PetscInt dof; 2115412e9a14SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, p, &dof); CHKERRQ(ierr); 2116412e9a14SMatthew G. Knepley if (dof) isLocalized = PETSC_TRUE; 2117b5da9499SMatthew G. Knepley } 2118412e9a14SMatthew G. Knepley if (isLocalized) { 2119412e9a14SMatthew G. Knepley const PetscScalar *pcoords; 21209fc2a3f3SStefano Zampini 2121412e9a14SMatthew G. Knepley ierr = DMPlexPointLocalRead(cdm, p, coords, &pcoords);CHKERRQ(ierr); 2122412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2123412e9a14SMatthew G. Knepley const PetscInt Nr = rsize[n]; 212490b157c4SStefano Zampini 2125412e9a14SMatthew G. Knepley if (DMPolytopeTypeGetDim(ct) != DMPolytopeTypeGetDim(rct[n])) continue; 2126412e9a14SMatthew G. Knepley for (r = 0; r < Nr; ++r) { 2127412e9a14SMatthew G. Knepley PetscInt pNew, offNew; 212890b157c4SStefano Zampini 2129412e9a14SMatthew G. Knepley /* It looks like Stefano and Lisandro are allowing localized coordinates without defining the periodic boundary, which means that 2130412e9a14SMatthew G. Knepley DMLocalizeCoordinate_Internal() will not work. Localized coordinates will have to have obtained by the affine map of the larger 2131412e9a14SMatthew G. Knepley cell to the ones it produces. */ 2132412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 2133412e9a14SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSectionNew, pNew, &offNew);CHKERRQ(ierr); 2134412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerMapLocalizedCoordinates(cr, ct, rct[n], r, pcoords, &coordsNew[offNew]);CHKERRQ(ierr); 213590b157c4SStefano Zampini } 213690b157c4SStefano Zampini } 213790b157c4SStefano Zampini } 213890b157c4SStefano Zampini } 2139412e9a14SMatthew G. Knepley ierr = VecRestoreArrayRead(coordsLocal, &coords);CHKERRQ(ierr); 2140412e9a14SMatthew G. Knepley ierr = VecRestoreArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr); 2141412e9a14SMatthew G. Knepley ierr = DMSetCoordinatesLocal(rdm, coordsLocalNew);CHKERRQ(ierr); 2142412e9a14SMatthew G. Knepley /* TODO Stefano has a final reduction if some hybrid coordinates cannot be found. (needcoords) Should not be needed. */ 2143412e9a14SMatthew G. Knepley ierr = VecDestroy(&coordsLocalNew);CHKERRQ(ierr); 214475d3a19aSMatthew G. Knepley ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 2145412e9a14SMatthew 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 2210412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateSF(DMPlexCellRefiner cr, DM rdm) 221175d3a19aSMatthew G. Knepley { 2212412e9a14SMatthew G. Knepley DM dm = cr->dm; 2213412e9a14SMatthew G. Knepley DMPlexCellRefiner *crRem; 221475d3a19aSMatthew G. Knepley PetscSF sf, sfNew, sfProcess; 221575d3a19aSMatthew G. Knepley IS processRanks; 2216412e9a14SMatthew 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; 2222412e9a14SMatthew G. Knepley PetscInt *ctStartRem, *ctStartNewRem; 2223412e9a14SMatthew 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]; 2235412e9a14SMatthew G. Knepley DMPolytopeType ct; 2236412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2237412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2238412e9a14SMatthew G. Knepley PetscInt Nct, n; 223975d3a19aSMatthew G. Knepley 2240412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2241412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2242412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) numLeavesNew += rsize[n]; 22430314a74cSLawrence Mitchell } 2244412e9a14SMatthew 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); 2247412e9a14SMatthew G. Knepley ierr = PetscMalloc2(ctSize*numNeighbors, &ctStartRem, ctSize*numNeighbors, &ctStartNewRem);CHKERRQ(ierr); 2248412e9a14SMatthew G. Knepley ierr = MPI_Type_contiguous(ctSize, MPIU_INT, &ctType);CHKERRQ(ierr); 2249412e9a14SMatthew G. Knepley ierr = MPI_Type_commit(&ctType);CHKERRQ(ierr); 2250412e9a14SMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr); 2251412e9a14SMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr); 2252412e9a14SMatthew G. Knepley ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr); 2253412e9a14SMatthew G. Knepley ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr); 2254412e9a14SMatthew G. Knepley ierr = MPI_Type_free(&ctType);CHKERRQ(ierr); 225575d3a19aSMatthew G. Knepley ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 2256412e9a14SMatthew G. Knepley ierr = PetscMalloc1(numNeighbors, &crRem);CHKERRQ(ierr); 2257412e9a14SMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) { 2258412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &crRem[n]);CHKERRQ(ierr); 2259412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetStarts(crRem[n], &ctStartRem[n*ctSize], &ctStartNewRem[n*ctSize]); 2260412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(crRem[n]);CHKERRQ(ierr); 2261412e9a14SMatthew G. Knepley } 2262412e9a14SMatthew 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]; 2269412e9a14SMatthew G. Knepley PetscInt pRem = remotePoints[l].index; 2270412e9a14SMatthew G. Knepley PetscMPIInt rankRem = remotePoints[l].rank; 2271412e9a14SMatthew G. Knepley DMPolytopeType ct; 2272412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2273412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2274412e9a14SMatthew G. Knepley PetscInt neighbor, Nct, n, r; 227575d3a19aSMatthew G. Knepley 2276412e9a14SMatthew G. Knepley ierr = PetscFindInt(rankRem, numNeighbors, neighbors, &neighbor);CHKERRQ(ierr); 2277412e9a14SMatthew G. Knepley if (neighbor < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rankRem); 2278412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 2279412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2280412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2281412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2282412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr); 2283412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(crRem[neighbor], ct, rct[n], pRem, r, &pNewRem);CHKERRQ(ierr); 2284412e9a14SMatthew G. Knepley localPointsNew[m] = pNew; 2285412e9a14SMatthew G. Knepley remotePointsNew[m].index = pNewRem; 2286412e9a14SMatthew G. Knepley remotePointsNew[m].rank = rankRem; 22870314a74cSLawrence Mitchell ++m; 22880314a74cSLawrence Mitchell } 22896ce3c06aSMatthew G. Knepley } 22906ce3c06aSMatthew G. Knepley } 2291412e9a14SMatthew G. Knepley for (n = 0; n < numNeighbors; ++n) {ierr = DMPlexCellRefinerDestroy(&crRem[n]);CHKERRQ(ierr);} 2292412e9a14SMatthew 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 2325412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateLabels(DMPlexCellRefiner cr, DM rdm) 232675d3a19aSMatthew G. Knepley { 2327412e9a14SMatthew G. Knepley DM dm = cr->dm; 232875d3a19aSMatthew G. Knepley PetscInt numLabels, l; 2329412e9a14SMatthew 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; 2359412e9a14SMatthew 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); 2364412e9a14SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 2365412e9a14SMatthew G. Knepley ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 2366412e9a14SMatthew G. Knepley ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 2367412e9a14SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 2368412e9a14SMatthew G. Knepley const PetscInt point = points[p]; 2369412e9a14SMatthew G. Knepley DMPolytopeType ct; 2370412e9a14SMatthew G. Knepley DMPolytopeType *rct; 2371412e9a14SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt; 2372412e9a14SMatthew G. Knepley PetscInt Nct, n, r; 2373412e9a14SMatthew G. Knepley 2374412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, point, &ct);CHKERRQ(ierr); 2375412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 2376412e9a14SMatthew G. Knepley for (n = 0; n < Nct; ++n) { 2377412e9a14SMatthew G. Knepley for (r = 0; r < rsize[n]; ++r) { 2378412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], point, r, &pNew);CHKERRQ(ierr); 2379412e9a14SMatthew 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 */ 2393412e9a14SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform(DM dm, DMPlexCellRefiner cr, DM *dmRefined) 239475d3a19aSMatthew G. Knepley { 239575d3a19aSMatthew G. Knepley DM rdm; 2396412e9a14SMatthew G. Knepley PetscInt dim, embedDim, depth; 239775d3a19aSMatthew G. Knepley PetscErrorCode ierr; 239875d3a19aSMatthew G. Knepley 239975d3a19aSMatthew G. Knepley PetscFunctionBegin; 2400412e9a14SMatthew 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 */ 2411412e9a14SMatthew 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) */ 2413412e9a14SMatthew 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) */ 2417412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetCones(cr, rdm);CHKERRQ(ierr); 24186d7373e8SToby Isaac /* Step 5: Create pointSF */ 2419412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreateSF(cr, rdm);CHKERRQ(ierr); 24206d7373e8SToby Isaac /* Step 6: Create labels */ 2421412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreateLabels(cr, rdm);CHKERRQ(ierr); 24226d7373e8SToby Isaac /* Step 7: Set coordinates */ 2423412e9a14SMatthew 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 2439*97d8846cSMatthew Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetSubpointIS() 24402389894bSMatthew G. Knepley @*/ 24412389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 24422389894bSMatthew G. Knepley { 2443412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 2444412e9a14SMatthew G. Knepley PetscInt *fpoints; 2445412e9a14SMatthew 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); 2451412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr); 2452412e9a14SMatthew 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; 2455412e9a14SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 2456412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetNewPoint(cr, DM_POLYTOPE_POINT, DM_POLYTOPE_POINT, p, 0, &vNew);CHKERRQ(ierr); 2457412e9a14SMatthew G. Knepley fpoints[v-pStart] = vNew; 24582389894bSMatthew G. Knepley } 2459412e9a14SMatthew 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; 2611412e9a14SMatthew 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); 2616412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-initref_dm_view");CHKERRQ(ierr); 26170d1cd5e0SMatthew G. Knepley if (isUniform) { 2618492b8470SStefano Zampini PetscBool localized; 26190d1cd5e0SMatthew G. Knepley 2620412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr); 2621412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 2622492b8470SStefano Zampini ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 2623412e9a14SMatthew 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);} 2627412e9a14SMatthew 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) { 2646412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 26470d1cd5e0SMatthew G. Knepley 2648412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(cdm, &cr);CHKERRQ(ierr); 2649412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr); 2650412e9a14SMatthew 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]; 2658412e9a14SMatthew 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