xref: /petsc/src/dm/impls/plex/plexgeometry.c (revision 738683725d82eaf98806d7ec2296ccee0d71c48e)
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__
205ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexComputeProjection3Dto2D_Internal"
206ccd2543fSMatthew G Knepley /*
207ccd2543fSMatthew G Knepley   DMPlexComputeProjection3Dto2D_Internal - Rewrite coordinates to be the 2D projection of the 3D
208ccd2543fSMatthew G Knepley */
209ccd2543fSMatthew G Knepley static PetscErrorCode DMPlexComputeProjection3Dto2D_Internal(PetscScalar coords[])
210ccd2543fSMatthew G Knepley {
211ccd2543fSMatthew G Knepley   PetscScalar    x1[3], x2[3], n[3], norm;
212da18b5e6SMatthew G Knepley   PetscScalar    R[9], x1p[3], x2p[3];
213da18b5e6SMatthew G Knepley   PetscScalar    sqrtz, alpha;
214ccd2543fSMatthew G Knepley   const PetscInt dim = 3;
215ccd2543fSMatthew G Knepley   PetscInt       d, e;
216ccd2543fSMatthew G Knepley 
217ccd2543fSMatthew G Knepley   PetscFunctionBegin;
218ccd2543fSMatthew G Knepley   /* 0) Calculate normal vector */
219ccd2543fSMatthew G Knepley   for (d = 0; d < dim; ++d) {
220ccd2543fSMatthew G Knepley     x1[d] = coords[1*dim+d] - coords[0*dim+d];
221ccd2543fSMatthew G Knepley     x2[d] = coords[2*dim+d] - coords[0*dim+d];
222ccd2543fSMatthew G Knepley   }
223ccd2543fSMatthew G Knepley   n[0] = x1[1]*x2[2] - x1[2]*x2[1];
224ccd2543fSMatthew G Knepley   n[1] = x1[2]*x2[0] - x1[0]*x2[2];
225ccd2543fSMatthew G Knepley   n[2] = x1[0]*x2[1] - x1[1]*x2[0];
226ccd2543fSMatthew G Knepley   norm = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
227ccd2543fSMatthew G Knepley   n[0] /= norm;
228ccd2543fSMatthew G Knepley   n[1] /= norm;
229ccd2543fSMatthew G Knepley   n[2] /= norm;
230ccd2543fSMatthew G Knepley   /* 1) Take the normal vector and rotate until it is \hat z
231ccd2543fSMatthew G Knepley 
232ccd2543fSMatthew G Knepley     Let the normal vector be <nx, ny, nz> and alpha = 1/sqrt(1 - nz^2), then
233ccd2543fSMatthew G Knepley 
234ccd2543fSMatthew G Knepley     R = /  alpha nx nz  alpha ny nz -1/alpha \
235ccd2543fSMatthew G Knepley         | -alpha ny     alpha nx        0    |
236ccd2543fSMatthew G Knepley         \     nx            ny         nz    /
237ccd2543fSMatthew G Knepley 
238ccd2543fSMatthew G Knepley     will rotate the normal vector to \hat z
239ccd2543fSMatthew G Knepley   */
240da18b5e6SMatthew G Knepley   sqrtz = sqrt(1.0 - n[2]*n[2]);
241*73868372SMatthew G. Knepley   /* Check for n = z */
242*73868372SMatthew G. Knepley   if (sqrtz < 1.0e-10) {
243*73868372SMatthew G. Knepley     coords[0] = 0.0;
244*73868372SMatthew G. Knepley     coords[1] = 0.0;
245*73868372SMatthew G. Knepley     if (n[2] < 0.0) {
246*73868372SMatthew G. Knepley       coords[2] = x2[0];
247*73868372SMatthew G. Knepley       coords[3] = x2[1];
248*73868372SMatthew G. Knepley       coords[4] = x1[0];
249*73868372SMatthew G. Knepley       coords[5] = x1[1];
250*73868372SMatthew G. Knepley     } else {
251*73868372SMatthew G. Knepley       coords[2] = x1[0];
252*73868372SMatthew G. Knepley       coords[3] = x1[1];
253*73868372SMatthew G. Knepley       coords[4] = x2[0];
254*73868372SMatthew G. Knepley       coords[5] = x2[1];
255*73868372SMatthew G. Knepley     }
256*73868372SMatthew G. Knepley     PetscFunctionReturn(0);
257*73868372SMatthew G. Knepley   }
258da18b5e6SMatthew G Knepley   alpha = 1.0/sqrtz;
259ccd2543fSMatthew G Knepley   R[0] =  alpha*n[0]*n[2]; R[1] = alpha*n[1]*n[2]; R[2] = -sqrtz;
260ccd2543fSMatthew G Knepley   R[3] = -alpha*n[1];      R[4] = alpha*n[0];      R[5] = 0.0;
261ccd2543fSMatthew G Knepley   R[6] =  n[0];            R[7] = n[1];            R[8] = n[2];
262ccd2543fSMatthew G Knepley   for (d = 0; d < dim; ++d) {
263ccd2543fSMatthew G Knepley     x1p[d] = 0.0;
264ccd2543fSMatthew G Knepley     x2p[d] = 0.0;
265ccd2543fSMatthew G Knepley     for (e = 0; e < dim; ++e) {
266ccd2543fSMatthew G Knepley       x1p[d] += R[d*dim+e]*x1[e];
267ccd2543fSMatthew G Knepley       x2p[d] += R[d*dim+e]*x2[e];
268ccd2543fSMatthew G Knepley     }
269ccd2543fSMatthew G Knepley   }
27088790e04SMatthew G Knepley   if (PetscAbsScalar(x1p[2]) > 1.0e-9) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid rotation calculated");
27188790e04SMatthew G Knepley   if (PetscAbsScalar(x2p[2]) > 1.0e-9) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid rotation calculated");
272ccd2543fSMatthew G Knepley   /* 2) Project to (x, y) */
273ccd2543fSMatthew G Knepley   coords[0] = 0.0;
274ccd2543fSMatthew G Knepley   coords[1] = 0.0;
275ccd2543fSMatthew G Knepley   coords[2] = x1p[0];
276ccd2543fSMatthew G Knepley   coords[3] = x1p[1];
277ccd2543fSMatthew G Knepley   coords[4] = x2p[0];
278ccd2543fSMatthew G Knepley   coords[5] = x2p[1];
279ccd2543fSMatthew G Knepley   PetscFunctionReturn(0);
280ccd2543fSMatthew G Knepley }
281ccd2543fSMatthew G Knepley 
282ccd2543fSMatthew G Knepley #undef __FUNCT__
283ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexComputeTriangleGeometry_Internal"
284ccd2543fSMatthew G Knepley static PetscErrorCode DMPlexComputeTriangleGeometry_Internal(DM dm, PetscInt e, PetscReal v0[], PetscReal J[], PetscReal invJ[], PetscReal *detJ)
285ccd2543fSMatthew G Knepley {
286ccd2543fSMatthew G Knepley   PetscSection   coordSection;
287ccd2543fSMatthew G Knepley   Vec            coordinates;
2887c1f9639SMatthew G Knepley   PetscScalar   *coords;
289ccd2543fSMatthew G Knepley   const PetscInt dim = 2;
290ccd2543fSMatthew G Knepley   PetscInt       numCoords, d, f;
291ccd2543fSMatthew G Knepley   PetscErrorCode ierr;
292ccd2543fSMatthew G Knepley 
293ccd2543fSMatthew G Knepley   PetscFunctionBegin;
294ccd2543fSMatthew G Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
295ccd2543fSMatthew G Knepley   ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
296ccd2543fSMatthew G Knepley   ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, e, &numCoords, &coords);CHKERRQ(ierr);
297ccd2543fSMatthew G Knepley   if (numCoords == 9) {
298ccd2543fSMatthew G Knepley     ierr = DMPlexComputeProjection3Dto2D_Internal(coords);CHKERRQ(ierr);
299ccd2543fSMatthew G Knepley   } else if (numCoords != 6) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "The number of coordinates for this triangle is %d != 6", numCoords);
300ccd2543fSMatthew G Knepley   if (v0) {
301ccd2543fSMatthew G Knepley     for (d = 0; d < dim; d++) v0[d] = PetscRealPart(coords[d]);
302ccd2543fSMatthew G Knepley   }
303ccd2543fSMatthew G Knepley   if (J) {
304ccd2543fSMatthew G Knepley     for (d = 0; d < dim; d++) {
305ccd2543fSMatthew G Knepley       for (f = 0; f < dim; f++) {
306ccd2543fSMatthew G Knepley         J[d*dim+f] = 0.5*(PetscRealPart(coords[(f+1)*dim+d]) - PetscRealPart(coords[0*dim+d]));
307ccd2543fSMatthew G Knepley       }
308ccd2543fSMatthew G Knepley     }
309ccd2543fSMatthew G Knepley     *detJ = J[0]*J[3] - J[1]*J[2];
310ccd2543fSMatthew G Knepley #if 0
311ccd2543fSMatthew G Knepley     if (detJ < 0.0) {
312ccd2543fSMatthew G Knepley       const PetscReal xLength = mesh->periodicity[0];
313ccd2543fSMatthew G Knepley 
314ccd2543fSMatthew G Knepley       if (xLength != 0.0) {
315ccd2543fSMatthew G Knepley         PetscReal v0x = coords[0*dim+0];
316ccd2543fSMatthew G Knepley 
317ccd2543fSMatthew G Knepley         if (v0x == 0.0) v0x = v0[0] = xLength;
318ccd2543fSMatthew G Knepley         for (f = 0; f < dim; f++) {
319ccd2543fSMatthew G Knepley           const PetscReal px = coords[(f+1)*dim+0] == 0.0 ? xLength : coords[(f+1)*dim+0];
320ccd2543fSMatthew G Knepley 
321ccd2543fSMatthew G Knepley           J[0*dim+f] = 0.5*(px - v0x);
322ccd2543fSMatthew G Knepley         }
323ccd2543fSMatthew G Knepley       }
324ccd2543fSMatthew G Knepley       detJ = J[0]*J[3] - J[1]*J[2];
325ccd2543fSMatthew G Knepley     }
326ccd2543fSMatthew G Knepley #endif
327ccd2543fSMatthew G Knepley     PetscLogFlops(8.0 + 3.0);
328923cbbb6SMatthew G. Knepley   } else {
329923cbbb6SMatthew G. Knepley     *detJ = 0.0;
330ccd2543fSMatthew G Knepley   }
331ccd2543fSMatthew G Knepley   if (invJ) {
332ccd2543fSMatthew G Knepley     const PetscReal invDet = 1.0/(*detJ);
333ccd2543fSMatthew G Knepley 
334ccd2543fSMatthew G Knepley     invJ[0] =  invDet*J[3];
335ccd2543fSMatthew G Knepley     invJ[1] = -invDet*J[1];
336ccd2543fSMatthew G Knepley     invJ[2] = -invDet*J[2];
337ccd2543fSMatthew G Knepley     invJ[3] =  invDet*J[0];
338ccd2543fSMatthew G Knepley     PetscLogFlops(5.0);
339ccd2543fSMatthew G Knepley   }
340ccd2543fSMatthew G Knepley   ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, e, &numCoords, &coords);CHKERRQ(ierr);
341ccd2543fSMatthew G Knepley   PetscFunctionReturn(0);
342ccd2543fSMatthew G Knepley }
343ccd2543fSMatthew G Knepley 
344ccd2543fSMatthew G Knepley #undef __FUNCT__
345ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexComputeRectangleGeometry_Internal"
346ccd2543fSMatthew G Knepley static PetscErrorCode DMPlexComputeRectangleGeometry_Internal(DM dm, PetscInt e, PetscReal v0[], PetscReal J[], PetscReal invJ[], PetscReal *detJ)
347ccd2543fSMatthew G Knepley {
348ccd2543fSMatthew G Knepley   PetscSection   coordSection;
349ccd2543fSMatthew G Knepley   Vec            coordinates;
3507c1f9639SMatthew G Knepley   PetscScalar   *coords;
351ccd2543fSMatthew G Knepley   const PetscInt dim = 2;
352ccd2543fSMatthew G Knepley   PetscInt       d, f;
353ccd2543fSMatthew G Knepley   PetscErrorCode ierr;
354ccd2543fSMatthew G Knepley 
355ccd2543fSMatthew G Knepley   PetscFunctionBegin;
356ccd2543fSMatthew G Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
357ccd2543fSMatthew G Knepley   ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
358ccd2543fSMatthew G Knepley   ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, e, NULL, &coords);CHKERRQ(ierr);
359ccd2543fSMatthew G Knepley   if (v0) {
360ccd2543fSMatthew G Knepley     for (d = 0; d < dim; d++) v0[d] = PetscRealPart(coords[d]);
361ccd2543fSMatthew G Knepley   }
362ccd2543fSMatthew G Knepley   if (J) {
363ccd2543fSMatthew G Knepley     for (d = 0; d < dim; d++) {
364ccd2543fSMatthew G Knepley       for (f = 0; f < dim; f++) {
365ccd2543fSMatthew G Knepley         J[d*dim+f] = 0.5*(PetscRealPart(coords[(f*2+1)*dim+d]) - PetscRealPart(coords[0*dim+d]));
366ccd2543fSMatthew G Knepley       }
367ccd2543fSMatthew G Knepley     }
368ccd2543fSMatthew G Knepley     *detJ = J[0]*J[3] - J[1]*J[2];
369ccd2543fSMatthew G Knepley     PetscLogFlops(8.0 + 3.0);
370923cbbb6SMatthew G. Knepley   } else {
371923cbbb6SMatthew G. Knepley     *detJ = 0.0;
372ccd2543fSMatthew G Knepley   }
373ccd2543fSMatthew G Knepley   if (invJ) {
374ccd2543fSMatthew G Knepley     const PetscReal invDet = 1.0/(*detJ);
375ccd2543fSMatthew G Knepley 
376ccd2543fSMatthew G Knepley     invJ[0] =  invDet*J[3];
377ccd2543fSMatthew G Knepley     invJ[1] = -invDet*J[1];
378ccd2543fSMatthew G Knepley     invJ[2] = -invDet*J[2];
379ccd2543fSMatthew G Knepley     invJ[3] =  invDet*J[0];
380ccd2543fSMatthew G Knepley     PetscLogFlops(5.0);
381ccd2543fSMatthew G Knepley   }
382ccd2543fSMatthew G Knepley   ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, e, NULL, &coords);CHKERRQ(ierr);
383ccd2543fSMatthew G Knepley   PetscFunctionReturn(0);
384ccd2543fSMatthew G Knepley }
385ccd2543fSMatthew G Knepley 
386ccd2543fSMatthew G Knepley #undef __FUNCT__
387ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexComputeTetrahedronGeometry_Internal"
388ccd2543fSMatthew G Knepley static PetscErrorCode DMPlexComputeTetrahedronGeometry_Internal(DM dm, PetscInt e, PetscReal v0[], PetscReal J[], PetscReal invJ[], PetscReal *detJ)
389ccd2543fSMatthew G Knepley {
390ccd2543fSMatthew G Knepley   PetscSection   coordSection;
391ccd2543fSMatthew G Knepley   Vec            coordinates;
3927c1f9639SMatthew G Knepley   PetscScalar   *coords;
393ccd2543fSMatthew G Knepley   const PetscInt dim = 3;
394ccd2543fSMatthew G Knepley   PetscInt       d, f;
395ccd2543fSMatthew G Knepley   PetscErrorCode ierr;
396ccd2543fSMatthew G Knepley 
397ccd2543fSMatthew G Knepley   PetscFunctionBegin;
398ccd2543fSMatthew G Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
399ccd2543fSMatthew G Knepley   ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
400ccd2543fSMatthew G Knepley   ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, e, NULL, &coords);CHKERRQ(ierr);
401ccd2543fSMatthew G Knepley   if (v0) {
402ccd2543fSMatthew G Knepley     for (d = 0; d < dim; d++) v0[d] = PetscRealPart(coords[d]);
403ccd2543fSMatthew G Knepley   }
404ccd2543fSMatthew G Knepley   if (J) {
405ccd2543fSMatthew G Knepley     for (d = 0; d < dim; d++) {
406ccd2543fSMatthew G Knepley       for (f = 0; f < dim; f++) {
407ccd2543fSMatthew G Knepley         J[d*dim+f] = 0.5*(PetscRealPart(coords[(f+1)*dim+d]) - PetscRealPart(coords[0*dim+d]));
408ccd2543fSMatthew G Knepley       }
409ccd2543fSMatthew G Knepley     }
4102e1b13c2SMatthew G. Knepley     *detJ = (J[0*3+0]*(J[1*3+2]*J[2*3+1] - J[1*3+1]*J[2*3+2]) +
4112e1b13c2SMatthew G. Knepley              J[0*3+1]*(J[1*3+0]*J[2*3+2] - J[1*3+2]*J[2*3+0]) +
4122e1b13c2SMatthew G. Knepley              J[0*3+2]*(J[1*3+1]*J[2*3+0] - J[1*3+0]*J[2*3+1]));
413ccd2543fSMatthew G Knepley     PetscLogFlops(18.0 + 12.0);
414ccd2543fSMatthew G Knepley   }
415ccd2543fSMatthew G Knepley   if (invJ) {
416ccd2543fSMatthew G Knepley     const PetscReal invDet = 1.0/(*detJ);
417ccd2543fSMatthew G Knepley 
418ccd2543fSMatthew G Knepley     invJ[0*3+0] = invDet*(J[1*3+1]*J[2*3+2] - J[1*3+2]*J[2*3+1]);
419ccd2543fSMatthew G Knepley     invJ[0*3+1] = invDet*(J[0*3+2]*J[2*3+1] - J[0*3+1]*J[2*3+2]);
420ccd2543fSMatthew G Knepley     invJ[0*3+2] = invDet*(J[0*3+1]*J[1*3+2] - J[0*3+2]*J[1*3+1]);
421ccd2543fSMatthew G Knepley     invJ[1*3+0] = invDet*(J[1*3+2]*J[2*3+0] - J[1*3+0]*J[2*3+2]);
422ccd2543fSMatthew G Knepley     invJ[1*3+1] = invDet*(J[0*3+0]*J[2*3+2] - J[0*3+2]*J[2*3+0]);
423ccd2543fSMatthew G Knepley     invJ[1*3+2] = invDet*(J[0*3+2]*J[1*3+0] - J[0*3+0]*J[1*3+2]);
424ccd2543fSMatthew G Knepley     invJ[2*3+0] = invDet*(J[1*3+0]*J[2*3+1] - J[1*3+1]*J[2*3+0]);
425ccd2543fSMatthew G Knepley     invJ[2*3+1] = invDet*(J[0*3+1]*J[2*3+0] - J[0*3+0]*J[2*3+1]);
426ccd2543fSMatthew G Knepley     invJ[2*3+2] = invDet*(J[0*3+0]*J[1*3+1] - J[0*3+1]*J[1*3+0]);
427ccd2543fSMatthew G Knepley     PetscLogFlops(37.0);
428ccd2543fSMatthew G Knepley   }
429ccd2543fSMatthew G Knepley   ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, e, NULL, &coords);CHKERRQ(ierr);
430ccd2543fSMatthew G Knepley   PetscFunctionReturn(0);
431ccd2543fSMatthew G Knepley }
432ccd2543fSMatthew G Knepley 
433ccd2543fSMatthew G Knepley #undef __FUNCT__
434ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexComputeHexahedronGeometry_Internal"
435ccd2543fSMatthew G Knepley static PetscErrorCode DMPlexComputeHexahedronGeometry_Internal(DM dm, PetscInt e, PetscReal v0[], PetscReal J[], PetscReal invJ[], PetscReal *detJ)
436ccd2543fSMatthew G Knepley {
437ccd2543fSMatthew G Knepley   PetscSection   coordSection;
438ccd2543fSMatthew G Knepley   Vec            coordinates;
4397c1f9639SMatthew G Knepley   PetscScalar   *coords;
440ccd2543fSMatthew G Knepley   const PetscInt dim = 3;
441ccd2543fSMatthew G Knepley   PetscInt       d;
442ccd2543fSMatthew G Knepley   PetscErrorCode ierr;
443ccd2543fSMatthew G Knepley 
444ccd2543fSMatthew G Knepley   PetscFunctionBegin;
445ccd2543fSMatthew G Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
446ccd2543fSMatthew G Knepley   ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
447ccd2543fSMatthew G Knepley   ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, e, NULL, &coords);CHKERRQ(ierr);
448ccd2543fSMatthew G Knepley   if (v0) {
449ccd2543fSMatthew G Knepley     for (d = 0; d < dim; d++) v0[d] = PetscRealPart(coords[d]);
450ccd2543fSMatthew G Knepley   }
451ccd2543fSMatthew G Knepley   if (J) {
452ccd2543fSMatthew G Knepley     for (d = 0; d < dim; d++) {
453ccd2543fSMatthew G Knepley       J[d*dim+0] = 0.5*(PetscRealPart(coords[(0+1)*dim+d]) - PetscRealPart(coords[0*dim+d]));
454ccd2543fSMatthew G Knepley       J[d*dim+1] = 0.5*(PetscRealPart(coords[(1+1)*dim+d]) - PetscRealPart(coords[0*dim+d]));
455ccd2543fSMatthew G Knepley       J[d*dim+2] = 0.5*(PetscRealPart(coords[(3+1)*dim+d]) - PetscRealPart(coords[0*dim+d]));
456ccd2543fSMatthew G Knepley     }
4572e1b13c2SMatthew G. Knepley     *detJ = (J[0*3+0]*(J[1*3+2]*J[2*3+1] - J[1*3+1]*J[2*3+2]) +
4582e1b13c2SMatthew G. Knepley              J[0*3+1]*(J[1*3+0]*J[2*3+2] - J[1*3+2]*J[2*3+0]) +
4592e1b13c2SMatthew G. Knepley              J[0*3+2]*(J[1*3+1]*J[2*3+0] - J[1*3+0]*J[2*3+1]));
460ccd2543fSMatthew G Knepley     PetscLogFlops(18.0 + 12.0);
461923cbbb6SMatthew G. Knepley   } else {
462923cbbb6SMatthew G. Knepley     *detJ = 0.0;
463ccd2543fSMatthew G Knepley   }
464ccd2543fSMatthew G Knepley   if (invJ) {
465ccd2543fSMatthew G Knepley     const PetscReal invDet = -1.0/(*detJ);
466ccd2543fSMatthew G Knepley 
467ccd2543fSMatthew G Knepley     invJ[0*3+0] = invDet*(J[1*3+1]*J[2*3+2] - J[1*3+2]*J[2*3+1]);
468ccd2543fSMatthew G Knepley     invJ[0*3+1] = invDet*(J[0*3+2]*J[2*3+1] - J[0*3+1]*J[2*3+2]);
469ccd2543fSMatthew G Knepley     invJ[0*3+2] = invDet*(J[0*3+1]*J[1*3+2] - J[0*3+2]*J[1*3+1]);
470ccd2543fSMatthew G Knepley     invJ[1*3+0] = invDet*(J[1*3+2]*J[2*3+0] - J[1*3+0]*J[2*3+2]);
471ccd2543fSMatthew G Knepley     invJ[1*3+1] = invDet*(J[0*3+0]*J[2*3+2] - J[0*3+2]*J[2*3+0]);
472ccd2543fSMatthew G Knepley     invJ[1*3+2] = invDet*(J[0*3+2]*J[1*3+0] - J[0*3+0]*J[1*3+2]);
473ccd2543fSMatthew G Knepley     invJ[2*3+0] = invDet*(J[1*3+0]*J[2*3+1] - J[1*3+1]*J[2*3+0]);
474ccd2543fSMatthew G Knepley     invJ[2*3+1] = invDet*(J[0*3+1]*J[2*3+0] - J[0*3+0]*J[2*3+1]);
475ccd2543fSMatthew G Knepley     invJ[2*3+2] = invDet*(J[0*3+0]*J[1*3+1] - J[0*3+1]*J[1*3+0]);
476ccd2543fSMatthew G Knepley     PetscLogFlops(37.0);
477ccd2543fSMatthew G Knepley   }
478ccd2543fSMatthew G Knepley   *detJ *= 8.0;
479ccd2543fSMatthew G Knepley   ierr   = DMPlexVecRestoreClosure(dm, coordSection, coordinates, e, NULL, &coords);CHKERRQ(ierr);
480ccd2543fSMatthew G Knepley   PetscFunctionReturn(0);
481ccd2543fSMatthew G Knepley }
482ccd2543fSMatthew G Knepley 
483ccd2543fSMatthew G Knepley #undef __FUNCT__
484ccd2543fSMatthew G Knepley #define __FUNCT__ "DMPlexComputeCellGeometry"
485ccd2543fSMatthew G Knepley /*@C
486ccd2543fSMatthew G Knepley   DMPlexComputeCellGeometry - Compute the Jacobian, inverse Jacobian, and Jacobian determinant for a given cell
487ccd2543fSMatthew G Knepley 
488ccd2543fSMatthew G Knepley   Collective on DM
489ccd2543fSMatthew G Knepley 
490ccd2543fSMatthew G Knepley   Input Arguments:
491ccd2543fSMatthew G Knepley + dm   - the DM
492ccd2543fSMatthew G Knepley - cell - the cell
493ccd2543fSMatthew G Knepley 
494ccd2543fSMatthew G Knepley   Output Arguments:
495ccd2543fSMatthew G Knepley + v0   - the translation part of this affine transform
496ccd2543fSMatthew G Knepley . J    - the Jacobian of the transform from the reference element
497ccd2543fSMatthew G Knepley . invJ - the inverse of the Jacobian
498ccd2543fSMatthew G Knepley - detJ - the Jacobian determinant
499ccd2543fSMatthew G Knepley 
500ccd2543fSMatthew G Knepley   Level: advanced
501ccd2543fSMatthew G Knepley 
502ccd2543fSMatthew G Knepley   Fortran Notes:
503ccd2543fSMatthew G Knepley   Since it returns arrays, this routine is only available in Fortran 90, and you must
504ccd2543fSMatthew G Knepley   include petsc.h90 in your code.
505ccd2543fSMatthew G Knepley 
506ccd2543fSMatthew G Knepley .seealso: DMPlexGetCoordinateSection(), DMPlexGetCoordinateVec()
507ccd2543fSMatthew G Knepley @*/
508ccd2543fSMatthew G Knepley PetscErrorCode DMPlexComputeCellGeometry(DM dm, PetscInt cell, PetscReal *v0, PetscReal *J, PetscReal *invJ, PetscReal *detJ)
509ccd2543fSMatthew G Knepley {
51049dc4407SMatthew G. Knepley   PetscInt       depth, dim, coneSize;
511ccd2543fSMatthew G Knepley   PetscErrorCode ierr;
512ccd2543fSMatthew G Knepley 
513ccd2543fSMatthew G Knepley   PetscFunctionBegin;
514139a35ccSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
515ccd2543fSMatthew G Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
516ccd2543fSMatthew G Knepley   ierr = DMPlexGetConeSize(dm, cell, &coneSize);CHKERRQ(ierr);
51749dc4407SMatthew G. Knepley   if (depth == 1) {
518ccd2543fSMatthew G Knepley     switch (dim) {
519ccd2543fSMatthew G Knepley     case 2:
520ccd2543fSMatthew G Knepley       switch (coneSize) {
521ccd2543fSMatthew G Knepley       case 3:
522ccd2543fSMatthew G Knepley         ierr = DMPlexComputeTriangleGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr);
523ccd2543fSMatthew G Knepley         break;
524ccd2543fSMatthew G Knepley       case 4:
525ccd2543fSMatthew G Knepley         ierr = DMPlexComputeRectangleGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr);
526ccd2543fSMatthew G Knepley         break;
527ccd2543fSMatthew G Knepley       default:
528ccd2543fSMatthew G Knepley         SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupported number of vertices %D in cell %D for element geometry computation", coneSize, cell);
529ccd2543fSMatthew G Knepley       }
530ccd2543fSMatthew G Knepley       break;
531ccd2543fSMatthew G Knepley     case 3:
532ccd2543fSMatthew G Knepley       switch (coneSize) {
533ccd2543fSMatthew G Knepley       case 4:
534ccd2543fSMatthew G Knepley         ierr = DMPlexComputeTetrahedronGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr);
535ccd2543fSMatthew G Knepley         break;
536ccd2543fSMatthew G Knepley       case 8:
537ccd2543fSMatthew G Knepley         ierr = DMPlexComputeHexahedronGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr);
538ccd2543fSMatthew G Knepley         break;
539ccd2543fSMatthew G Knepley       default:
540ccd2543fSMatthew G Knepley         SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupported number of vertices %D in cell %D for element geometry computation", coneSize, cell);
541ccd2543fSMatthew G Knepley       }
542ccd2543fSMatthew G Knepley       break;
543ccd2543fSMatthew G Knepley     default:
544ccd2543fSMatthew G Knepley       SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupported dimension %D for element geometry computation", dim);
545ccd2543fSMatthew G Knepley     }
54649dc4407SMatthew G. Knepley   } else {
54749dc4407SMatthew G. Knepley     /* Cone size is now the number of faces */
54849dc4407SMatthew G. Knepley     switch (dim) {
54949dc4407SMatthew G. Knepley     case 2:
55049dc4407SMatthew G. Knepley       switch (coneSize) {
55149dc4407SMatthew G. Knepley       case 3:
55249dc4407SMatthew G. Knepley         ierr = DMPlexComputeTriangleGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr);
55349dc4407SMatthew G. Knepley         break;
55449dc4407SMatthew G. Knepley       case 4:
55549dc4407SMatthew G. Knepley         ierr = DMPlexComputeRectangleGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr);
55649dc4407SMatthew G. Knepley         break;
55749dc4407SMatthew G. Knepley       default:
55849dc4407SMatthew G. Knepley         SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupported number of vertices %D in cell %D for element geometry computation", coneSize, cell);
55949dc4407SMatthew G. Knepley       }
56049dc4407SMatthew G. Knepley       break;
56149dc4407SMatthew G. Knepley     case 3:
56249dc4407SMatthew G. Knepley       switch (coneSize) {
56349dc4407SMatthew G. Knepley       case 4:
56449dc4407SMatthew G. Knepley         ierr = DMPlexComputeTetrahedronGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr);
56549dc4407SMatthew G. Knepley         break;
56649dc4407SMatthew G. Knepley       case 6:
56749dc4407SMatthew G. Knepley         ierr = DMPlexComputeHexahedronGeometry_Internal(dm, cell, v0, J, invJ, detJ);CHKERRQ(ierr);
56849dc4407SMatthew G. Knepley         break;
56949dc4407SMatthew G. Knepley       default:
57049dc4407SMatthew G. Knepley         SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupported number of vertices %D in cell %D for element geometry computation", coneSize, cell);
57149dc4407SMatthew G. Knepley       }
57249dc4407SMatthew G. Knepley       break;
57349dc4407SMatthew G. Knepley     default:
57449dc4407SMatthew G. Knepley       SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unsupported dimension %D for element geometry computation", dim);
57549dc4407SMatthew G. Knepley     }
57649dc4407SMatthew G. Knepley   }
577ccd2543fSMatthew G Knepley   PetscFunctionReturn(0);
578ccd2543fSMatthew G Knepley }
579