1ccd2543fSMatthew G Knepley #include <petsc-private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2ccd2543fSMatthew G Knepley 3ccd2543fSMatthew G Knepley #undef __FUNCT__ 4ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexLocatePoint_Simplex_2D_Internal" 5ccd2543fSMatthew G Knepley static PetscErrorCode DMPlexLocatePoint_Simplex_2D_Internal(DM dm, const PetscScalar point[], PetscInt c, PetscInt *cell) 6ccd2543fSMatthew G Knepley { 7ccd2543fSMatthew G Knepley const PetscInt embedDim = 2; 8ccd2543fSMatthew G Knepley PetscReal x = PetscRealPart(point[0]); 9ccd2543fSMatthew G Knepley PetscReal y = PetscRealPart(point[1]); 10ccd2543fSMatthew G Knepley PetscReal v0[2], J[4], invJ[4], detJ; 11ccd2543fSMatthew G Knepley PetscReal xi, eta; 12ccd2543fSMatthew G Knepley PetscErrorCode ierr; 13ccd2543fSMatthew G Knepley 14ccd2543fSMatthew G Knepley PetscFunctionBegin; 15ccd2543fSMatthew G Knepley ierr = DMPlexComputeCellGeometry(dm, c, v0, J, invJ, &detJ);CHKERRQ(ierr); 16ccd2543fSMatthew G Knepley xi = invJ[0*embedDim+0]*(x - v0[0]) + invJ[0*embedDim+1]*(y - v0[1]); 17ccd2543fSMatthew G Knepley eta = invJ[1*embedDim+0]*(x - v0[0]) + invJ[1*embedDim+1]*(y - v0[1]); 18ccd2543fSMatthew G Knepley 19ccd2543fSMatthew G Knepley if ((xi >= 0.0) && (eta >= 0.0) && (xi + eta <= 2.0)) *cell = c; 20ccd2543fSMatthew G Knepley else *cell = -1; 21ccd2543fSMatthew G Knepley PetscFunctionReturn(0); 22ccd2543fSMatthew G Knepley } 23ccd2543fSMatthew G Knepley 24ccd2543fSMatthew G Knepley #undef __FUNCT__ 25ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexLocatePoint_General_2D_Internal" 26ccd2543fSMatthew G Knepley static PetscErrorCode DMPlexLocatePoint_General_2D_Internal(DM dm, const PetscScalar point[], PetscInt c, PetscInt *cell) 27ccd2543fSMatthew G Knepley { 28ccd2543fSMatthew G Knepley PetscSection coordSection; 29ccd2543fSMatthew G Knepley Vec coordsLocal; 307c1f9639SMatthew G Knepley PetscScalar *coords; 31ccd2543fSMatthew G Knepley const PetscInt faces[8] = {0, 1, 1, 2, 2, 3, 3, 0}; 32ccd2543fSMatthew G Knepley PetscReal x = PetscRealPart(point[0]); 33ccd2543fSMatthew G Knepley PetscReal y = PetscRealPart(point[1]); 34ccd2543fSMatthew G Knepley PetscInt crossings = 0, f; 35ccd2543fSMatthew G Knepley PetscErrorCode ierr; 36ccd2543fSMatthew G Knepley 37ccd2543fSMatthew G Knepley PetscFunctionBegin; 38ccd2543fSMatthew G Knepley ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); 39ccd2543fSMatthew G Knepley ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 40ccd2543fSMatthew G Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, c, NULL, &coords);CHKERRQ(ierr); 41ccd2543fSMatthew G Knepley for (f = 0; f < 4; ++f) { 42ccd2543fSMatthew G Knepley PetscReal x_i = PetscRealPart(coords[faces[2*f+0]*2+0]); 43ccd2543fSMatthew G Knepley PetscReal y_i = PetscRealPart(coords[faces[2*f+0]*2+1]); 44ccd2543fSMatthew G Knepley PetscReal x_j = PetscRealPart(coords[faces[2*f+1]*2+0]); 45ccd2543fSMatthew G Knepley PetscReal y_j = PetscRealPart(coords[faces[2*f+1]*2+1]); 46ccd2543fSMatthew G Knepley PetscReal slope = (y_j - y_i) / (x_j - x_i); 47ccd2543fSMatthew G Knepley PetscBool cond1 = (x_i <= x) && (x < x_j) ? PETSC_TRUE : PETSC_FALSE; 48ccd2543fSMatthew G Knepley PetscBool cond2 = (x_j <= x) && (x < x_i) ? PETSC_TRUE : PETSC_FALSE; 49ccd2543fSMatthew G Knepley PetscBool above = (y < slope * (x - x_i) + y_i) ? PETSC_TRUE : PETSC_FALSE; 50ccd2543fSMatthew G Knepley if ((cond1 || cond2) && above) ++crossings; 51ccd2543fSMatthew G Knepley } 52ccd2543fSMatthew G Knepley if (crossings % 2) *cell = c; 53ccd2543fSMatthew G Knepley else *cell = -1; 54ccd2543fSMatthew G Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, c, NULL, &coords);CHKERRQ(ierr); 55ccd2543fSMatthew G Knepley PetscFunctionReturn(0); 56ccd2543fSMatthew G Knepley } 57ccd2543fSMatthew G Knepley 58ccd2543fSMatthew G Knepley #undef __FUNCT__ 59ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexLocatePoint_Simplex_3D_Internal" 60ccd2543fSMatthew G Knepley static PetscErrorCode DMPlexLocatePoint_Simplex_3D_Internal(DM dm, const PetscScalar point[], PetscInt c, PetscInt *cell) 61ccd2543fSMatthew G Knepley { 62ccd2543fSMatthew G Knepley const PetscInt embedDim = 3; 63ccd2543fSMatthew G Knepley PetscReal v0[3], J[9], invJ[9], detJ; 64ccd2543fSMatthew G Knepley PetscReal x = PetscRealPart(point[0]); 65ccd2543fSMatthew G Knepley PetscReal y = PetscRealPart(point[1]); 66ccd2543fSMatthew G Knepley PetscReal z = PetscRealPart(point[2]); 67ccd2543fSMatthew G Knepley PetscReal xi, eta, zeta; 68ccd2543fSMatthew G Knepley PetscErrorCode ierr; 69ccd2543fSMatthew G Knepley 70ccd2543fSMatthew G Knepley PetscFunctionBegin; 71ccd2543fSMatthew G Knepley ierr = DMPlexComputeCellGeometry(dm, c, v0, J, invJ, &detJ);CHKERRQ(ierr); 72ccd2543fSMatthew G Knepley xi = invJ[0*embedDim+0]*(x - v0[0]) + invJ[0*embedDim+1]*(y - v0[1]) + invJ[0*embedDim+2]*(z - v0[2]); 73ccd2543fSMatthew G Knepley eta = invJ[1*embedDim+0]*(x - v0[0]) + invJ[1*embedDim+1]*(y - v0[1]) + invJ[1*embedDim+2]*(z - v0[2]); 74ccd2543fSMatthew G Knepley zeta = invJ[2*embedDim+0]*(x - v0[0]) + invJ[2*embedDim+1]*(y - v0[1]) + invJ[2*embedDim+2]*(z - v0[2]); 75ccd2543fSMatthew G Knepley 76ccd2543fSMatthew G Knepley if ((xi >= 0.0) && (eta >= 0.0) && (zeta >= 0.0) && (xi + eta + zeta <= 2.0)) *cell = c; 77ccd2543fSMatthew G Knepley else *cell = -1; 78ccd2543fSMatthew G Knepley PetscFunctionReturn(0); 79ccd2543fSMatthew G Knepley } 80ccd2543fSMatthew G Knepley 81ccd2543fSMatthew G Knepley #undef __FUNCT__ 82ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexLocatePoint_General_3D_Internal" 83ccd2543fSMatthew G Knepley static PetscErrorCode DMPlexLocatePoint_General_3D_Internal(DM dm, const PetscScalar point[], PetscInt c, PetscInt *cell) 84ccd2543fSMatthew G Knepley { 85ccd2543fSMatthew G Knepley PetscSection coordSection; 86ccd2543fSMatthew G Knepley Vec coordsLocal; 877c1f9639SMatthew G Knepley PetscScalar *coords; 88ccd2543fSMatthew G Knepley const PetscInt faces[24] = {0, 1, 2, 3, 5, 4, 7, 6, 1, 0, 4, 5, 89ccd2543fSMatthew G Knepley 3, 2, 6, 7, 1, 5, 6, 2, 0, 3, 7, 4}; 90ccd2543fSMatthew G Knepley PetscBool found = PETSC_TRUE; 91ccd2543fSMatthew G Knepley PetscInt f; 92ccd2543fSMatthew G Knepley PetscErrorCode ierr; 93ccd2543fSMatthew G Knepley 94ccd2543fSMatthew G Knepley PetscFunctionBegin; 95ccd2543fSMatthew G Knepley ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); 96ccd2543fSMatthew G Knepley ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 97ccd2543fSMatthew G Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, c, NULL, &coords);CHKERRQ(ierr); 98ccd2543fSMatthew G Knepley for (f = 0; f < 6; ++f) { 99ccd2543fSMatthew G Knepley /* Check the point is under plane */ 100ccd2543fSMatthew G Knepley /* Get face normal */ 101ccd2543fSMatthew G Knepley PetscReal v_i[3]; 102ccd2543fSMatthew G Knepley PetscReal v_j[3]; 103ccd2543fSMatthew G Knepley PetscReal normal[3]; 104ccd2543fSMatthew G Knepley PetscReal pp[3]; 105ccd2543fSMatthew G Knepley PetscReal dot; 106ccd2543fSMatthew G Knepley 107ccd2543fSMatthew G Knepley v_i[0] = PetscRealPart(coords[faces[f*4+3]*3+0]-coords[faces[f*4+0]*3+0]); 108ccd2543fSMatthew G Knepley v_i[1] = PetscRealPart(coords[faces[f*4+3]*3+1]-coords[faces[f*4+0]*3+1]); 109ccd2543fSMatthew G Knepley v_i[2] = PetscRealPart(coords[faces[f*4+3]*3+2]-coords[faces[f*4+0]*3+2]); 110ccd2543fSMatthew G Knepley v_j[0] = PetscRealPart(coords[faces[f*4+1]*3+0]-coords[faces[f*4+0]*3+0]); 111ccd2543fSMatthew G Knepley v_j[1] = PetscRealPart(coords[faces[f*4+1]*3+1]-coords[faces[f*4+0]*3+1]); 112ccd2543fSMatthew G Knepley v_j[2] = PetscRealPart(coords[faces[f*4+1]*3+2]-coords[faces[f*4+0]*3+2]); 113ccd2543fSMatthew G Knepley normal[0] = v_i[1]*v_j[2] - v_i[2]*v_j[1]; 114ccd2543fSMatthew G Knepley normal[1] = v_i[2]*v_j[0] - v_i[0]*v_j[2]; 115ccd2543fSMatthew G Knepley normal[2] = v_i[0]*v_j[1] - v_i[1]*v_j[0]; 116ccd2543fSMatthew G Knepley pp[0] = PetscRealPart(coords[faces[f*4+0]*3+0] - point[0]); 117ccd2543fSMatthew G Knepley pp[1] = PetscRealPart(coords[faces[f*4+0]*3+1] - point[1]); 118ccd2543fSMatthew G Knepley pp[2] = PetscRealPart(coords[faces[f*4+0]*3+2] - point[2]); 119ccd2543fSMatthew G Knepley dot = normal[0]*pp[0] + normal[1]*pp[1] + normal[2]*pp[2]; 120ccd2543fSMatthew G Knepley 121ccd2543fSMatthew G Knepley /* Check that projected point is in face (2D location problem) */ 122ccd2543fSMatthew G Knepley if (dot < 0.0) { 123ccd2543fSMatthew G Knepley found = PETSC_FALSE; 124ccd2543fSMatthew G Knepley break; 125ccd2543fSMatthew G Knepley } 126ccd2543fSMatthew G Knepley } 127ccd2543fSMatthew G Knepley if (found) *cell = c; 128ccd2543fSMatthew G Knepley else *cell = -1; 129ccd2543fSMatthew G Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, c, NULL, &coords);CHKERRQ(ierr); 130ccd2543fSMatthew G Knepley PetscFunctionReturn(0); 131ccd2543fSMatthew G Knepley } 132ccd2543fSMatthew G Knepley 133ccd2543fSMatthew G Knepley #undef __FUNCT__ 134ccd2543fSMatthew G Knepley #define __FUNCT__ "DMLocatePoints_Plex" 135ccd2543fSMatthew G Knepley /* 136ccd2543fSMatthew G Knepley Need to implement using the guess 137ccd2543fSMatthew G Knepley */ 138ccd2543fSMatthew G Knepley PetscErrorCode DMLocatePoints_Plex(DM dm, Vec v, IS *cellIS) 139ccd2543fSMatthew G Knepley { 140ccd2543fSMatthew G Knepley PetscInt cell = -1 /*, guess = -1*/; 141ccd2543fSMatthew G Knepley PetscInt bs, numPoints, p; 142ccd2543fSMatthew G Knepley PetscInt dim, cStart, cEnd, cMax, c, coneSize; 143ccd2543fSMatthew G Knepley PetscInt *cells; 144ccd2543fSMatthew G Knepley PetscScalar *a; 145ccd2543fSMatthew G Knepley PetscErrorCode ierr; 146ccd2543fSMatthew G Knepley 147ccd2543fSMatthew G Knepley PetscFunctionBegin; 148ccd2543fSMatthew G Knepley ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 149ccd2543fSMatthew G Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 150ccd2543fSMatthew G Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 151ccd2543fSMatthew G Knepley if (cMax >= 0) cEnd = PetscMin(cEnd, cMax); 152ccd2543fSMatthew G Knepley ierr = VecGetLocalSize(v, &numPoints);CHKERRQ(ierr); 153ccd2543fSMatthew G Knepley ierr = VecGetBlockSize(v, &bs);CHKERRQ(ierr); 154ccd2543fSMatthew G Knepley ierr = VecGetArray(v, &a);CHKERRQ(ierr); 155ccd2543fSMatthew G Knepley if (bs != dim) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Block size for point vector %d must be the mesh coordinate dimension %d", bs, dim); 156ccd2543fSMatthew G Knepley numPoints /= bs; 157ccd2543fSMatthew G Knepley ierr = PetscMalloc(numPoints * sizeof(PetscInt), &cells);CHKERRQ(ierr); 158ccd2543fSMatthew G Knepley for (p = 0; p < numPoints; ++p) { 159ccd2543fSMatthew G Knepley const PetscScalar *point = &a[p*bs]; 160ccd2543fSMatthew G Knepley 161ccd2543fSMatthew G Knepley switch (dim) { 162ccd2543fSMatthew G Knepley case 2: 163ccd2543fSMatthew G Knepley for (c = cStart; c < cEnd; ++c) { 164ccd2543fSMatthew G Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 165ccd2543fSMatthew G Knepley switch (coneSize) { 166ccd2543fSMatthew G Knepley case 3: 167ccd2543fSMatthew G Knepley ierr = DMPlexLocatePoint_Simplex_2D_Internal(dm, point, c, &cell);CHKERRQ(ierr); 168ccd2543fSMatthew G Knepley break; 169ccd2543fSMatthew G Knepley case 4: 170ccd2543fSMatthew G Knepley ierr = DMPlexLocatePoint_General_2D_Internal(dm, point, c, &cell);CHKERRQ(ierr); 171ccd2543fSMatthew G Knepley break; 172ccd2543fSMatthew G Knepley default: 173ccd2543fSMatthew G Knepley SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "No point location for cell with cone size %d", coneSize); 174ccd2543fSMatthew G Knepley } 175ccd2543fSMatthew G Knepley if (cell >= 0) break; 176ccd2543fSMatthew G Knepley } 177ccd2543fSMatthew G Knepley break; 178ccd2543fSMatthew G Knepley case 3: 179ccd2543fSMatthew G Knepley for (c = cStart; c < cEnd; ++c) { 180ccd2543fSMatthew G Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 181ccd2543fSMatthew G Knepley switch (coneSize) { 182ccd2543fSMatthew G Knepley case 4: 183ccd2543fSMatthew G Knepley ierr = DMPlexLocatePoint_Simplex_3D_Internal(dm, point, c, &cell);CHKERRQ(ierr); 184ccd2543fSMatthew G Knepley break; 185ccd2543fSMatthew G Knepley case 8: 186ccd2543fSMatthew G Knepley ierr = DMPlexLocatePoint_General_3D_Internal(dm, point, c, &cell);CHKERRQ(ierr); 187ccd2543fSMatthew G Knepley break; 188ccd2543fSMatthew G Knepley default: 189ccd2543fSMatthew G Knepley SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "No point location for cell with cone size %d", coneSize); 190ccd2543fSMatthew G Knepley } 191ccd2543fSMatthew G Knepley if (cell >= 0) break; 192ccd2543fSMatthew G Knepley } 193ccd2543fSMatthew G Knepley break; 194ccd2543fSMatthew G Knepley default: 195ccd2543fSMatthew G Knepley SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "No point location for mesh dimension %d", dim); 196ccd2543fSMatthew G Knepley } 197ccd2543fSMatthew G Knepley cells[p] = cell; 198ccd2543fSMatthew G Knepley } 199ccd2543fSMatthew G Knepley ierr = VecRestoreArray(v, &a);CHKERRQ(ierr); 200ccd2543fSMatthew G Knepley ierr = ISCreateGeneral(PETSC_COMM_SELF, numPoints, cells, PETSC_OWN_POINTER, cellIS);CHKERRQ(ierr); 201ccd2543fSMatthew G Knepley PetscFunctionReturn(0); 202ccd2543fSMatthew G Knepley } 203ccd2543fSMatthew G Knepley 204ccd2543fSMatthew G Knepley #undef __FUNCT__ 20517fe8556SMatthew G. Knepley #define __FUNCT__ "DMPlexComputeProjection2Dto1D_Internal" 20617fe8556SMatthew G. Knepley /* 20717fe8556SMatthew G. Knepley DMPlexComputeProjection2Dto1D_Internal - Rewrite coordinates to be the 1D projection of the 2D 20817fe8556SMatthew G. Knepley */ 2097f07f362SMatthew G. Knepley static PetscErrorCode DMPlexComputeProjection2Dto1D_Internal(PetscScalar coords[], PetscReal R[]) 21017fe8556SMatthew G. Knepley { 21117fe8556SMatthew G. Knepley const PetscReal x = PetscRealPart(coords[2] - coords[0]); 21217fe8556SMatthew G. Knepley const PetscReal y = PetscRealPart(coords[3] - coords[1]); 2137f07f362SMatthew G. Knepley const PetscReal r = sqrt(x*x + y*y), c = x/r, s = y/r; 21417fe8556SMatthew G. Knepley 21517fe8556SMatthew G. Knepley PetscFunctionBegin; 2167f07f362SMatthew G. Knepley R[0] = c; R[1] = s; 2177f07f362SMatthew G. Knepley R[2] = -s; R[3] = c; 21817fe8556SMatthew G. Knepley coords[0] = 0.0; 2197f07f362SMatthew G. Knepley coords[1] = r; 22017fe8556SMatthew G. Knepley PetscFunctionReturn(0); 22117fe8556SMatthew G. Knepley } 22217fe8556SMatthew G. Knepley 22317fe8556SMatthew G. Knepley #undef __FUNCT__ 224ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexComputeProjection3Dto2D_Internal" 225ccd2543fSMatthew G Knepley /* 226ccd2543fSMatthew G Knepley DMPlexComputeProjection3Dto2D_Internal - Rewrite coordinates to be the 2D projection of the 3D 227ccd2543fSMatthew G Knepley */ 2287f07f362SMatthew G. Knepley static PetscErrorCode DMPlexComputeProjection3Dto2D_Internal(PetscScalar coords[], PetscReal R[]) 229ccd2543fSMatthew G Knepley { 230ccd2543fSMatthew G Knepley PetscScalar x1[3], x2[3], n[3], norm; 2317f07f362SMatthew G. Knepley PetscScalar x1p[3], x2p[3]; 2324a217a95SMatthew G. Knepley PetscReal sqrtz, alpha; 233ccd2543fSMatthew G Knepley const PetscInt dim = 3; 234ccd2543fSMatthew G Knepley PetscInt d, e; 235ccd2543fSMatthew G Knepley 236ccd2543fSMatthew G Knepley PetscFunctionBegin; 237ccd2543fSMatthew G Knepley /* 0) Calculate normal vector */ 238ccd2543fSMatthew G Knepley for (d = 0; d < dim; ++d) { 239ccd2543fSMatthew G Knepley x1[d] = coords[1*dim+d] - coords[0*dim+d]; 240ccd2543fSMatthew G Knepley x2[d] = coords[2*dim+d] - coords[0*dim+d]; 241ccd2543fSMatthew G Knepley } 242ccd2543fSMatthew G Knepley n[0] = x1[1]*x2[2] - x1[2]*x2[1]; 243ccd2543fSMatthew G Knepley n[1] = x1[2]*x2[0] - x1[0]*x2[2]; 244ccd2543fSMatthew G Knepley n[2] = x1[0]*x2[1] - x1[1]*x2[0]; 245ccd2543fSMatthew G Knepley norm = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]); 246ccd2543fSMatthew G Knepley n[0] /= norm; 247ccd2543fSMatthew G Knepley n[1] /= norm; 248ccd2543fSMatthew G Knepley n[2] /= norm; 249ccd2543fSMatthew G Knepley /* 1) Take the normal vector and rotate until it is \hat z 250ccd2543fSMatthew G Knepley 251ccd2543fSMatthew G Knepley Let the normal vector be <nx, ny, nz> and alpha = 1/sqrt(1 - nz^2), then 252ccd2543fSMatthew G Knepley 253ccd2543fSMatthew G Knepley R = / alpha nx nz alpha ny nz -1/alpha \ 254ccd2543fSMatthew G Knepley | -alpha ny alpha nx 0 | 255ccd2543fSMatthew G Knepley \ nx ny nz / 256ccd2543fSMatthew G Knepley 257ccd2543fSMatthew G Knepley will rotate the normal vector to \hat z 258ccd2543fSMatthew G Knepley */ 2594a217a95SMatthew G. Knepley sqrtz = sqrt(1.0 - PetscAbsScalar(n[2]*n[2])); 26073868372SMatthew G. Knepley /* Check for n = z */ 26173868372SMatthew G. Knepley if (sqrtz < 1.0e-10) { 26273868372SMatthew G. Knepley coords[0] = 0.0; 26373868372SMatthew G. Knepley coords[1] = 0.0; 2644a217a95SMatthew G. Knepley if (PetscRealPart(n[2]) < 0.0) { 26573868372SMatthew G. Knepley coords[2] = x2[0]; 26673868372SMatthew G. Knepley coords[3] = x2[1]; 26773868372SMatthew G. Knepley coords[4] = x1[0]; 26873868372SMatthew G. Knepley coords[5] = x1[1]; 26973868372SMatthew G. Knepley } else { 27073868372SMatthew G. Knepley coords[2] = x1[0]; 27173868372SMatthew G. Knepley coords[3] = x1[1]; 27273868372SMatthew G. Knepley coords[4] = x2[0]; 27373868372SMatthew G. Knepley coords[5] = x2[1]; 27473868372SMatthew G. Knepley } 27573868372SMatthew G. Knepley PetscFunctionReturn(0); 27673868372SMatthew G. Knepley } 277da18b5e6SMatthew G Knepley alpha = 1.0/sqrtz; 278ccd2543fSMatthew G Knepley R[0] = alpha*n[0]*n[2]; R[1] = alpha*n[1]*n[2]; R[2] = -sqrtz; 279ccd2543fSMatthew G Knepley R[3] = -alpha*n[1]; R[4] = alpha*n[0]; R[5] = 0.0; 280ccd2543fSMatthew G Knepley R[6] = n[0]; R[7] = n[1]; R[8] = n[2]; 281ccd2543fSMatthew G Knepley for (d = 0; d < dim; ++d) { 282ccd2543fSMatthew G Knepley x1p[d] = 0.0; 283ccd2543fSMatthew G Knepley x2p[d] = 0.0; 284ccd2543fSMatthew G Knepley for (e = 0; e < dim; ++e) { 285ccd2543fSMatthew G Knepley x1p[d] += R[d*dim+e]*x1[e]; 286ccd2543fSMatthew G Knepley x2p[d] += R[d*dim+e]*x2[e]; 287ccd2543fSMatthew G Knepley } 288ccd2543fSMatthew G Knepley } 28988790e04SMatthew G Knepley if (PetscAbsScalar(x1p[2]) > 1.0e-9) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid rotation calculated"); 29088790e04SMatthew G Knepley if (PetscAbsScalar(x2p[2]) > 1.0e-9) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid rotation calculated"); 291ccd2543fSMatthew G Knepley /* 2) Project to (x, y) */ 292ccd2543fSMatthew G Knepley coords[0] = 0.0; 293ccd2543fSMatthew G Knepley coords[1] = 0.0; 294ccd2543fSMatthew G Knepley coords[2] = x1p[0]; 295ccd2543fSMatthew G Knepley coords[3] = x1p[1]; 296ccd2543fSMatthew G Knepley coords[4] = x2p[0]; 297ccd2543fSMatthew G Knepley coords[5] = x2p[1]; 2987f07f362SMatthew G. Knepley /* Output R^T which rotates \hat z to the input normal */ 2997f07f362SMatthew G. Knepley for (d = 0; d < dim; ++d) { 3007f07f362SMatthew G. Knepley for (e = d+1; e < dim; ++e) { 3017f07f362SMatthew G. Knepley PetscReal tmp; 3027f07f362SMatthew G. Knepley 3037f07f362SMatthew G. Knepley tmp = R[d*dim+e]; 3047f07f362SMatthew G. Knepley R[d*dim+e] = R[e*dim+d]; 3057f07f362SMatthew G. Knepley R[e*dim+d] = tmp; 3067f07f362SMatthew G. Knepley } 3077f07f362SMatthew G. Knepley } 308ccd2543fSMatthew G Knepley PetscFunctionReturn(0); 309ccd2543fSMatthew G Knepley } 310ccd2543fSMatthew G Knepley 311ccd2543fSMatthew G Knepley #undef __FUNCT__ 3127f07f362SMatthew G. Knepley #define __FUNCT__ "Invert2D_Internal" 3137f07f362SMatthew G. Knepley PETSC_STATIC_INLINE void Invert2D_Internal(PetscReal invJ[], PetscReal J[], PetscReal detJ) 3147f07f362SMatthew G. Knepley { 3157f07f362SMatthew G. Knepley const PetscReal invDet = 1.0/detJ; 3167f07f362SMatthew G. Knepley 3177f07f362SMatthew G. Knepley invJ[0] = invDet*J[3]; 3187f07f362SMatthew G. Knepley invJ[1] = -invDet*J[1]; 3197f07f362SMatthew G. Knepley invJ[2] = -invDet*J[2]; 3207f07f362SMatthew G. Knepley invJ[3] = invDet*J[0]; 3217f07f362SMatthew G. Knepley PetscLogFlops(5.0); 3227f07f362SMatthew G. Knepley } 3237f07f362SMatthew G. Knepley 3247f07f362SMatthew G. Knepley #undef __FUNCT__ 3257f07f362SMatthew G. Knepley #define __FUNCT__ "Invert3D_Internal" 3267f07f362SMatthew G. Knepley PETSC_STATIC_INLINE void Invert3D_Internal(PetscReal invJ[], PetscReal J[], PetscReal detJ) 3277f07f362SMatthew G. Knepley { 3287f07f362SMatthew G. Knepley const PetscReal invDet = 1.0/detJ; 3297f07f362SMatthew G. Knepley 3307f07f362SMatthew G. Knepley invJ[0*3+0] = invDet*(J[1*3+1]*J[2*3+2] - J[1*3+2]*J[2*3+1]); 3317f07f362SMatthew G. Knepley invJ[0*3+1] = invDet*(J[0*3+2]*J[2*3+1] - J[0*3+1]*J[2*3+2]); 3327f07f362SMatthew G. Knepley invJ[0*3+2] = invDet*(J[0*3+1]*J[1*3+2] - J[0*3+2]*J[1*3+1]); 3337f07f362SMatthew G. Knepley invJ[1*3+0] = invDet*(J[1*3+2]*J[2*3+0] - J[1*3+0]*J[2*3+2]); 3347f07f362SMatthew G. Knepley invJ[1*3+1] = invDet*(J[0*3+0]*J[2*3+2] - J[0*3+2]*J[2*3+0]); 3357f07f362SMatthew G. Knepley invJ[1*3+2] = invDet*(J[0*3+2]*J[1*3+0] - J[0*3+0]*J[1*3+2]); 3367f07f362SMatthew G. Knepley invJ[2*3+0] = invDet*(J[1*3+0]*J[2*3+1] - J[1*3+1]*J[2*3+0]); 3377f07f362SMatthew G. Knepley invJ[2*3+1] = invDet*(J[0*3+1]*J[2*3+0] - J[0*3+0]*J[2*3+1]); 3387f07f362SMatthew G. Knepley invJ[2*3+2] = invDet*(J[0*3+0]*J[1*3+1] - J[0*3+1]*J[1*3+0]); 3397f07f362SMatthew G. Knepley PetscLogFlops(37.0); 3407f07f362SMatthew G. Knepley } 3417f07f362SMatthew G. Knepley 3427f07f362SMatthew G. Knepley #undef __FUNCT__ 3437f07f362SMatthew G. Knepley #define __FUNCT__ "Det2D_Internal" 3447f07f362SMatthew G. Knepley PETSC_STATIC_INLINE void Det2D_Internal(PetscReal *detJ, PetscReal J[]) 3457f07f362SMatthew G. Knepley { 3467f07f362SMatthew G. Knepley *detJ = J[0]*J[3] - J[1]*J[2]; 3477f07f362SMatthew G. Knepley PetscLogFlops(3.0); 3487f07f362SMatthew G. Knepley } 3497f07f362SMatthew G. Knepley 3507f07f362SMatthew G. Knepley #undef __FUNCT__ 3517f07f362SMatthew G. Knepley #define __FUNCT__ "Det3D_Internal" 3527f07f362SMatthew G. Knepley PETSC_STATIC_INLINE void Det3D_Internal(PetscReal *detJ, PetscReal J[]) 3537f07f362SMatthew G. Knepley { 3547f07f362SMatthew G. Knepley *detJ = (J[0*3+0]*(J[1*3+2]*J[2*3+1] - J[1*3+1]*J[2*3+2]) + 3557f07f362SMatthew G. Knepley J[0*3+1]*(J[1*3+0]*J[2*3+2] - J[1*3+2]*J[2*3+0]) + 3567f07f362SMatthew G. Knepley J[0*3+2]*(J[1*3+1]*J[2*3+0] - J[1*3+0]*J[2*3+1])); 3577f07f362SMatthew G. Knepley PetscLogFlops(12.0); 3587f07f362SMatthew G. Knepley } 3597f07f362SMatthew G. Knepley 3607f07f362SMatthew G. Knepley #undef __FUNCT__ 361834e62ceSMatthew G. Knepley #define __FUNCT__ "Volume_Triangle_Internal" 362834e62ceSMatthew G. Knepley PETSC_STATIC_INLINE void Volume_Triangle_Internal(PetscReal *vol, PetscReal coords[]) 363834e62ceSMatthew G. Knepley { 364834e62ceSMatthew G. Knepley /* Signed volume is 1/2 the determinant 365834e62ceSMatthew G. Knepley 366834e62ceSMatthew G. Knepley | 1 1 1 | 367834e62ceSMatthew G. Knepley | x0 x1 x2 | 368834e62ceSMatthew G. Knepley | y0 y1 y2 | 369834e62ceSMatthew G. Knepley 370834e62ceSMatthew G. Knepley but if x0,y0 is the origin, we have 371834e62ceSMatthew G. Knepley 372834e62ceSMatthew G. Knepley | x1 x2 | 373834e62ceSMatthew G. Knepley | y1 y2 | 374834e62ceSMatthew G. Knepley */ 375834e62ceSMatthew G. Knepley const PetscReal x1 = coords[2] - coords[0], y1 = coords[3] - coords[1]; 376834e62ceSMatthew G. Knepley const PetscReal x2 = coords[4] - coords[0], y2 = coords[5] - coords[1]; 377834e62ceSMatthew G. Knepley PetscReal M[4], detM; 378834e62ceSMatthew G. Knepley M[0] = x1; M[1] = x2; 379834e62ceSMatthew G. Knepley M[3] = y1; M[4] = y2; 380834e62ceSMatthew G. Knepley Det2D_Internal(&detM, M); 381834e62ceSMatthew G. Knepley *vol = 0.5*detM; 382834e62ceSMatthew G. Knepley PetscLogFlops(5.0); 383834e62ceSMatthew G. Knepley } 384834e62ceSMatthew G. Knepley 385834e62ceSMatthew G. Knepley #undef __FUNCT__ 386834e62ceSMatthew G. Knepley #define __FUNCT__ "Volume_Triangle_Origin_Internal" 387834e62ceSMatthew G. Knepley PETSC_STATIC_INLINE void Volume_Triangle_Origin_Internal(PetscReal *vol, PetscReal coords[]) 388834e62ceSMatthew G. Knepley { 389834e62ceSMatthew G. Knepley Det2D_Internal(vol, coords); 390834e62ceSMatthew G. Knepley *vol *= 0.5; 391834e62ceSMatthew G. Knepley } 392834e62ceSMatthew G. Knepley 393834e62ceSMatthew G. Knepley #undef __FUNCT__ 394834e62ceSMatthew G. Knepley #define __FUNCT__ "Volume_Tetrahedron_Internal" 395834e62ceSMatthew G. Knepley PETSC_STATIC_INLINE void Volume_Tetrahedron_Internal(PetscReal *vol, PetscReal coords[]) 396834e62ceSMatthew G. Knepley { 397834e62ceSMatthew G. Knepley /* Signed volume is 1/6th of the determinant 398834e62ceSMatthew G. Knepley 399834e62ceSMatthew G. Knepley | 1 1 1 1 | 400834e62ceSMatthew G. Knepley | x0 x1 x2 x3 | 401834e62ceSMatthew G. Knepley | y0 y1 y2 y3 | 402834e62ceSMatthew G. Knepley | z0 z1 z2 z3 | 403834e62ceSMatthew G. Knepley 404834e62ceSMatthew G. Knepley but if x0,y0,z0 is the origin, we have 405834e62ceSMatthew G. Knepley 406834e62ceSMatthew G. Knepley | x1 x2 x3 | 407834e62ceSMatthew G. Knepley | y1 y2 y3 | 408834e62ceSMatthew G. Knepley | z1 z2 z3 | 409834e62ceSMatthew G. Knepley */ 410834e62ceSMatthew G. Knepley const PetscReal x1 = coords[3] - coords[0], y1 = coords[4] - coords[1], z1 = coords[5] - coords[2]; 411834e62ceSMatthew G. Knepley const PetscReal x2 = coords[6] - coords[0], y2 = coords[7] - coords[1], z2 = coords[8] - coords[2]; 412834e62ceSMatthew G. Knepley const PetscReal x3 = coords[9] - coords[0], y3 = coords[10] - coords[1], z3 = coords[11] - coords[2]; 413834e62ceSMatthew G. Knepley PetscReal M[9], detM; 414834e62ceSMatthew G. Knepley M[0] = x1; M[1] = x2; M[2] = x3; 415834e62ceSMatthew G. Knepley M[3] = y1; M[4] = y2; M[5] = y3; 416834e62ceSMatthew G. Knepley M[6] = z1; M[7] = z2; M[8] = z3; 417834e62ceSMatthew G. Knepley Det3D_Internal(&detM, M); 418834e62ceSMatthew G. Knepley *vol = 0.16666666666666666666666*detM; 419834e62ceSMatthew G. Knepley PetscLogFlops(10.0); 420834e62ceSMatthew G. Knepley } 421834e62ceSMatthew G. Knepley 422834e62ceSMatthew G. Knepley #undef __FUNCT__ 4230ec8681fSMatthew G. Knepley #define __FUNCT__ "Volume_Tetrahedron_Origin_Internal" 4240ec8681fSMatthew G. Knepley PETSC_STATIC_INLINE void Volume_Tetrahedron_Origin_Internal(PetscReal *vol, PetscReal coords[]) 4250ec8681fSMatthew G. Knepley { 4260ec8681fSMatthew G. Knepley Det3D_Internal(vol, coords); 4270ec8681fSMatthew G. Knepley *vol *= 0.16666666666666666666666; 4280ec8681fSMatthew G. Knepley } 4290ec8681fSMatthew G. Knepley 4300ec8681fSMatthew G. Knepley #undef __FUNCT__ 43117fe8556SMatthew G. Knepley #define __FUNCT__ "DMPlexComputeLineGeometry_Internal" 43217fe8556SMatthew G. Knepley static PetscErrorCode DMPlexComputeLineGeometry_Internal(DM dm, PetscInt e, PetscReal v0[], PetscReal J[], PetscReal invJ[], PetscReal *detJ) 43317fe8556SMatthew G. Knepley { 43417fe8556SMatthew G. Knepley PetscSection coordSection; 43517fe8556SMatthew G. Knepley Vec coordinates; 43617fe8556SMatthew G. Knepley PetscScalar *coords; 4377f07f362SMatthew G. Knepley PetscInt numCoords, d; 43817fe8556SMatthew G. Knepley PetscErrorCode ierr; 43917fe8556SMatthew G. Knepley 44017fe8556SMatthew G. Knepley PetscFunctionBegin; 44117fe8556SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 44217fe8556SMatthew G. Knepley ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 44317fe8556SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, e, &numCoords, &coords);CHKERRQ(ierr); 4447f07f362SMatthew G. Knepley *detJ = 0.0; 44517fe8556SMatthew G. Knepley if (numCoords == 4) { 4467f07f362SMatthew G. Knepley const PetscInt dim = 2; 4477f07f362SMatthew G. Knepley PetscReal R[4], J0; 4487f07f362SMatthew G. Knepley 4497f07f362SMatthew G. Knepley if (v0) {for (d = 0; d < dim; d++) v0[d] = PetscRealPart(coords[d]);} 4507f07f362SMatthew G. Knepley ierr = DMPlexComputeProjection2Dto1D_Internal(coords, R);CHKERRQ(ierr); 45117fe8556SMatthew G. Knepley if (J) { 4527f07f362SMatthew G. Knepley J0 = 0.5*PetscRealPart(coords[1]); 4537f07f362SMatthew G. Knepley J[0] = R[0]*J0; J[1] = R[1]; 4547f07f362SMatthew G. Knepley J[2] = R[2]*J0; J[3] = R[3]; 4557f07f362SMatthew G. Knepley Det2D_Internal(detJ, J); 45617fe8556SMatthew G. Knepley } 4577f07f362SMatthew G. Knepley if (invJ) {Invert2D_Internal(invJ, J, *detJ);} 4587f07f362SMatthew G. Knepley } else if (numCoords == 2) { 4597f07f362SMatthew G. Knepley const PetscInt dim = 1; 4607f07f362SMatthew G. Knepley 4617f07f362SMatthew G. Knepley if (v0) {for (d = 0; d < dim; d++) v0[d] = PetscRealPart(coords[d]);} 4627f07f362SMatthew G. Knepley if (J) { 4637f07f362SMatthew G. Knepley J[0] = 0.5*(PetscRealPart(coords[1]) - PetscRealPart(coords[0])); 46417fe8556SMatthew G. Knepley *detJ = J[0]; 46517fe8556SMatthew G. Knepley PetscLogFlops(2.0); 46617fe8556SMatthew G. Knepley } 4677f07f362SMatthew G. Knepley if (invJ) {invJ[0] = 1.0/J[0]; PetscLogFlops(1.0);} 4687f07f362SMatthew G. Knepley } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "The number of coordinates for this segment is %d != 2", numCoords); 46917fe8556SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, e, &numCoords, &coords);CHKERRQ(ierr); 47017fe8556SMatthew G. Knepley PetscFunctionReturn(0); 47117fe8556SMatthew G. Knepley } 47217fe8556SMatthew G. Knepley 47317fe8556SMatthew G. Knepley #undef __FUNCT__ 474ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexComputeTriangleGeometry_Internal" 475ccd2543fSMatthew G Knepley static PetscErrorCode DMPlexComputeTriangleGeometry_Internal(DM dm, PetscInt e, PetscReal v0[], PetscReal J[], PetscReal invJ[], PetscReal *detJ) 476ccd2543fSMatthew G Knepley { 477ccd2543fSMatthew G Knepley PetscSection coordSection; 478ccd2543fSMatthew G Knepley Vec coordinates; 4797c1f9639SMatthew G Knepley PetscScalar *coords; 4807f07f362SMatthew G. Knepley PetscInt numCoords, d, f, g; 481ccd2543fSMatthew G Knepley PetscErrorCode ierr; 482ccd2543fSMatthew G Knepley 483ccd2543fSMatthew G Knepley PetscFunctionBegin; 484ccd2543fSMatthew G Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 485ccd2543fSMatthew G Knepley ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 486ccd2543fSMatthew G Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, e, &numCoords, &coords);CHKERRQ(ierr); 4877f07f362SMatthew G. Knepley *detJ = 0.0; 488ccd2543fSMatthew G Knepley if (numCoords == 9) { 4897f07f362SMatthew G. Knepley const PetscInt dim = 3; 4907f07f362SMatthew G. Knepley PetscReal R[9], J0[9] = {1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0}; 4917f07f362SMatthew G. Knepley 4927f07f362SMatthew G. Knepley if (v0) {for (d = 0; d < dim; d++) v0[d] = PetscRealPart(coords[d]);} 4937f07f362SMatthew G. Knepley ierr = DMPlexComputeProjection3Dto2D_Internal(coords, R);CHKERRQ(ierr); 4947f07f362SMatthew G. Knepley if (J) { 4957f07f362SMatthew G. Knepley for (d = 0; d < dim-1; d++) { 4967f07f362SMatthew G. Knepley for (f = 0; f < dim-1; f++) { 4977f07f362SMatthew G. Knepley J0[d*(dim+1)+f] = 0.5*(PetscRealPart(coords[(f+1)*dim+d]) - PetscRealPart(coords[0*dim+d])); 498ccd2543fSMatthew G Knepley } 4997f07f362SMatthew G. Knepley } 5007f07f362SMatthew G. Knepley PetscLogFlops(8.0); 5017f07f362SMatthew G. Knepley for (d = 0; d < dim; d++) { 5027f07f362SMatthew G. Knepley for (f = 0; f < dim; f++) { 5037f07f362SMatthew G. Knepley J[d*dim+f] = 0.0; 5047f07f362SMatthew G. Knepley for (g = 0; g < dim; g++) { 5057f07f362SMatthew G. Knepley J[d*dim+f] += R[d*dim+g]*J0[g*dim+f]; 5067f07f362SMatthew G. Knepley } 5077f07f362SMatthew G. Knepley } 5087f07f362SMatthew G. Knepley } 5097f07f362SMatthew G. Knepley PetscLogFlops(18.0); 5107f07f362SMatthew G. Knepley Det3D_Internal(detJ, J); 5117f07f362SMatthew G. Knepley } 5127f07f362SMatthew G. Knepley if (invJ) {Invert3D_Internal(invJ, J, *detJ);} 5137f07f362SMatthew G. Knepley } else if (numCoords == 6) { 5147f07f362SMatthew G. Knepley const PetscInt dim = 2; 5157f07f362SMatthew G. Knepley 5167f07f362SMatthew G. Knepley if (v0) {for (d = 0; d < dim; d++) v0[d] = PetscRealPart(coords[d]);} 517ccd2543fSMatthew G Knepley if (J) { 518ccd2543fSMatthew G Knepley for (d = 0; d < dim; d++) { 519ccd2543fSMatthew G Knepley for (f = 0; f < dim; f++) { 520ccd2543fSMatthew G Knepley J[d*dim+f] = 0.5*(PetscRealPart(coords[(f+1)*dim+d]) - PetscRealPart(coords[0*dim+d])); 521ccd2543fSMatthew G Knepley } 522ccd2543fSMatthew G Knepley } 5237f07f362SMatthew G. Knepley PetscLogFlops(8.0); 5247f07f362SMatthew G. Knepley Det2D_Internal(detJ, J); 525ccd2543fSMatthew G Knepley } 5267f07f362SMatthew G. Knepley if (invJ) {Invert2D_Internal(invJ, J, *detJ);} 5277f07f362SMatthew G. Knepley } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "The number of coordinates for this triangle is %d != 6", numCoords); 528ccd2543fSMatthew G Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, e, &numCoords, &coords);CHKERRQ(ierr); 529ccd2543fSMatthew G Knepley PetscFunctionReturn(0); 530ccd2543fSMatthew G Knepley } 531ccd2543fSMatthew G Knepley 532ccd2543fSMatthew G Knepley #undef __FUNCT__ 533ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexComputeRectangleGeometry_Internal" 534ccd2543fSMatthew G Knepley static PetscErrorCode DMPlexComputeRectangleGeometry_Internal(DM dm, PetscInt e, PetscReal v0[], PetscReal J[], PetscReal invJ[], PetscReal *detJ) 535ccd2543fSMatthew G Knepley { 536ccd2543fSMatthew G Knepley PetscSection coordSection; 537ccd2543fSMatthew G Knepley Vec coordinates; 5387c1f9639SMatthew G Knepley PetscScalar *coords; 539ccd2543fSMatthew G Knepley const PetscInt dim = 2; 540ccd2543fSMatthew G Knepley PetscInt d, f; 541ccd2543fSMatthew G Knepley PetscErrorCode ierr; 542ccd2543fSMatthew G Knepley 543ccd2543fSMatthew G Knepley PetscFunctionBegin; 544ccd2543fSMatthew G Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 545ccd2543fSMatthew G Knepley ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 546ccd2543fSMatthew G Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, e, NULL, &coords);CHKERRQ(ierr); 5477f07f362SMatthew G. Knepley *detJ = 0.0; 5487f07f362SMatthew G. Knepley if (v0) {for (d = 0; d < dim; d++) v0[d] = PetscRealPart(coords[d]);} 549ccd2543fSMatthew G Knepley if (J) { 550ccd2543fSMatthew G Knepley for (d = 0; d < dim; d++) { 551ccd2543fSMatthew G Knepley for (f = 0; f < dim; f++) { 552ccd2543fSMatthew G Knepley J[d*dim+f] = 0.5*(PetscRealPart(coords[(f*2+1)*dim+d]) - PetscRealPart(coords[0*dim+d])); 553ccd2543fSMatthew G Knepley } 554ccd2543fSMatthew G Knepley } 5557f07f362SMatthew G. Knepley PetscLogFlops(8.0); 5567f07f362SMatthew G. Knepley Det2D_Internal(detJ, J); 557ccd2543fSMatthew G Knepley } 5587f07f362SMatthew G. Knepley if (invJ) {Invert2D_Internal(invJ, J, *detJ);} 559ccd2543fSMatthew G Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, e, NULL, &coords);CHKERRQ(ierr); 560ccd2543fSMatthew G Knepley PetscFunctionReturn(0); 561ccd2543fSMatthew G Knepley } 562ccd2543fSMatthew G Knepley 563ccd2543fSMatthew G Knepley #undef __FUNCT__ 564ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexComputeTetrahedronGeometry_Internal" 565ccd2543fSMatthew G Knepley static PetscErrorCode DMPlexComputeTetrahedronGeometry_Internal(DM dm, PetscInt e, PetscReal v0[], PetscReal J[], PetscReal invJ[], PetscReal *detJ) 566ccd2543fSMatthew G Knepley { 567ccd2543fSMatthew G Knepley PetscSection coordSection; 568ccd2543fSMatthew G Knepley Vec coordinates; 5697c1f9639SMatthew G Knepley PetscScalar *coords; 570ccd2543fSMatthew G Knepley const PetscInt dim = 3; 571ccd2543fSMatthew G Knepley PetscInt d, f; 572ccd2543fSMatthew G Knepley PetscErrorCode ierr; 573ccd2543fSMatthew G Knepley 574ccd2543fSMatthew G Knepley PetscFunctionBegin; 575ccd2543fSMatthew G Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 576ccd2543fSMatthew G Knepley ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 577ccd2543fSMatthew G Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, e, NULL, &coords);CHKERRQ(ierr); 5787f07f362SMatthew G. Knepley *detJ = 0.0; 5797f07f362SMatthew G. Knepley if (v0) {for (d = 0; d < dim; d++) v0[d] = PetscRealPart(coords[d]);} 580ccd2543fSMatthew G Knepley if (J) { 581ccd2543fSMatthew G Knepley for (d = 0; d < dim; d++) { 582ccd2543fSMatthew G Knepley for (f = 0; f < dim; f++) { 583ccd2543fSMatthew G Knepley J[d*dim+f] = 0.5*(PetscRealPart(coords[(f+1)*dim+d]) - PetscRealPart(coords[0*dim+d])); 584ccd2543fSMatthew G Knepley } 585ccd2543fSMatthew G Knepley } 5867f07f362SMatthew G. Knepley PetscLogFlops(18.0); 5877f07f362SMatthew G. Knepley Det3D_Internal(detJ, J); 588ccd2543fSMatthew G Knepley } 5897f07f362SMatthew G. Knepley if (invJ) {Invert3D_Internal(invJ, J, *detJ);} 590ccd2543fSMatthew G Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, e, NULL, &coords);CHKERRQ(ierr); 591ccd2543fSMatthew G Knepley PetscFunctionReturn(0); 592ccd2543fSMatthew G Knepley } 593ccd2543fSMatthew G Knepley 594ccd2543fSMatthew G Knepley #undef __FUNCT__ 595ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexComputeHexahedronGeometry_Internal" 596ccd2543fSMatthew G Knepley static PetscErrorCode DMPlexComputeHexahedronGeometry_Internal(DM dm, PetscInt e, PetscReal v0[], PetscReal J[], PetscReal invJ[], PetscReal *detJ) 597ccd2543fSMatthew G Knepley { 598ccd2543fSMatthew G Knepley PetscSection coordSection; 599ccd2543fSMatthew G Knepley Vec coordinates; 6007c1f9639SMatthew G Knepley PetscScalar *coords; 601ccd2543fSMatthew G Knepley const PetscInt dim = 3; 602ccd2543fSMatthew G Knepley PetscInt d; 603ccd2543fSMatthew G Knepley PetscErrorCode ierr; 604ccd2543fSMatthew G Knepley 605ccd2543fSMatthew G Knepley PetscFunctionBegin; 606ccd2543fSMatthew G Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 607ccd2543fSMatthew G Knepley ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 608ccd2543fSMatthew G Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, e, NULL, &coords);CHKERRQ(ierr); 6097f07f362SMatthew G. Knepley *detJ = 0.0; 6107f07f362SMatthew G. Knepley if (v0) {for (d = 0; d < dim; d++) v0[d] = PetscRealPart(coords[d]);} 611ccd2543fSMatthew G Knepley if (J) { 612ccd2543fSMatthew G Knepley for (d = 0; d < dim; d++) { 613de36ddddSMatthew G. Knepley J[d*dim+0] = 0.5*(PetscRealPart(coords[(2+1)*dim+d]) - PetscRealPart(coords[0*dim+d])); 614ccd2543fSMatthew G Knepley J[d*dim+1] = 0.5*(PetscRealPart(coords[(1+1)*dim+d]) - PetscRealPart(coords[0*dim+d])); 615ccd2543fSMatthew G Knepley J[d*dim+2] = 0.5*(PetscRealPart(coords[(3+1)*dim+d]) - PetscRealPart(coords[0*dim+d])); 616ccd2543fSMatthew G Knepley } 6177f07f362SMatthew G. Knepley PetscLogFlops(18.0); 6187f07f362SMatthew G. Knepley Det3D_Internal(detJ, J); 619ccd2543fSMatthew G Knepley } 6207f07f362SMatthew G. Knepley if (invJ) {Invert3D_Internal(invJ, J, *detJ);} 6217f07f362SMatthew G. Knepley *detJ *= -8.0; 622ccd2543fSMatthew G Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, e, NULL, &coords);CHKERRQ(ierr); 623ccd2543fSMatthew G Knepley PetscFunctionReturn(0); 624ccd2543fSMatthew G Knepley } 625ccd2543fSMatthew G Knepley 626ccd2543fSMatthew G Knepley #undef __FUNCT__ 627ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexComputeCellGeometry" 628ccd2543fSMatthew G Knepley /*@C 629ccd2543fSMatthew G Knepley DMPlexComputeCellGeometry - Compute the Jacobian, inverse Jacobian, and Jacobian determinant for a given cell 630ccd2543fSMatthew G Knepley 631ccd2543fSMatthew G Knepley Collective on DM 632ccd2543fSMatthew G Knepley 633ccd2543fSMatthew G Knepley Input Arguments: 634ccd2543fSMatthew G Knepley + dm - the DM 635ccd2543fSMatthew G Knepley - cell - the cell 636ccd2543fSMatthew G Knepley 637ccd2543fSMatthew G Knepley Output Arguments: 638ccd2543fSMatthew G Knepley + v0 - the translation part of this affine transform 639ccd2543fSMatthew G Knepley . J - the Jacobian of the transform from the reference element 640ccd2543fSMatthew G Knepley . invJ - the inverse of the Jacobian 641ccd2543fSMatthew G Knepley - detJ - the Jacobian determinant 642ccd2543fSMatthew G Knepley 643ccd2543fSMatthew G Knepley Level: advanced 644ccd2543fSMatthew G Knepley 645ccd2543fSMatthew G Knepley Fortran Notes: 646ccd2543fSMatthew G Knepley Since it returns arrays, this routine is only available in Fortran 90, and you must 647ccd2543fSMatthew G Knepley include petsc.h90 in your code. 648ccd2543fSMatthew G Knepley 649ccd2543fSMatthew G Knepley .seealso: DMPlexGetCoordinateSection(), DMPlexGetCoordinateVec() 650ccd2543fSMatthew G Knepley @*/ 651ccd2543fSMatthew G Knepley PetscErrorCode DMPlexComputeCellGeometry(DM dm, PetscInt cell, PetscReal *v0, PetscReal *J, PetscReal *invJ, PetscReal *detJ) 652ccd2543fSMatthew G Knepley { 65349dc4407SMatthew G. Knepley PetscInt depth, dim, coneSize; 654ccd2543fSMatthew G Knepley PetscErrorCode ierr; 655ccd2543fSMatthew G Knepley 656ccd2543fSMatthew G Knepley PetscFunctionBegin; 657139a35ccSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 658ccd2543fSMatthew G Knepley ierr = DMPlexGetConeSize(dm, cell, &coneSize);CHKERRQ(ierr); 65949dc4407SMatthew G. Knepley if (depth == 1) { 6605743f1d7SMatthew G. Knepley ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 661ccd2543fSMatthew G Knepley switch (dim) { 66217fe8556SMatthew G. Knepley case 1: 66317fe8556SMatthew G. Knepley ierr = DMPlexComputeLineGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr); 66417fe8556SMatthew G. Knepley break; 665ccd2543fSMatthew G Knepley case 2: 666ccd2543fSMatthew G Knepley switch (coneSize) { 667ccd2543fSMatthew G Knepley case 3: 668ccd2543fSMatthew G Knepley ierr = DMPlexComputeTriangleGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr); 669ccd2543fSMatthew G Knepley break; 670ccd2543fSMatthew G Knepley case 4: 671ccd2543fSMatthew G Knepley ierr = DMPlexComputeRectangleGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr); 672ccd2543fSMatthew G Knepley break; 673ccd2543fSMatthew G Knepley default: 674ccd2543fSMatthew G Knepley SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupported number of vertices %D in cell %D for element geometry computation", coneSize, cell); 675ccd2543fSMatthew G Knepley } 676ccd2543fSMatthew G Knepley break; 677ccd2543fSMatthew G Knepley case 3: 678ccd2543fSMatthew G Knepley switch (coneSize) { 679ccd2543fSMatthew G Knepley case 4: 680ccd2543fSMatthew G Knepley ierr = DMPlexComputeTetrahedronGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr); 681ccd2543fSMatthew G Knepley break; 682ccd2543fSMatthew G Knepley case 8: 683ccd2543fSMatthew G Knepley ierr = DMPlexComputeHexahedronGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr); 684ccd2543fSMatthew G Knepley break; 685ccd2543fSMatthew G Knepley default: 686ccd2543fSMatthew G Knepley SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupported number of vertices %D in cell %D for element geometry computation", coneSize, cell); 687ccd2543fSMatthew G Knepley } 688ccd2543fSMatthew G Knepley break; 689ccd2543fSMatthew G Knepley default: 690ccd2543fSMatthew G Knepley SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupported dimension %D for element geometry computation", dim); 691ccd2543fSMatthew G Knepley } 69249dc4407SMatthew G. Knepley } else { 6935743f1d7SMatthew G. Knepley /* We need to keep a pointer to the depth label */ 6945743f1d7SMatthew G. Knepley ierr = DMPlexGetLabelValue(dm, "depth", cell, &dim);CHKERRQ(ierr); 69549dc4407SMatthew G. Knepley /* Cone size is now the number of faces */ 69649dc4407SMatthew G. Knepley switch (dim) { 69717fe8556SMatthew G. Knepley case 1: 69817fe8556SMatthew G. Knepley ierr = DMPlexComputeLineGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr); 69917fe8556SMatthew G. Knepley break; 70049dc4407SMatthew G. Knepley case 2: 70149dc4407SMatthew G. Knepley switch (coneSize) { 70249dc4407SMatthew G. Knepley case 3: 70349dc4407SMatthew G. Knepley ierr = DMPlexComputeTriangleGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr); 70449dc4407SMatthew G. Knepley break; 70549dc4407SMatthew G. Knepley case 4: 70649dc4407SMatthew G. Knepley ierr = DMPlexComputeRectangleGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr); 70749dc4407SMatthew G. Knepley break; 70849dc4407SMatthew G. Knepley default: 70949dc4407SMatthew G. Knepley SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupported number of vertices %D in cell %D for element geometry computation", coneSize, cell); 71049dc4407SMatthew G. Knepley } 71149dc4407SMatthew G. Knepley break; 71249dc4407SMatthew G. Knepley case 3: 71349dc4407SMatthew G. Knepley switch (coneSize) { 71449dc4407SMatthew G. Knepley case 4: 71549dc4407SMatthew G. Knepley ierr = DMPlexComputeTetrahedronGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr); 71649dc4407SMatthew G. Knepley break; 71749dc4407SMatthew G. Knepley case 6: 71849dc4407SMatthew G. Knepley ierr = DMPlexComputeHexahedronGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr); 71949dc4407SMatthew G. Knepley break; 72049dc4407SMatthew G. Knepley default: 72149dc4407SMatthew G. Knepley SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupported number of vertices %D in cell %D for element geometry computation", coneSize, cell); 72249dc4407SMatthew G. Knepley } 72349dc4407SMatthew G. Knepley break; 72449dc4407SMatthew G. Knepley default: 72549dc4407SMatthew G. Knepley SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupported dimension %D for element geometry computation", dim); 72649dc4407SMatthew G. Knepley } 72749dc4407SMatthew G. Knepley } 728ccd2543fSMatthew G Knepley PetscFunctionReturn(0); 729ccd2543fSMatthew G Knepley } 730834e62ceSMatthew G. Knepley 731834e62ceSMatthew G. Knepley #undef __FUNCT__ 732cc08537eSMatthew G. Knepley #define __FUNCT__ "DMPlexComputeGeometryFVM_1D_Internal" 733*011ea5d8SMatthew G. Knepley static PetscErrorCode DMPlexComputeGeometryFVM_1D_Internal(DM dm, PetscInt dim, PetscInt cell, PetscReal *vol, PetscReal centroid[], PetscReal normal[]) 734cc08537eSMatthew G. Knepley { 735cc08537eSMatthew G. Knepley PetscSection coordSection; 736cc08537eSMatthew G. Knepley Vec coordinates; 737cc08537eSMatthew G. Knepley PetscScalar *coords; 738cc08537eSMatthew G. Knepley PetscInt coordSize; 739cc08537eSMatthew G. Knepley PetscErrorCode ierr; 740cc08537eSMatthew G. Knepley 741cc08537eSMatthew G. Knepley PetscFunctionBegin; 742cc08537eSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 743cc08537eSMatthew G. Knepley ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 744cc08537eSMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, cell, &coordSize, &coords);CHKERRQ(ierr); 745*011ea5d8SMatthew G. Knepley if (dim != 2) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "We only support 2D edges right now"); 746cc08537eSMatthew G. Knepley if (centroid) { 747cc08537eSMatthew G. Knepley centroid[0] = 0.5*(coords[0] + coords[dim+0]); 748cc08537eSMatthew G. Knepley centroid[1] = 0.5*(coords[1] + coords[dim+1]); 749cc08537eSMatthew G. Knepley } 750cc08537eSMatthew G. Knepley if (normal) { 751cc08537eSMatthew G. Knepley normal[0] = (coords[1] - coords[dim+1]); 752cc08537eSMatthew G. Knepley normal[1] = -(coords[0] - coords[dim+0]); 753cc08537eSMatthew G. Knepley } 754cc08537eSMatthew G. Knepley if (vol) { 755cc08537eSMatthew G. Knepley *vol = sqrt(PetscSqr(coords[0] - coords[dim+0]) + PetscSqr(coords[1] - coords[dim+1])); 756cc08537eSMatthew G. Knepley } 757cc08537eSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, cell, &coordSize, &coords);CHKERRQ(ierr); 758cc08537eSMatthew G. Knepley PetscFunctionReturn(0); 759cc08537eSMatthew G. Knepley } 760cc08537eSMatthew G. Knepley 761cc08537eSMatthew G. Knepley #undef __FUNCT__ 762cc08537eSMatthew G. Knepley #define __FUNCT__ "DMPlexComputeGeometryFVM_2D_Internal" 763cc08537eSMatthew G. Knepley /* Centroid_i = (\sum_n A_n Cn_i ) / A */ 764*011ea5d8SMatthew G. Knepley static PetscErrorCode DMPlexComputeGeometryFVM_2D_Internal(DM dm, PetscInt dim, PetscInt cell, PetscReal *vol, PetscReal centroid[], PetscReal normal[]) 765cc08537eSMatthew G. Knepley { 766cc08537eSMatthew G. Knepley PetscSection coordSection; 767cc08537eSMatthew G. Knepley Vec coordinates; 768cc08537eSMatthew G. Knepley PetscScalar *coords = NULL; 7690ec8681fSMatthew G. Knepley PetscReal vsum, csum[2], vtmp, ctmp[4]; 770cc08537eSMatthew G. Knepley PetscInt coordSize, numCorners, p, d; 771cc08537eSMatthew G. Knepley PetscErrorCode ierr; 772cc08537eSMatthew G. Knepley 773cc08537eSMatthew G. Knepley PetscFunctionBegin; 774*011ea5d8SMatthew G. Knepley if (dim != 2) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "We only support 2D triangles right now"); 775cc08537eSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 776cc08537eSMatthew G. Knepley ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 777cc08537eSMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, cell, &coordSize, &coords);CHKERRQ(ierr); 778cc08537eSMatthew G. Knepley numCorners = coordSize/dim; 7790ec8681fSMatthew G. Knepley for (p = 0; p < numCorners; ++p) { 7800ec8681fSMatthew G. Knepley /* Need to do this copy to get types right */ 781cc08537eSMatthew G. Knepley for (d = 0; d < dim; ++d) { 7820ec8681fSMatthew G. Knepley ctmp[d] = coords[p*dim+d]; 7830ec8681fSMatthew G. Knepley ctmp[dim+d] = coords[((p+1)%numCorners)*dim+d]; 784cc08537eSMatthew G. Knepley } 785cc08537eSMatthew G. Knepley Volume_Triangle_Origin_Internal(&vtmp, ctmp); 786cc08537eSMatthew G. Knepley vsum += vtmp; 787cc08537eSMatthew G. Knepley for (d = 0; d < dim; ++d) { 7880ec8681fSMatthew G. Knepley csum[d] += (ctmp[d] + ctmp[dim+d])*vtmp; 7890ec8681fSMatthew G. Knepley } 7900ec8681fSMatthew G. Knepley } 7910ec8681fSMatthew G. Knepley for (d = 0; d < dim; ++d) { 792cc08537eSMatthew G. Knepley csum[d] /= (dim+1)*vsum; 793cc08537eSMatthew G. Knepley } 794cc08537eSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, cell, &coordSize, &coords);CHKERRQ(ierr); 795cc08537eSMatthew G. Knepley if (vol) *vol = PetscAbsScalar(vsum); 796cc08537eSMatthew G. Knepley if (centroid) for (d = 0; d < dim; ++d) centroid[d] = csum[d]; 797*011ea5d8SMatthew G. Knepley if (normal) { 798*011ea5d8SMatthew G. Knepley if (dim > 2) { 799*011ea5d8SMatthew G. Knepley } else { 800*011ea5d8SMatthew G. Knepley for (d = 0; d < dim; ++d) normal[d] = 0.0; 801*011ea5d8SMatthew G. Knepley } 802*011ea5d8SMatthew G. Knepley } 803cc08537eSMatthew G. Knepley PetscFunctionReturn(0); 804cc08537eSMatthew G. Knepley } 805cc08537eSMatthew G. Knepley 806cc08537eSMatthew G. Knepley #undef __FUNCT__ 8070ec8681fSMatthew G. Knepley #define __FUNCT__ "DMPlexComputeGeometryFVM_3D_Internal" 8080ec8681fSMatthew G. Knepley /* Centroid_i = (\sum_n V_n Cn_i ) / V */ 809*011ea5d8SMatthew G. Knepley static PetscErrorCode DMPlexComputeGeometryFVM_3D_Internal(DM dm, PetscInt dim, PetscInt cell, PetscReal *vol, PetscReal centroid[], PetscReal normal[]) 8100ec8681fSMatthew G. Knepley { 8110ec8681fSMatthew G. Knepley PetscSection coordSection; 8120ec8681fSMatthew G. Knepley Vec coordinates; 8130ec8681fSMatthew G. Knepley PetscScalar *coords = NULL; 8140ec8681fSMatthew G. Knepley PetscReal vsum, vtmp, coordsTmp[3*3]; 815*011ea5d8SMatthew G. Knepley const PetscInt *faces; 8160ec8681fSMatthew G. Knepley PetscInt numFaces, f, coordSize, numCorners, p, d; 8170ec8681fSMatthew G. Knepley PetscErrorCode ierr; 8180ec8681fSMatthew G. Knepley 8190ec8681fSMatthew G. Knepley PetscFunctionBegin; 8200ec8681fSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 8210ec8681fSMatthew G. Knepley ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 8220ec8681fSMatthew G. Knepley 8230ec8681fSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cell, &numFaces);CHKERRQ(ierr); 8240ec8681fSMatthew G. Knepley ierr = DMPlexGetCone(dm, cell, &faces);CHKERRQ(ierr); 8250ec8681fSMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 826*011ea5d8SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, faces[f], &coordSize, &coords);CHKERRQ(ierr); 8270ec8681fSMatthew G. Knepley numCorners = coordSize/dim; 8280ec8681fSMatthew G. Knepley switch (numCorners) { 8290ec8681fSMatthew G. Knepley case 3: 8300ec8681fSMatthew G. Knepley for (d = 0; d < dim; ++d) { 8310ec8681fSMatthew G. Knepley coordsTmp[0*dim+d] = coords[0*dim+d]; 8320ec8681fSMatthew G. Knepley coordsTmp[1*dim+d] = coords[1*dim+d]; 8330ec8681fSMatthew G. Knepley coordsTmp[2*dim+d] = coords[2*dim+d]; 8340ec8681fSMatthew G. Knepley } 8350ec8681fSMatthew G. Knepley Volume_Tetrahedron_Origin_Internal(&vtmp, coordsTmp); 8360ec8681fSMatthew G. Knepley vsum += vtmp; 8370ec8681fSMatthew G. Knepley if (centroid) { 8380ec8681fSMatthew G. Knepley for (d = 0; d < dim; ++d) { 8390ec8681fSMatthew G. Knepley for (p = 0; p < 3; ++p) centroid[d] += coords[p*dim+d]*vtmp; 8400ec8681fSMatthew G. Knepley } 8410ec8681fSMatthew G. Knepley } 8420ec8681fSMatthew G. Knepley break; 8430ec8681fSMatthew G. Knepley case 4: 8440ec8681fSMatthew G. Knepley /* DO FOR PYRAMID */ 8450ec8681fSMatthew G. Knepley /* First tet */ 8460ec8681fSMatthew G. Knepley for (d = 0; d < dim; ++d) { 8470ec8681fSMatthew G. Knepley coordsTmp[0*dim+d] = coords[0*dim+d]; 8480ec8681fSMatthew G. Knepley coordsTmp[1*dim+d] = coords[1*dim+d]; 8490ec8681fSMatthew G. Knepley coordsTmp[2*dim+d] = coords[3*dim+d]; 8500ec8681fSMatthew G. Knepley } 8510ec8681fSMatthew G. Knepley Volume_Tetrahedron_Origin_Internal(&vtmp, coordsTmp); 8520ec8681fSMatthew G. Knepley vsum += vtmp; 8530ec8681fSMatthew G. Knepley if (centroid) { 8540ec8681fSMatthew G. Knepley for (d = 0; d < dim; ++d) { 8550ec8681fSMatthew G. Knepley for (p = 0; p < 3; ++p) centroid[d] += coordsTmp[p*dim+d]*vtmp; 8560ec8681fSMatthew G. Knepley } 8570ec8681fSMatthew G. Knepley } 8580ec8681fSMatthew G. Knepley /* Second tet */ 8590ec8681fSMatthew G. Knepley for (d = 0; d < dim; ++d) { 8600ec8681fSMatthew G. Knepley coordsTmp[0*dim+d] = coords[1*dim+d]; 8610ec8681fSMatthew G. Knepley coordsTmp[1*dim+d] = coords[2*dim+d]; 8620ec8681fSMatthew G. Knepley coordsTmp[2*dim+d] = coords[3*dim+d]; 8630ec8681fSMatthew G. Knepley } 8640ec8681fSMatthew G. Knepley Volume_Tetrahedron_Origin_Internal(&vtmp, coordsTmp); 8650ec8681fSMatthew G. Knepley vsum += vtmp; 8660ec8681fSMatthew G. Knepley if (centroid) { 8670ec8681fSMatthew G. Knepley for (d = 0; d < dim; ++d) { 8680ec8681fSMatthew G. Knepley for (p = 0; p < 3; ++p) centroid[d] += coordsTmp[p*dim+d]*vtmp; 8690ec8681fSMatthew G. Knepley } 8700ec8681fSMatthew G. Knepley } 8710ec8681fSMatthew G. Knepley break; 8720ec8681fSMatthew G. Knepley default: 8730ec8681fSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle faces with %d vertices", numCorners); 8740ec8681fSMatthew G. Knepley } 8750ec8681fSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, cell, &coordSize, &coords);CHKERRQ(ierr); 8760ec8681fSMatthew G. Knepley } 8770ec8681fSMatthew G. Knepley if (vol) *vol = PetscAbsScalar(vsum); 8780ec8681fSMatthew G. Knepley if (normal) for (d = 0; d < dim; ++d) normal[d] = 0.0; 8790ec8681fSMatthew G. Knepley PetscFunctionReturn(0); 8800ec8681fSMatthew G. Knepley } 8810ec8681fSMatthew G. Knepley 8820ec8681fSMatthew G. Knepley #undef __FUNCT__ 883834e62ceSMatthew G. Knepley #define __FUNCT__ "DMPlexComputeCellGeometryFVM" 884834e62ceSMatthew G. Knepley /*@C 885834e62ceSMatthew G. Knepley DMPlexComputeCellGeometryFVM - Compute the volume for a given cell 886834e62ceSMatthew G. Knepley 887834e62ceSMatthew G. Knepley Collective on DM 888834e62ceSMatthew G. Knepley 889834e62ceSMatthew G. Knepley Input Arguments: 890834e62ceSMatthew G. Knepley + dm - the DM 891834e62ceSMatthew G. Knepley - cell - the cell 892834e62ceSMatthew G. Knepley 893834e62ceSMatthew G. Knepley Output Arguments: 894834e62ceSMatthew G. Knepley + volume - the cell volume 895cc08537eSMatthew G. Knepley . centroid - the cell centroid 896cc08537eSMatthew G. Knepley - normal - the cell normal, if appropriate 897834e62ceSMatthew G. Knepley 898834e62ceSMatthew G. Knepley Level: advanced 899834e62ceSMatthew G. Knepley 900834e62ceSMatthew G. Knepley Fortran Notes: 901834e62ceSMatthew G. Knepley Since it returns arrays, this routine is only available in Fortran 90, and you must 902834e62ceSMatthew G. Knepley include petsc.h90 in your code. 903834e62ceSMatthew G. Knepley 904834e62ceSMatthew G. Knepley .seealso: DMPlexGetCoordinateSection(), DMPlexGetCoordinateVec() 905834e62ceSMatthew G. Knepley @*/ 906cc08537eSMatthew G. Knepley PetscErrorCode DMPlexComputeCellGeometryFVM(DM dm, PetscInt cell, PetscReal *vol, PetscReal centroid[], PetscReal normal[]) 907834e62ceSMatthew G. Knepley { 9080ec8681fSMatthew G. Knepley PetscInt depth, dim; 909834e62ceSMatthew G. Knepley PetscErrorCode ierr; 910834e62ceSMatthew G. Knepley 911834e62ceSMatthew G. Knepley PetscFunctionBegin; 912834e62ceSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 913834e62ceSMatthew G. Knepley ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 914834e62ceSMatthew G. Knepley if (depth != dim) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh must be interpolated"); 915834e62ceSMatthew G. Knepley /* We need to keep a pointer to the depth label */ 916*011ea5d8SMatthew G. Knepley ierr = DMPlexGetLabelValue(dm, "depth", cell, &depth);CHKERRQ(ierr); 917834e62ceSMatthew G. Knepley /* Cone size is now the number of faces */ 918*011ea5d8SMatthew G. Knepley switch (depth) { 919cc08537eSMatthew G. Knepley case 1: 920*011ea5d8SMatthew G. Knepley ierr = DMPlexComputeGeometryFVM_1D_Internal(dm, dim, cell, vol, centroid, normal);CHKERRQ(ierr); 921cc08537eSMatthew G. Knepley break; 922834e62ceSMatthew G. Knepley case 2: 923*011ea5d8SMatthew G. Knepley ierr = DMPlexComputeGeometryFVM_2D_Internal(dm, dim, cell, vol, centroid, normal);CHKERRQ(ierr); 924834e62ceSMatthew G. Knepley break; 925834e62ceSMatthew G. Knepley case 3: 926*011ea5d8SMatthew G. Knepley ierr = DMPlexComputeGeometryFVM_3D_Internal(dm, dim, cell, vol, centroid, normal);CHKERRQ(ierr); 927834e62ceSMatthew G. Knepley break; 928834e62ceSMatthew G. Knepley default: 929834e62ceSMatthew G. Knepley SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupported dimension %D for element geometry computation", dim); 930834e62ceSMatthew G. Knepley } 931834e62ceSMatthew G. Knepley PetscFunctionReturn(0); 932834e62ceSMatthew G. Knepley } 933