1*5aed82e4SJeremy L Thompson // Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and other CEED contributors. 28756a6ccSJames Wright // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 38756a6ccSJames Wright // 48756a6ccSJames Wright // SPDX-License-Identifier: BSD-2-Clause 58756a6ccSJames Wright // 68756a6ccSJames Wright // This file is part of CEED: http://github.com/ceed 78756a6ccSJames Wright 88756a6ccSJames Wright /// @file 98756a6ccSJames Wright /// Geometric factors (3D) for Navier-Stokes example using PETSc 108756a6ccSJames Wright 118756a6ccSJames Wright #ifndef setupgeo_helpers_h 128756a6ccSJames Wright #define setupgeo_helpers_h 138756a6ccSJames Wright 148756a6ccSJames Wright #include <ceed.h> 158756a6ccSJames Wright #include <math.h> 168756a6ccSJames Wright 178756a6ccSJames Wright #include "utils.h" 188756a6ccSJames Wright 198756a6ccSJames Wright /** 208756a6ccSJames Wright * @brief Calculate dXdx from dxdX for 3D elements 218756a6ccSJames Wright * 228756a6ccSJames Wright * Reference (parent) coordinates: X 238756a6ccSJames Wright * Physical (current) coordinates: x 248756a6ccSJames Wright * Change of coordinate matrix: dxdX_{i,j} = x_{i,j} (indicial notation) 258756a6ccSJames Wright * Inverse of change of coordinate matrix: dXdx_{i,j} = (detJ^-1) * X_{i,j} 268756a6ccSJames Wright * 278756a6ccSJames Wright * Determinant of Jacobian: 288756a6ccSJames Wright * detJ = J11*A11 + J21*A12 + J31*A13 298756a6ccSJames Wright * Jij = Jacobian entry ij 308756a6ccSJames Wright * Aij = Adjugate ij 318756a6ccSJames Wright * 328756a6ccSJames Wright * Inverse of Jacobian: 338756a6ccSJames Wright * dXdx_i,j = Aij / detJ 348756a6ccSJames Wright * 358756a6ccSJames Wright * @param[in] Q Number of quadrature points 368756a6ccSJames Wright * @param[in] i Current quadrature point 378756a6ccSJames Wright * @param[in] dxdX_q Mapping Jacobian (gradient of the coordinate space) 388756a6ccSJames Wright * @param[out] dXdx Inverse of mapping Jacobian at quadrature point i 398756a6ccSJames Wright * @param[out] detJ_ptr Determinate of the Jacobian, may be NULL is not desired 408756a6ccSJames Wright */ 418756a6ccSJames Wright CEED_QFUNCTION_HELPER void InvertMappingJacobian_3D(CeedInt Q, CeedInt i, const CeedScalar (*dxdX_q)[3][CEED_Q_VLA], CeedScalar dXdx[3][3], 428756a6ccSJames Wright CeedScalar *detJ_ptr) { 438756a6ccSJames Wright const CeedScalar dxdX_11 = dxdX_q[0][0][i]; 448756a6ccSJames Wright const CeedScalar dxdX_21 = dxdX_q[0][1][i]; 458756a6ccSJames Wright const CeedScalar dxdX_31 = dxdX_q[0][2][i]; 468756a6ccSJames Wright const CeedScalar dxdX_12 = dxdX_q[1][0][i]; 478756a6ccSJames Wright const CeedScalar dxdX_22 = dxdX_q[1][1][i]; 488756a6ccSJames Wright const CeedScalar dxdX_32 = dxdX_q[1][2][i]; 498756a6ccSJames Wright const CeedScalar dxdX_13 = dxdX_q[2][0][i]; 508756a6ccSJames Wright const CeedScalar dxdX_23 = dxdX_q[2][1][i]; 518756a6ccSJames Wright const CeedScalar dxdX_33 = dxdX_q[2][2][i]; 528756a6ccSJames Wright const CeedScalar A11 = dxdX_22 * dxdX_33 - dxdX_23 * dxdX_32; 538756a6ccSJames Wright const CeedScalar A12 = dxdX_13 * dxdX_32 - dxdX_12 * dxdX_33; 548756a6ccSJames Wright const CeedScalar A13 = dxdX_12 * dxdX_23 - dxdX_13 * dxdX_22; 558756a6ccSJames Wright const CeedScalar A21 = dxdX_23 * dxdX_31 - dxdX_21 * dxdX_33; 568756a6ccSJames Wright const CeedScalar A22 = dxdX_11 * dxdX_33 - dxdX_13 * dxdX_31; 578756a6ccSJames Wright const CeedScalar A23 = dxdX_13 * dxdX_21 - dxdX_11 * dxdX_23; 588756a6ccSJames Wright const CeedScalar A31 = dxdX_21 * dxdX_32 - dxdX_22 * dxdX_31; 598756a6ccSJames Wright const CeedScalar A32 = dxdX_12 * dxdX_31 - dxdX_11 * dxdX_32; 608756a6ccSJames Wright const CeedScalar A33 = dxdX_11 * dxdX_22 - dxdX_12 * dxdX_21; 618756a6ccSJames Wright const CeedScalar detJ = dxdX_11 * A11 + dxdX_21 * A12 + dxdX_31 * A13; 628756a6ccSJames Wright 638756a6ccSJames Wright dXdx[0][0] = A11 / detJ; 648756a6ccSJames Wright dXdx[0][1] = A12 / detJ; 658756a6ccSJames Wright dXdx[0][2] = A13 / detJ; 668756a6ccSJames Wright dXdx[1][0] = A21 / detJ; 678756a6ccSJames Wright dXdx[1][1] = A22 / detJ; 688756a6ccSJames Wright dXdx[1][2] = A23 / detJ; 698756a6ccSJames Wright dXdx[2][0] = A31 / detJ; 708756a6ccSJames Wright dXdx[2][1] = A32 / detJ; 718756a6ccSJames Wright dXdx[2][2] = A33 / detJ; 728756a6ccSJames Wright if (detJ_ptr) *detJ_ptr = detJ; 738756a6ccSJames Wright } 748756a6ccSJames Wright 758756a6ccSJames Wright /** 76bf415d3fSJames Wright * @brief Calculate dXdx from dxdX for 3D elements 77bf415d3fSJames Wright * 78bf415d3fSJames Wright * Reference (parent) coordinates: X 79bf415d3fSJames Wright * Physical (current) coordinates: x 80bf415d3fSJames Wright * Change of coordinate matrix: dxdX_{i,j} = x_{i,j} (indicial notation) 81bf415d3fSJames Wright * Inverse of change of coordinate matrix: dXdx_{i,j} = (detJ^-1) * X_{i,j} 82bf415d3fSJames Wright * 83bf415d3fSJames Wright * Determinant of Jacobian: 84bf415d3fSJames Wright * detJ = J11*A11 + J21*A12 + J31*A13 85bf415d3fSJames Wright * Jij = Jacobian entry ij 86bf415d3fSJames Wright * Aij = Adjugate ij 87bf415d3fSJames Wright * 88bf415d3fSJames Wright * Inverse of Jacobian: 89bf415d3fSJames Wright * dXdx_i,j = Aij / detJ 90bf415d3fSJames Wright * 91bf415d3fSJames Wright * @param[in] Q Number of quadrature points 92bf415d3fSJames Wright * @param[in] i Current quadrature point 93bf415d3fSJames Wright * @param[in] dxdX_q Mapping Jacobian (gradient of the coordinate space) 94bf415d3fSJames Wright * @param[out] dXdx Inverse of mapping Jacobian at quadrature point i 95bf415d3fSJames Wright * @param[out] detJ_ptr Determinate of the Jacobian, may be NULL is not desired 96bf415d3fSJames Wright */ 97bf415d3fSJames Wright CEED_QFUNCTION_HELPER void InvertMappingJacobian_2D(CeedInt Q, CeedInt i, const CeedScalar (*dxdX_q)[2][CEED_Q_VLA], CeedScalar dXdx[2][2], 98bf415d3fSJames Wright CeedScalar *detJ_ptr) { 99bf415d3fSJames Wright const CeedScalar dxdX_11 = dxdX_q[0][0][i]; 100bf415d3fSJames Wright const CeedScalar dxdX_21 = dxdX_q[0][1][i]; 101bf415d3fSJames Wright const CeedScalar dxdX_12 = dxdX_q[1][0][i]; 102bf415d3fSJames Wright const CeedScalar dxdX_22 = dxdX_q[1][1][i]; 103bf415d3fSJames Wright const CeedScalar detJ = dxdX_11 * dxdX_22 - dxdX_21 * dxdX_12; 104bf415d3fSJames Wright 105bf415d3fSJames Wright dXdx[0][0] = dxdX_22 / detJ; 106bf415d3fSJames Wright dXdx[0][1] = -dxdX_12 / detJ; 107bf415d3fSJames Wright dXdx[1][0] = -dxdX_21 / detJ; 108bf415d3fSJames Wright dXdx[1][1] = dxdX_11 / detJ; 109bf415d3fSJames Wright if (detJ_ptr) *detJ_ptr = detJ; 110bf415d3fSJames Wright } 111bf415d3fSJames Wright 112bf415d3fSJames Wright /** 1138756a6ccSJames Wright * @brief Calculate face element's normal vector from dxdX 1148756a6ccSJames Wright * 1158756a6ccSJames Wright * Reference (parent) 2D coordinates: X 1168756a6ccSJames Wright * Physical (current) 3D coordinates: x 1178756a6ccSJames Wright * Change of coordinate matrix: 1188756a6ccSJames Wright * dxdX_{i,j} = dx_i/dX_j (indicial notation) [3 * 2] 1198756a6ccSJames Wright * Inverse change of coordinate matrix: 1208756a6ccSJames Wright * dXdx_{i,j} = dX_i/dx_j (indicial notation) [2 * 3] 1218756a6ccSJames Wright * 1228756a6ccSJames Wright * (J1,J2,J3) is given by the cross product of the columns of dxdX_{i,j} 1238756a6ccSJames Wright * 1248756a6ccSJames Wright * detJb is the magnitude of (J1,J2,J3) 1258756a6ccSJames Wright * 1268756a6ccSJames Wright * Normal vector = (J1,J2,J3) / detJb 1278756a6ccSJames Wright * 1288756a6ccSJames Wright * @param[in] Q Number of quadrature points 1298756a6ccSJames Wright * @param[in] i Current quadrature point 1308756a6ccSJames Wright * @param[in] dxdX_q Mapping Jacobian (gradient of the coordinate space) 1318756a6ccSJames Wright * @param[out] normal Inverse of mapping Jacobian at quadrature point i 1328756a6ccSJames Wright * @param[out] detJ_ptr Determinate of the Jacobian, may be NULL is not desired 1338756a6ccSJames Wright */ 13409b5d125SJames Wright CEED_QFUNCTION_HELPER void NormalVectorFromdxdX_3D(CeedInt Q, CeedInt i, const CeedScalar (*dxdX_q)[3][CEED_Q_VLA], CeedScalar normal[3], 1358756a6ccSJames Wright CeedScalar *detJ_ptr) { 1368756a6ccSJames Wright const CeedScalar dxdX[3][2] = { 1378756a6ccSJames Wright {dxdX_q[0][0][i], dxdX_q[1][0][i]}, 1388756a6ccSJames Wright {dxdX_q[0][1][i], dxdX_q[1][1][i]}, 1398756a6ccSJames Wright {dxdX_q[0][2][i], dxdX_q[1][2][i]} 1408756a6ccSJames Wright }; 1418756a6ccSJames Wright // J1, J2, and J3 are given by the cross product of the columns of dxdX 1428756a6ccSJames Wright const CeedScalar J1 = dxdX[1][0] * dxdX[2][1] - dxdX[2][0] * dxdX[1][1]; 1438756a6ccSJames Wright const CeedScalar J2 = dxdX[2][0] * dxdX[0][1] - dxdX[0][0] * dxdX[2][1]; 1448756a6ccSJames Wright const CeedScalar J3 = dxdX[0][0] * dxdX[1][1] - dxdX[1][0] * dxdX[0][1]; 1458756a6ccSJames Wright 1468756a6ccSJames Wright const CeedScalar detJ = sqrt(J1 * J1 + J2 * J2 + J3 * J3); 1478756a6ccSJames Wright 1488756a6ccSJames Wright normal[0] = J1 / detJ; 1498756a6ccSJames Wright normal[1] = J2 / detJ; 1508756a6ccSJames Wright normal[2] = J3 / detJ; 1518756a6ccSJames Wright if (detJ_ptr) *detJ_ptr = detJ; 1528756a6ccSJames Wright } 1538756a6ccSJames Wright 1548756a6ccSJames Wright /** 1551394d07eSJames Wright * This QFunction sets up the geometric factor required for integration when reference coordinates are in 1D and the physical coordinates are in 2D 1561394d07eSJames Wright * 1571394d07eSJames Wright * Reference (parent) 1D coordinates: X 1581394d07eSJames Wright * Physical (current) 2D coordinates: x 1591394d07eSJames Wright * Change of coordinate vector: 1601394d07eSJames Wright * J1 = dx_1/dX 1611394d07eSJames Wright * J2 = dx_2/dX 1621394d07eSJames Wright * 1631394d07eSJames Wright * detJb is the magnitude of (J1,J2) 1641394d07eSJames Wright * 1651394d07eSJames Wright * We require the determinant of the Jacobian to properly compute integrals of the form: int( u v ) 1661394d07eSJames Wright * 1671394d07eSJames Wright * Normal vector is given by the cross product of (J1,J2)/detJ and ẑ 1681394d07eSJames Wright * 1691394d07eSJames Wright * @param[in] Q Number of quadrature points 1701394d07eSJames Wright * @param[in] i Current quadrature point 1711394d07eSJames Wright * @param[in] dxdX_q Mapping Jacobian (gradient of the coordinate space) 1721394d07eSJames Wright * @param[out] normal Inverse of mapping Jacobian at quadrature point i 1731394d07eSJames Wright * @param[out] detJ_ptr Determinate of the Jacobian, may be NULL is not desired 1741394d07eSJames Wright */ 1751394d07eSJames Wright CEED_QFUNCTION_HELPER void NormalVectorFromdxdX_2D(CeedInt Q, CeedInt i, const CeedScalar (*dxdX_q)[CEED_Q_VLA], CeedScalar normal[2], 1761394d07eSJames Wright CeedScalar *detJ_ptr) { 1771394d07eSJames Wright const CeedScalar J1 = dxdX_q[0][i]; 1781394d07eSJames Wright const CeedScalar J2 = dxdX_q[1][i]; 1791394d07eSJames Wright 1801394d07eSJames Wright CeedScalar detJb = sqrt(J1 * J1 + J2 * J2); 1811394d07eSJames Wright normal[0] = J2 / detJb; 1821394d07eSJames Wright normal[1] = -J1 / detJb; 1831394d07eSJames Wright if (detJ_ptr) *detJ_ptr = detJb; 1841394d07eSJames Wright } 1851394d07eSJames Wright 1861394d07eSJames Wright /** 1878756a6ccSJames Wright * @brief Calculate inverse of mapping Jacobian, (dxdX)^-1 1888756a6ccSJames Wright * 1898756a6ccSJames Wright * Reference (parent) 2D coordinates: X 1908756a6ccSJames Wright * Physical (current) 3D coordinates: x 1918756a6ccSJames Wright * Change of coordinate matrix: 1928756a6ccSJames Wright * dxdX_{i,j} = dx_i/dX_j (indicial notation) [3 * 2] 1938756a6ccSJames Wright * Inverse change of coordinate matrix: 1948756a6ccSJames Wright * dXdx_{i,j} = dX_i/dx_j (indicial notation) [2 * 3] 1958756a6ccSJames Wright * 1968756a6ccSJames Wright * dXdx is calculated via Moore–Penrose inverse: 1978756a6ccSJames Wright * 1988756a6ccSJames Wright * dX_i/dx_j = (dxdX^T dxdX)^(-1) dxdX 1998756a6ccSJames Wright * = (dx_l/dX_i * dx_l/dX_k)^(-1) dx_j/dX_k 2008756a6ccSJames Wright * 2018756a6ccSJames Wright * @param[in] Q Number of quadrature points 2028756a6ccSJames Wright * @param[in] i Current quadrature point 2038756a6ccSJames Wright * @param[in] dxdX_q Mapping Jacobian (gradient of the coordinate space) 2048756a6ccSJames Wright * @param[out] dXdx Inverse of mapping Jacobian at quadrature point i 2058756a6ccSJames Wright */ 2068756a6ccSJames Wright CEED_QFUNCTION_HELPER void InvertBoundaryMappingJacobian_3D(CeedInt Q, CeedInt i, const CeedScalar (*dxdX_q)[3][CEED_Q_VLA], CeedScalar dXdx[2][3]) { 2078756a6ccSJames Wright const CeedScalar dxdX[3][2] = { 2088756a6ccSJames Wright {dxdX_q[0][0][i], dxdX_q[1][0][i]}, 2098756a6ccSJames Wright {dxdX_q[0][1][i], dxdX_q[1][1][i]}, 2108756a6ccSJames Wright {dxdX_q[0][2][i], dxdX_q[1][2][i]} 2118756a6ccSJames Wright }; 2128756a6ccSJames Wright 2138756a6ccSJames Wright // dxdX_k,j * dxdX_j,k 2148756a6ccSJames Wright CeedScalar dxdXTdxdX[2][2] = {{0.}}; 2158756a6ccSJames Wright for (CeedInt j = 0; j < 2; j++) { 2168756a6ccSJames Wright for (CeedInt k = 0; k < 2; k++) { 2178756a6ccSJames Wright for (CeedInt l = 0; l < 3; l++) dxdXTdxdX[j][k] += dxdX[l][j] * dxdX[l][k]; 2188756a6ccSJames Wright } 2198756a6ccSJames Wright } 2208756a6ccSJames Wright 2218756a6ccSJames Wright const CeedScalar detdxdXTdxdX = dxdXTdxdX[0][0] * dxdXTdxdX[1][1] - dxdXTdxdX[1][0] * dxdXTdxdX[0][1]; 2228756a6ccSJames Wright 2238756a6ccSJames Wright // Compute inverse of dxdXTdxdX 2248756a6ccSJames Wright CeedScalar dxdXTdxdX_inv[2][2]; 2258756a6ccSJames Wright dxdXTdxdX_inv[0][0] = dxdXTdxdX[1][1] / detdxdXTdxdX; 2268756a6ccSJames Wright dxdXTdxdX_inv[0][1] = -dxdXTdxdX[0][1] / detdxdXTdxdX; 2278756a6ccSJames Wright dxdXTdxdX_inv[1][0] = -dxdXTdxdX[1][0] / detdxdXTdxdX; 2288756a6ccSJames Wright dxdXTdxdX_inv[1][1] = dxdXTdxdX[0][0] / detdxdXTdxdX; 2298756a6ccSJames Wright 2308756a6ccSJames Wright // Compute dXdx from dxdXTdxdX^-1 and dxdX 2318756a6ccSJames Wright for (CeedInt j = 0; j < 2; j++) { 2328756a6ccSJames Wright for (CeedInt k = 0; k < 3; k++) { 2338756a6ccSJames Wright dXdx[j][k] = 0; 2348756a6ccSJames Wright for (CeedInt l = 0; l < 2; l++) dXdx[j][k] += dxdXTdxdX_inv[l][j] * dxdX[k][l]; 2358756a6ccSJames Wright } 2368756a6ccSJames Wright } 2378756a6ccSJames Wright } 2388756a6ccSJames Wright 2398756a6ccSJames Wright #endif // setupgeo_helpers_h 240