120cf1dd8SToby Isaac #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/ 220cf1dd8SToby Isaac 32b99622eSMatthew G. Knepley /*@C 4dce8aebaSBarry Smith PetscFEGeomCreate - Create a `PetscFEGeom` object to manage geometry for a group of cells 52b99622eSMatthew G. Knepley 62b99622eSMatthew G. Knepley Input Parameters: 7dce8aebaSBarry Smith + quad - A `PetscQuadrature` determining the tabulation 82b99622eSMatthew G. Knepley . numCells - The number of cells in the group 92b99622eSMatthew G. Knepley . dimEmbed - The coordinate dimension 10*ac9d17c7SMatthew G. Knepley - mode - Type of geometry data to store 112b99622eSMatthew G. Knepley 122b99622eSMatthew G. Knepley Output Parameter: 13f13dfd9eSBarry Smith . geom - The `PetscFEGeom` object, which is a struct not a `PetscObject` 142b99622eSMatthew G. Knepley 152b99622eSMatthew G. Knepley Level: beginner 162b99622eSMatthew G. Knepley 1760225df5SJacob Faibussowitsch .seealso: `PetscFEGeom`, `PetscQuadrature`, `PetscFEGeomDestroy()`, `PetscFEGeomComplete()` 182b99622eSMatthew G. Knepley @*/ 19*ac9d17c7SMatthew G. Knepley PetscErrorCode PetscFEGeomCreate(PetscQuadrature quad, PetscInt numCells, PetscInt dimEmbed, PetscFEGeomMode mode, PetscFEGeom **geom) 20d71ae5a4SJacob Faibussowitsch { 2120cf1dd8SToby Isaac PetscFEGeom *g; 227489efa5SMatthew G. Knepley PetscInt dim, Nq, N; 2320cf1dd8SToby Isaac const PetscReal *p; 2420cf1dd8SToby Isaac 2520cf1dd8SToby Isaac PetscFunctionBegin; 269566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(quad, &dim, NULL, &Nq, &p, NULL)); 279566063dSJacob Faibussowitsch PetscCall(PetscNew(&g)); 28*ac9d17c7SMatthew G. Knepley g->mode = mode; 2920cf1dd8SToby Isaac g->xi = p; 3020cf1dd8SToby Isaac g->numCells = numCells; 317489efa5SMatthew G. Knepley g->numPoints = Nq; 3220cf1dd8SToby Isaac g->dim = dim; 3320cf1dd8SToby Isaac g->dimEmbed = dimEmbed; 347489efa5SMatthew G. Knepley N = numCells * Nq; 359566063dSJacob Faibussowitsch PetscCall(PetscCalloc3(N * dimEmbed, &g->v, N * dimEmbed * dimEmbed, &g->J, N, &g->detJ)); 36*ac9d17c7SMatthew G. Knepley if (mode == PETSC_FEGEOM_BOUNDARY || mode == PETSC_FEGEOM_COHESIVE) { 379566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(numCells, &g->face, N * dimEmbed, &g->n)); 38f4f49eeaSPierre Jolivet PetscCall(PetscCalloc6(N * dimEmbed * dimEmbed, &g->suppJ[0], N * dimEmbed * dimEmbed, &g->suppJ[1], N * dimEmbed * dimEmbed, &g->suppInvJ[0], N * dimEmbed * dimEmbed, &g->suppInvJ[1], N, &g->suppDetJ[0], N, &g->suppDetJ[1])); 3920cf1dd8SToby Isaac } 409566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(N * dimEmbed * dimEmbed, &g->invJ)); 4120cf1dd8SToby Isaac *geom = g; 423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4320cf1dd8SToby Isaac } 4420cf1dd8SToby Isaac 452b99622eSMatthew G. Knepley /*@C 46dce8aebaSBarry Smith PetscFEGeomDestroy - Destroy a `PetscFEGeom` object 472b99622eSMatthew G. Knepley 482b99622eSMatthew G. Knepley Input Parameter: 49dce8aebaSBarry Smith . geom - `PetscFEGeom` object 502b99622eSMatthew G. Knepley 512b99622eSMatthew G. Knepley Level: beginner 522b99622eSMatthew G. Knepley 53dce8aebaSBarry Smith .seealso: `PetscFEGeom`, `PetscFEGeomCreate()` 542b99622eSMatthew G. Knepley @*/ 55d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGeomDestroy(PetscFEGeom **geom) 56d71ae5a4SJacob Faibussowitsch { 5720cf1dd8SToby Isaac PetscFunctionBegin; 583ba16761SJacob Faibussowitsch if (!*geom) PetscFunctionReturn(PETSC_SUCCESS); 599566063dSJacob Faibussowitsch PetscCall(PetscFree3((*geom)->v, (*geom)->J, (*geom)->detJ)); 609566063dSJacob Faibussowitsch PetscCall(PetscFree((*geom)->invJ)); 619566063dSJacob Faibussowitsch PetscCall(PetscFree2((*geom)->face, (*geom)->n)); 629566063dSJacob Faibussowitsch PetscCall(PetscFree6((*geom)->suppJ[0], (*geom)->suppJ[1], (*geom)->suppInvJ[0], (*geom)->suppInvJ[1], (*geom)->suppDetJ[0], (*geom)->suppDetJ[1])); 639566063dSJacob Faibussowitsch PetscCall(PetscFree(*geom)); 643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6520cf1dd8SToby Isaac } 6620cf1dd8SToby Isaac 672b99622eSMatthew G. Knepley /*@C 68dce8aebaSBarry Smith PetscFEGeomGetChunk - Get a chunk of cells in the group as a `PetscFEGeom` 692b99622eSMatthew G. Knepley 702b99622eSMatthew G. Knepley Input Parameters: 71dce8aebaSBarry Smith + geom - `PetscFEGeom` object 722b99622eSMatthew G. Knepley . cStart - The first cell in the chunk 732b99622eSMatthew G. Knepley - cEnd - The first cell not in the chunk 742b99622eSMatthew G. Knepley 752b99622eSMatthew G. Knepley Output Parameter: 76f13dfd9eSBarry Smith . chunkGeom - an array of cells of length `cEnd` - `cStart` 772b99622eSMatthew G. Knepley 782b99622eSMatthew G. Knepley Level: intermediate 792b99622eSMatthew G. Knepley 80dce8aebaSBarry Smith Note: 81dce8aebaSBarry Smith Use `PetscFEGeomRestoreChunk()` to return the result 82dce8aebaSBarry Smith 83dce8aebaSBarry Smith .seealso: `PetscFEGeom`, `PetscFEGeomRestoreChunk()`, `PetscFEGeomCreate()` 842b99622eSMatthew G. Knepley @*/ 85f13dfd9eSBarry Smith PetscErrorCode PetscFEGeomGetChunk(PetscFEGeom *geom, PetscInt cStart, PetscInt cEnd, PetscFEGeom *chunkGeom[]) 86d71ae5a4SJacob Faibussowitsch { 8720cf1dd8SToby Isaac PetscInt Nq; 8820cf1dd8SToby Isaac PetscInt dE; 8920cf1dd8SToby Isaac 9020cf1dd8SToby Isaac PetscFunctionBegin; 914f572ea9SToby Isaac PetscAssertPointer(geom, 1); 924f572ea9SToby Isaac PetscAssertPointer(chunkGeom, 4); 934ad8454bSPierre Jolivet if (!*chunkGeom) PetscCall(PetscNew(chunkGeom)); 9420cf1dd8SToby Isaac Nq = geom->numPoints; 9520cf1dd8SToby Isaac dE = geom->dimEmbed; 96*ac9d17c7SMatthew G. Knepley (*chunkGeom)->mode = geom->mode; 9720cf1dd8SToby Isaac (*chunkGeom)->dim = geom->dim; 9820cf1dd8SToby Isaac (*chunkGeom)->dimEmbed = geom->dimEmbed; 9920cf1dd8SToby Isaac (*chunkGeom)->numPoints = geom->numPoints; 10020cf1dd8SToby Isaac (*chunkGeom)->numCells = cEnd - cStart; 10120cf1dd8SToby Isaac (*chunkGeom)->xi = geom->xi; 1028e3a54c0SPierre Jolivet (*chunkGeom)->v = PetscSafePointerPlusOffset(geom->v, Nq * dE * cStart); 1038e3a54c0SPierre Jolivet (*chunkGeom)->J = PetscSafePointerPlusOffset(geom->J, Nq * dE * dE * cStart); 1048e3a54c0SPierre Jolivet (*chunkGeom)->invJ = PetscSafePointerPlusOffset(geom->invJ, Nq * dE * dE * cStart); 1058e3a54c0SPierre Jolivet (*chunkGeom)->detJ = PetscSafePointerPlusOffset(geom->detJ, Nq * cStart); 1068e3a54c0SPierre Jolivet (*chunkGeom)->n = PetscSafePointerPlusOffset(geom->n, Nq * dE * cStart); 1078e3a54c0SPierre Jolivet (*chunkGeom)->face = PetscSafePointerPlusOffset(geom->face, cStart); 1088e3a54c0SPierre Jolivet (*chunkGeom)->suppJ[0] = PetscSafePointerPlusOffset(geom->suppJ[0], Nq * dE * dE * cStart); 1098e3a54c0SPierre Jolivet (*chunkGeom)->suppJ[1] = PetscSafePointerPlusOffset(geom->suppJ[1], Nq * dE * dE * cStart); 1108e3a54c0SPierre Jolivet (*chunkGeom)->suppInvJ[0] = PetscSafePointerPlusOffset(geom->suppInvJ[0], Nq * dE * dE * cStart); 1118e3a54c0SPierre Jolivet (*chunkGeom)->suppInvJ[1] = PetscSafePointerPlusOffset(geom->suppInvJ[1], Nq * dE * dE * cStart); 1128e3a54c0SPierre Jolivet (*chunkGeom)->suppDetJ[0] = PetscSafePointerPlusOffset(geom->suppDetJ[0], Nq * cStart); 1138e3a54c0SPierre Jolivet (*chunkGeom)->suppDetJ[1] = PetscSafePointerPlusOffset(geom->suppDetJ[1], Nq * cStart); 11420cf1dd8SToby Isaac (*chunkGeom)->isAffine = geom->isAffine; 1153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11620cf1dd8SToby Isaac } 11720cf1dd8SToby Isaac 1182b99622eSMatthew G. Knepley /*@C 119dce8aebaSBarry Smith PetscFEGeomRestoreChunk - Restore the chunk obtained with `PetscFEGeomCreateChunk()` 1202b99622eSMatthew G. Knepley 1212b99622eSMatthew G. Knepley Input Parameters: 122dce8aebaSBarry Smith + geom - `PetscFEGeom` object 1232b99622eSMatthew G. Knepley . cStart - The first cell in the chunk 1242b99622eSMatthew G. Knepley . cEnd - The first cell not in the chunk 1252b99622eSMatthew G. Knepley - chunkGeom - The chunk of cells 1262b99622eSMatthew G. Knepley 1272b99622eSMatthew G. Knepley Level: intermediate 1282b99622eSMatthew G. Knepley 129dce8aebaSBarry Smith .seealso: `PetscFEGeom`, `PetscFEGeomGetChunk()`, `PetscFEGeomCreate()` 1302b99622eSMatthew G. Knepley @*/ 131d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGeomRestoreChunk(PetscFEGeom *geom, PetscInt cStart, PetscInt cEnd, PetscFEGeom **chunkGeom) 132d71ae5a4SJacob Faibussowitsch { 13320cf1dd8SToby Isaac PetscFunctionBegin; 1349566063dSJacob Faibussowitsch PetscCall(PetscFree(*chunkGeom)); 1353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13620cf1dd8SToby Isaac } 13720cf1dd8SToby Isaac 1386587ee25SMatthew G. Knepley /*@C 139f13dfd9eSBarry Smith PetscFEGeomGetPoint - Get the geometry for cell `c` at point `p` as a `PetscFEGeom` 1406587ee25SMatthew G. Knepley 1416587ee25SMatthew G. Knepley Input Parameters: 142dce8aebaSBarry Smith + geom - `PetscFEGeom` object 1436587ee25SMatthew G. Knepley . c - The cell 1446587ee25SMatthew G. Knepley . p - The point 145f13dfd9eSBarry Smith - pcoords - The reference coordinates of point `p`, or `NULL` 1466587ee25SMatthew G. Knepley 1476587ee25SMatthew G. Knepley Output Parameter: 148f13dfd9eSBarry Smith . pgeom - The geometry of cell `c` at point `p` 1496587ee25SMatthew G. Knepley 150dce8aebaSBarry Smith Level: intermediate 151dce8aebaSBarry Smith 152dce8aebaSBarry Smith Notes: 153f13dfd9eSBarry Smith For affine geometries, this only copies to `pgeom` at point 0. Since we copy pointers into `pgeom`, 1546587ee25SMatthew G. Knepley nothing needs to be done with it afterwards. 1556587ee25SMatthew G. Knepley 156f13dfd9eSBarry Smith In the affine case, `pgeom` must have storage for the integration point coordinates in pgeom->v if `pcoords` is passed in. 1576587ee25SMatthew G. Knepley 158dce8aebaSBarry Smith .seealso: `PetscFEGeom`, `PetscFEGeomRestoreChunk()`, `PetscFEGeomCreate()` 1596587ee25SMatthew G. Knepley @*/ 160d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGeomGetPoint(PetscFEGeom *geom, PetscInt c, PetscInt p, const PetscReal pcoords[], PetscFEGeom *pgeom) 161d71ae5a4SJacob Faibussowitsch { 1626587ee25SMatthew G. Knepley const PetscInt dim = geom->dim; 1636587ee25SMatthew G. Knepley const PetscInt dE = geom->dimEmbed; 1646587ee25SMatthew G. Knepley const PetscInt Np = geom->numPoints; 1656587ee25SMatthew G. Knepley 1666587ee25SMatthew G. Knepley PetscFunctionBeginHot; 167*ac9d17c7SMatthew G. Knepley pgeom->mode = geom->mode; 1686587ee25SMatthew G. Knepley pgeom->dim = dim; 1696587ee25SMatthew G. Knepley pgeom->dimEmbed = dE; 1706587ee25SMatthew G. Knepley //pgeom->isAffine = geom->isAffine; 1716587ee25SMatthew G. Knepley if (geom->isAffine) { 1726587ee25SMatthew G. Knepley if (!p) { 1736587ee25SMatthew G. Knepley pgeom->xi = geom->xi; 1746587ee25SMatthew G. Knepley pgeom->J = &geom->J[c * Np * dE * dE]; 1756587ee25SMatthew G. Knepley pgeom->invJ = &geom->invJ[c * Np * dE * dE]; 1766587ee25SMatthew G. Knepley pgeom->detJ = &geom->detJ[c * Np]; 1778e3a54c0SPierre Jolivet pgeom->n = PetscSafePointerPlusOffset(geom->n, c * Np * dE); 1786587ee25SMatthew G. Knepley } 179ad540459SPierre Jolivet if (pcoords) CoordinatesRefToReal(dE, dim, pgeom->xi, &geom->v[c * Np * dE], pgeom->J, pcoords, pgeom->v); 1806587ee25SMatthew G. Knepley } else { 1816587ee25SMatthew G. Knepley pgeom->v = &geom->v[(c * Np + p) * dE]; 1826587ee25SMatthew G. Knepley pgeom->J = &geom->J[(c * Np + p) * dE * dE]; 1836587ee25SMatthew G. Knepley pgeom->invJ = &geom->invJ[(c * Np + p) * dE * dE]; 1846587ee25SMatthew G. Knepley pgeom->detJ = &geom->detJ[c * Np + p]; 1858e3a54c0SPierre Jolivet pgeom->n = PetscSafePointerPlusOffset(geom->n, (c * Np + p) * dE); 1866587ee25SMatthew G. Knepley } 1873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1886587ee25SMatthew G. Knepley } 1896587ee25SMatthew G. Knepley 1906587ee25SMatthew G. Knepley /*@C 191*ac9d17c7SMatthew G. Knepley PetscFEGeomGetCellPoint - Get the cell geometry for cell `c` at point `p` as a `PetscFEGeom` 1926587ee25SMatthew G. Knepley 1936587ee25SMatthew G. Knepley Input Parameters: 194dce8aebaSBarry Smith + geom - `PetscFEGeom` object 195*ac9d17c7SMatthew G. Knepley . c - The cell 1966587ee25SMatthew G. Knepley - p - The point 1976587ee25SMatthew G. Knepley 1986587ee25SMatthew G. Knepley Output Parameter: 199*ac9d17c7SMatthew G. Knepley . pgeom - The cell geometry of cell `c` at point `p` 2006587ee25SMatthew G. Knepley 2016587ee25SMatthew G. Knepley Level: intermediate 2026587ee25SMatthew G. Knepley 203*ac9d17c7SMatthew G. Knepley Notes: 204*ac9d17c7SMatthew G. Knepley For PETSC_FEGEOM_BOUNDARY mode, this gives the geometry for supporting cell 0. For PETSC_FEGEOM_COHESIVE mode, 205*ac9d17c7SMatthew G. Knepley this gives the bulk geometry for that internal face. 206*ac9d17c7SMatthew G. Knepley 207f13dfd9eSBarry Smith For affine geometries, this only copies to pgeom at point 0. Since we copy pointers into `pgeom`, 208dce8aebaSBarry Smith nothing needs to be done with it afterwards. 209dce8aebaSBarry Smith 210*ac9d17c7SMatthew G. Knepley .seealso: `PetscFEGeom`, `PetscFEGeomMode`, `PetscFEGeomRestoreChunk()`, `PetscFEGeomCreate()` 2116587ee25SMatthew G. Knepley @*/ 212d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGeomGetCellPoint(PetscFEGeom *geom, PetscInt c, PetscInt p, PetscFEGeom *pgeom) 213d71ae5a4SJacob Faibussowitsch { 214*ac9d17c7SMatthew G. Knepley const PetscBool bd = geom->mode == PETSC_FEGEOM_BOUNDARY ? PETSC_TRUE : PETSC_FALSE; 2156587ee25SMatthew G. Knepley const PetscInt dim = bd ? geom->dimEmbed : geom->dim; 2166587ee25SMatthew G. Knepley const PetscInt dE = geom->dimEmbed; 2176587ee25SMatthew G. Knepley const PetscInt Np = geom->numPoints; 2186587ee25SMatthew G. Knepley 2196587ee25SMatthew G. Knepley PetscFunctionBeginHot; 220*ac9d17c7SMatthew G. Knepley pgeom->mode = geom->mode; 2216587ee25SMatthew G. Knepley pgeom->dim = dim; 2226587ee25SMatthew G. Knepley pgeom->dimEmbed = dE; 2236587ee25SMatthew G. Knepley //pgeom->isAffine = geom->isAffine; 2246587ee25SMatthew G. Knepley if (geom->isAffine) { 2256587ee25SMatthew G. Knepley if (!p) { 2266587ee25SMatthew G. Knepley if (bd) { 2276587ee25SMatthew G. Knepley pgeom->J = &geom->suppJ[0][c * Np * dE * dE]; 2286587ee25SMatthew G. Knepley pgeom->invJ = &geom->suppInvJ[0][c * Np * dE * dE]; 2296587ee25SMatthew G. Knepley pgeom->detJ = &geom->suppDetJ[0][c * Np]; 2306587ee25SMatthew G. Knepley } else { 2316587ee25SMatthew G. Knepley pgeom->J = &geom->J[c * Np * dE * dE]; 2326587ee25SMatthew G. Knepley pgeom->invJ = &geom->invJ[c * Np * dE * dE]; 2336587ee25SMatthew G. Knepley pgeom->detJ = &geom->detJ[c * Np]; 2346587ee25SMatthew G. Knepley } 2356587ee25SMatthew G. Knepley } 2366587ee25SMatthew G. Knepley } else { 2376587ee25SMatthew G. Knepley if (bd) { 2386587ee25SMatthew G. Knepley pgeom->J = &geom->suppJ[0][(c * Np + p) * dE * dE]; 2396587ee25SMatthew G. Knepley pgeom->invJ = &geom->suppInvJ[0][(c * Np + p) * dE * dE]; 2406587ee25SMatthew G. Knepley pgeom->detJ = &geom->suppDetJ[0][c * Np + p]; 2416587ee25SMatthew G. Knepley } else { 2426587ee25SMatthew G. Knepley pgeom->J = &geom->J[(c * Np + p) * dE * dE]; 2436587ee25SMatthew G. Knepley pgeom->invJ = &geom->invJ[(c * Np + p) * dE * dE]; 2446587ee25SMatthew G. Knepley pgeom->detJ = &geom->detJ[c * Np + p]; 2456587ee25SMatthew G. Knepley } 2466587ee25SMatthew G. Knepley } 2473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2486587ee25SMatthew G. Knepley } 2496587ee25SMatthew G. Knepley 2508e1e1cc9SMatthew G. Knepley /*@C 251f13dfd9eSBarry Smith PetscFEGeomComplete - Calculate derived quantities from a base geometry specification 2522b99622eSMatthew G. Knepley 2532b99622eSMatthew G. Knepley Input Parameter: 254dce8aebaSBarry Smith . geom - `PetscFEGeom` object 2552b99622eSMatthew G. Knepley 2562b99622eSMatthew G. Knepley Level: intermediate 2572b99622eSMatthew G. Knepley 258dce8aebaSBarry Smith .seealso: `PetscFEGeom`, `PetscFEGeomCreate()` 2592b99622eSMatthew G. Knepley @*/ 260d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGeomComplete(PetscFEGeom *geom) 261d71ae5a4SJacob Faibussowitsch { 26220cf1dd8SToby Isaac PetscInt i, j, N, dE; 26320cf1dd8SToby Isaac 26420cf1dd8SToby Isaac PetscFunctionBeginHot; 26520cf1dd8SToby Isaac N = geom->numPoints * geom->numCells; 26620cf1dd8SToby Isaac dE = geom->dimEmbed; 26720cf1dd8SToby Isaac switch (dE) { 26820cf1dd8SToby Isaac case 3: 26920cf1dd8SToby Isaac for (i = 0; i < N; i++) { 27020cf1dd8SToby Isaac DMPlex_Det3D_Internal(&geom->detJ[i], &geom->J[dE * dE * i]); 27120cf1dd8SToby Isaac if (geom->invJ) DMPlex_Invert3D_Internal(&geom->invJ[dE * dE * i], &geom->J[dE * dE * i], geom->detJ[i]); 27220cf1dd8SToby Isaac } 27320cf1dd8SToby Isaac break; 27420cf1dd8SToby Isaac case 2: 27520cf1dd8SToby Isaac for (i = 0; i < N; i++) { 27620cf1dd8SToby Isaac DMPlex_Det2D_Internal(&geom->detJ[i], &geom->J[dE * dE * i]); 27720cf1dd8SToby Isaac if (geom->invJ) DMPlex_Invert2D_Internal(&geom->invJ[dE * dE * i], &geom->J[dE * dE * i], geom->detJ[i]); 27820cf1dd8SToby Isaac } 27920cf1dd8SToby Isaac break; 28020cf1dd8SToby Isaac case 1: 28120cf1dd8SToby Isaac for (i = 0; i < N; i++) { 28220cf1dd8SToby Isaac geom->detJ[i] = PetscAbsReal(geom->J[i]); 28320cf1dd8SToby Isaac if (geom->invJ) geom->invJ[i] = 1. / geom->J[i]; 28420cf1dd8SToby Isaac } 28520cf1dd8SToby Isaac break; 28620cf1dd8SToby Isaac } 28720cf1dd8SToby Isaac if (geom->n) { 28820cf1dd8SToby Isaac for (i = 0; i < N; i++) { 289ad540459SPierre Jolivet for (j = 0; j < dE; j++) geom->n[dE * i + j] = geom->J[dE * dE * i + dE * j + dE - 1] * ((dE == 2) ? -1. : 1.); 29020cf1dd8SToby Isaac } 29120cf1dd8SToby Isaac } 2923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29320cf1dd8SToby Isaac } 294