1*1a74fa30SJames Wright // Copyright (c) 2017-2023, Lawrence Livermore National Security, LLC and other CEED contributors. 2*1a74fa30SJames Wright // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3*1a74fa30SJames Wright // 4*1a74fa30SJames Wright // SPDX-License-Identifier: BSD-2-Clause 5*1a74fa30SJames Wright // 6*1a74fa30SJames Wright // This file is part of CEED: http://github.com/ceed 7*1a74fa30SJames Wright 8*1a74fa30SJames Wright /// @file 9*1a74fa30SJames Wright /// Geometric factors (3D) for Navier-Stokes example using PETSc 10*1a74fa30SJames Wright 11*1a74fa30SJames Wright #ifndef setupgeo_helpers_h 12*1a74fa30SJames Wright #define setupgeo_helpers_h 13*1a74fa30SJames Wright 14*1a74fa30SJames Wright #include <ceed.h> 15*1a74fa30SJames Wright #include <math.h> 16*1a74fa30SJames Wright 17*1a74fa30SJames Wright #include "utils.h" 18*1a74fa30SJames Wright 19*1a74fa30SJames Wright /** 20*1a74fa30SJames Wright * @brief Calculate dXdx from dxdX for 3D elements 21*1a74fa30SJames Wright * 22*1a74fa30SJames Wright * Reference (parent) coordinates: X 23*1a74fa30SJames Wright * Physical (current) coordinates: x 24*1a74fa30SJames Wright * Change of coordinate matrix: dxdX_{i,j} = x_{i,j} (indicial notation) 25*1a74fa30SJames Wright * Inverse of change of coordinate matrix: dXdx_{i,j} = (detJ^-1) * X_{i,j} 26*1a74fa30SJames Wright * 27*1a74fa30SJames Wright * Determinant of Jacobian: 28*1a74fa30SJames Wright * detJ = J11*A11 + J21*A12 + J31*A13 29*1a74fa30SJames Wright * Jij = Jacobian entry ij 30*1a74fa30SJames Wright * Aij = Adjugate ij 31*1a74fa30SJames Wright * 32*1a74fa30SJames Wright * Inverse of Jacobian: 33*1a74fa30SJames Wright * dXdx_i,j = Aij / detJ 34*1a74fa30SJames Wright * 35*1a74fa30SJames Wright * @param[in] Q Number of quadrature points 36*1a74fa30SJames Wright * @param[in] i Current quadrature point 37*1a74fa30SJames Wright * @param[in] dxdX_q Mapping Jacobian (gradient of the coordinate space) 38*1a74fa30SJames Wright * @param[out] dXdx Inverse of mapping Jacobian at quadrature point i 39*1a74fa30SJames Wright * @param[out] detJ_ptr Determinate of the Jacobian, may be NULL is not desired 40*1a74fa30SJames Wright */ 41*1a74fa30SJames Wright CEED_QFUNCTION_HELPER void InvertMappingJacobian_3D(CeedInt Q, CeedInt i, const CeedScalar (*dxdX_q)[3][CEED_Q_VLA], CeedScalar dXdx[3][3], 42*1a74fa30SJames Wright CeedScalar *detJ_ptr) { 43*1a74fa30SJames Wright const CeedScalar dxdX_11 = dxdX_q[0][0][i]; 44*1a74fa30SJames Wright const CeedScalar dxdX_21 = dxdX_q[0][1][i]; 45*1a74fa30SJames Wright const CeedScalar dxdX_31 = dxdX_q[0][2][i]; 46*1a74fa30SJames Wright const CeedScalar dxdX_12 = dxdX_q[1][0][i]; 47*1a74fa30SJames Wright const CeedScalar dxdX_22 = dxdX_q[1][1][i]; 48*1a74fa30SJames Wright const CeedScalar dxdX_32 = dxdX_q[1][2][i]; 49*1a74fa30SJames Wright const CeedScalar dxdX_13 = dxdX_q[2][0][i]; 50*1a74fa30SJames Wright const CeedScalar dxdX_23 = dxdX_q[2][1][i]; 51*1a74fa30SJames Wright const CeedScalar dxdX_33 = dxdX_q[2][2][i]; 52*1a74fa30SJames Wright const CeedScalar A11 = dxdX_22 * dxdX_33 - dxdX_23 * dxdX_32; 53*1a74fa30SJames Wright const CeedScalar A12 = dxdX_13 * dxdX_32 - dxdX_12 * dxdX_33; 54*1a74fa30SJames Wright const CeedScalar A13 = dxdX_12 * dxdX_23 - dxdX_13 * dxdX_22; 55*1a74fa30SJames Wright const CeedScalar A21 = dxdX_23 * dxdX_31 - dxdX_21 * dxdX_33; 56*1a74fa30SJames Wright const CeedScalar A22 = dxdX_11 * dxdX_33 - dxdX_13 * dxdX_31; 57*1a74fa30SJames Wright const CeedScalar A23 = dxdX_13 * dxdX_21 - dxdX_11 * dxdX_23; 58*1a74fa30SJames Wright const CeedScalar A31 = dxdX_21 * dxdX_32 - dxdX_22 * dxdX_31; 59*1a74fa30SJames Wright const CeedScalar A32 = dxdX_12 * dxdX_31 - dxdX_11 * dxdX_32; 60*1a74fa30SJames Wright const CeedScalar A33 = dxdX_11 * dxdX_22 - dxdX_12 * dxdX_21; 61*1a74fa30SJames Wright const CeedScalar detJ = dxdX_11 * A11 + dxdX_21 * A12 + dxdX_31 * A13; 62*1a74fa30SJames Wright 63*1a74fa30SJames Wright dXdx[0][0] = A11 / detJ; 64*1a74fa30SJames Wright dXdx[0][1] = A12 / detJ; 65*1a74fa30SJames Wright dXdx[0][2] = A13 / detJ; 66*1a74fa30SJames Wright dXdx[1][0] = A21 / detJ; 67*1a74fa30SJames Wright dXdx[1][1] = A22 / detJ; 68*1a74fa30SJames Wright dXdx[1][2] = A23 / detJ; 69*1a74fa30SJames Wright dXdx[2][0] = A31 / detJ; 70*1a74fa30SJames Wright dXdx[2][1] = A32 / detJ; 71*1a74fa30SJames Wright dXdx[2][2] = A33 / detJ; 72*1a74fa30SJames Wright if (detJ_ptr) *detJ_ptr = detJ; 73*1a74fa30SJames Wright } 74*1a74fa30SJames Wright 75*1a74fa30SJames Wright /** 76*1a74fa30SJames Wright * @brief Calculate face element's normal vector from dxdX 77*1a74fa30SJames Wright * 78*1a74fa30SJames Wright * Reference (parent) 2D coordinates: X 79*1a74fa30SJames Wright * Physical (current) 3D coordinates: x 80*1a74fa30SJames Wright * Change of coordinate matrix: 81*1a74fa30SJames Wright * dxdX_{i,j} = dx_i/dX_j (indicial notation) [3 * 2] 82*1a74fa30SJames Wright * Inverse change of coordinate matrix: 83*1a74fa30SJames Wright * dXdx_{i,j} = dX_i/dx_j (indicial notation) [2 * 3] 84*1a74fa30SJames Wright * 85*1a74fa30SJames Wright * (J1,J2,J3) is given by the cross product of the columns of dxdX_{i,j} 86*1a74fa30SJames Wright * 87*1a74fa30SJames Wright * detJb is the magnitude of (J1,J2,J3) 88*1a74fa30SJames Wright * 89*1a74fa30SJames Wright * Normal vector = (J1,J2,J3) / detJb 90*1a74fa30SJames Wright * 91*1a74fa30SJames Wright * Stored: (J1,J2,J3) / detJb 92*1a74fa30SJames Wright * in q_data_sur[1:3] as 93*1a74fa30SJames Wright * (detJb^-1) * [ J1 ] 94*1a74fa30SJames Wright * [ J2 ] 95*1a74fa30SJames Wright * [ J3 ] 96*1a74fa30SJames Wright * 97*1a74fa30SJames Wright * @param[in] Q Number of quadrature points 98*1a74fa30SJames Wright * @param[in] i Current quadrature point 99*1a74fa30SJames Wright * @param[in] dxdX_q Mapping Jacobian (gradient of the coordinate space) 100*1a74fa30SJames Wright * @param[out] normal Inverse of mapping Jacobian at quadrature point i 101*1a74fa30SJames Wright * @param[out] detJ_ptr Determinate of the Jacobian, may be NULL is not desired 102*1a74fa30SJames Wright */ 103*1a74fa30SJames Wright CEED_QFUNCTION_HELPER void NormalVectorFromdxdX_3D(CeedInt Q, CeedInt i, const CeedScalar dxdX_q[][3][CEED_Q_VLA], CeedScalar normal[3], 104*1a74fa30SJames Wright CeedScalar *detJ_ptr) { 105*1a74fa30SJames Wright const CeedScalar dxdX[3][2] = { 106*1a74fa30SJames Wright {dxdX_q[0][0][i], dxdX_q[1][0][i]}, 107*1a74fa30SJames Wright {dxdX_q[0][1][i], dxdX_q[1][1][i]}, 108*1a74fa30SJames Wright {dxdX_q[0][2][i], dxdX_q[1][2][i]} 109*1a74fa30SJames Wright }; 110*1a74fa30SJames Wright // J1, J2, and J3 are given by the cross product of the columns of dxdX 111*1a74fa30SJames Wright const CeedScalar J1 = dxdX[1][0] * dxdX[2][1] - dxdX[2][0] * dxdX[1][1]; 112*1a74fa30SJames Wright const CeedScalar J2 = dxdX[2][0] * dxdX[0][1] - dxdX[0][0] * dxdX[2][1]; 113*1a74fa30SJames Wright const CeedScalar J3 = dxdX[0][0] * dxdX[1][1] - dxdX[1][0] * dxdX[0][1]; 114*1a74fa30SJames Wright 115*1a74fa30SJames Wright const CeedScalar detJ = sqrt(J1 * J1 + J2 * J2 + J3 * J3); 116*1a74fa30SJames Wright 117*1a74fa30SJames Wright normal[0] = J1 / detJ; 118*1a74fa30SJames Wright normal[1] = J2 / detJ; 119*1a74fa30SJames Wright normal[2] = J3 / detJ; 120*1a74fa30SJames Wright if (detJ_ptr) *detJ_ptr = detJ; 121*1a74fa30SJames Wright } 122*1a74fa30SJames Wright 123*1a74fa30SJames Wright /** 124*1a74fa30SJames Wright * @brief Calculate inverse of mapping Jacobian, (dxdX)^-1 125*1a74fa30SJames Wright * 126*1a74fa30SJames Wright * Reference (parent) 2D coordinates: X 127*1a74fa30SJames Wright * Physical (current) 3D coordinates: x 128*1a74fa30SJames Wright * Change of coordinate matrix: 129*1a74fa30SJames Wright * dxdX_{i,j} = dx_i/dX_j (indicial notation) [3 * 2] 130*1a74fa30SJames Wright * Inverse change of coordinate matrix: 131*1a74fa30SJames Wright * dXdx_{i,j} = dX_i/dx_j (indicial notation) [2 * 3] 132*1a74fa30SJames Wright * 133*1a74fa30SJames Wright * dXdx is calculated via Moore–Penrose inverse: 134*1a74fa30SJames Wright * 135*1a74fa30SJames Wright * dX_i/dx_j = (dxdX^T dxdX)^(-1) dxdX 136*1a74fa30SJames Wright * = (dx_l/dX_i * dx_l/dX_k)^(-1) dx_j/dX_k 137*1a74fa30SJames Wright * 138*1a74fa30SJames Wright * @param[in] Q Number of quadrature points 139*1a74fa30SJames Wright * @param[in] i Current quadrature point 140*1a74fa30SJames Wright * @param[in] dxdX_q Mapping Jacobian (gradient of the coordinate space) 141*1a74fa30SJames Wright * @param[out] dXdx Inverse of mapping Jacobian at quadrature point i 142*1a74fa30SJames Wright */ 143*1a74fa30SJames Wright CEED_QFUNCTION_HELPER void InvertBoundaryMappingJacobian_3D(CeedInt Q, CeedInt i, const CeedScalar (*dxdX_q)[3][CEED_Q_VLA], CeedScalar dXdx[2][3]) { 144*1a74fa30SJames Wright const CeedScalar dxdX[3][2] = { 145*1a74fa30SJames Wright {dxdX_q[0][0][i], dxdX_q[1][0][i]}, 146*1a74fa30SJames Wright {dxdX_q[0][1][i], dxdX_q[1][1][i]}, 147*1a74fa30SJames Wright {dxdX_q[0][2][i], dxdX_q[1][2][i]} 148*1a74fa30SJames Wright }; 149*1a74fa30SJames Wright 150*1a74fa30SJames Wright // dxdX_k,j * dxdX_j,k 151*1a74fa30SJames Wright CeedScalar dxdXTdxdX[2][2] = {{0.}}; 152*1a74fa30SJames Wright for (CeedInt j = 0; j < 2; j++) { 153*1a74fa30SJames Wright for (CeedInt k = 0; k < 2; k++) { 154*1a74fa30SJames Wright for (CeedInt l = 0; l < 3; l++) dxdXTdxdX[j][k] += dxdX[l][j] * dxdX[l][k]; 155*1a74fa30SJames Wright } 156*1a74fa30SJames Wright } 157*1a74fa30SJames Wright 158*1a74fa30SJames Wright const CeedScalar detdxdXTdxdX = dxdXTdxdX[0][0] * dxdXTdxdX[1][1] - dxdXTdxdX[1][0] * dxdXTdxdX[0][1]; 159*1a74fa30SJames Wright 160*1a74fa30SJames Wright // Compute inverse of dxdXTdxdX 161*1a74fa30SJames Wright CeedScalar dxdXTdxdX_inv[2][2]; 162*1a74fa30SJames Wright dxdXTdxdX_inv[0][0] = dxdXTdxdX[1][1] / detdxdXTdxdX; 163*1a74fa30SJames Wright dxdXTdxdX_inv[0][1] = -dxdXTdxdX[0][1] / detdxdXTdxdX; 164*1a74fa30SJames Wright dxdXTdxdX_inv[1][0] = -dxdXTdxdX[1][0] / detdxdXTdxdX; 165*1a74fa30SJames Wright dxdXTdxdX_inv[1][1] = dxdXTdxdX[0][0] / detdxdXTdxdX; 166*1a74fa30SJames Wright 167*1a74fa30SJames Wright // Compute dXdx from dxdXTdxdX^-1 and dxdX 168*1a74fa30SJames Wright for (CeedInt j = 0; j < 2; j++) { 169*1a74fa30SJames Wright for (CeedInt k = 0; k < 3; k++) { 170*1a74fa30SJames Wright dXdx[j][k] = 0; 171*1a74fa30SJames Wright for (CeedInt l = 0; l < 2; l++) dXdx[j][k] += dxdXTdxdX_inv[l][j] * dxdX[k][l]; 172*1a74fa30SJames Wright } 173*1a74fa30SJames Wright } 174*1a74fa30SJames Wright } 175*1a74fa30SJames Wright 176*1a74fa30SJames Wright #endif // setupgeo_helpers_h 177