1ae2b091fSJames Wright // SPDX-FileCopyrightText: Copyright (c) 2017-2024, HONEE contributors. 2ae2b091fSJames Wright // SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause 3a515125bSLeila Ghaffari 4a515125bSLeila Ghaffari /// @file 5*ea615d4cSJames Wright /// Geometric factors (2D) for HONEE 63e17a7a1SJames Wright #include <ceed/types.h> 7baadde1fSJames Wright #include "setupgeo_helpers.h" 8baadde1fSJames Wright #include "utils.h" 9a515125bSLeila Ghaffari 10a515125bSLeila Ghaffari // ***************************************************************************** 1104e40bb6SJeremy L Thompson // This QFunction sets up the geometric factors required for integration and coordinate transformations 12a515125bSLeila Ghaffari // 13a515125bSLeila Ghaffari // Reference (parent) coordinates: X 14a515125bSLeila Ghaffari // Physical (current) coordinates: x 15a515125bSLeila Ghaffari // Change of coordinate matrix: dxdX_{i,j} = x_{i,j} (indicial notation) 16a515125bSLeila Ghaffari // Inverse of change of coordinate matrix: dXdx_{i,j} = (detJ^-1) * X_{i,j} 17a515125bSLeila Ghaffari // 18a515125bSLeila Ghaffari // All quadrature data is stored in 10 field vector of quadrature data. 19a515125bSLeila Ghaffari // 2004e40bb6SJeremy L Thompson // We require the determinant of the Jacobian to properly compute integrals of the form: int( v u ) 21a515125bSLeila Ghaffari // 22a515125bSLeila Ghaffari // Determinant of Jacobian: 23a515125bSLeila Ghaffari // detJ = J11*J22 - J21*J12 24a515125bSLeila Ghaffari // Jij = Jacobian entry ij 25a515125bSLeila Ghaffari // 26a515125bSLeila Ghaffari // Stored: w detJ 27a515125bSLeila Ghaffari // in q_data[0] 28a515125bSLeila Ghaffari // 2904e40bb6SJeremy L Thompson // We require the transpose of the inverse of the Jacobian to properly compute integrals of the form: int( gradv u ) 30a515125bSLeila Ghaffari // 31a515125bSLeila Ghaffari // Inverse of Jacobian: 32a515125bSLeila Ghaffari // dXdx_i,j = Aij / detJ 33baadde1fSJames Wright // Aij = Adjugate ij 34a515125bSLeila Ghaffari // 35a515125bSLeila Ghaffari // Stored: Aij / detJ 36a515125bSLeila Ghaffari // in q_data[1:4] as 37a515125bSLeila Ghaffari // (detJ^-1) * [A11 A12] 38a515125bSLeila Ghaffari // [A21 A22] 39a515125bSLeila Ghaffari // ***************************************************************************** 402b916ea7SJeremy L Thompson CEED_QFUNCTION(Setup2d)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 413d65b166SJames Wright const CeedScalar(*J)[2][CEED_Q_VLA] = (const CeedScalar(*)[2][CEED_Q_VLA])in[0]; 423d65b166SJames Wright const CeedScalar(*w) = in[1]; 43baadde1fSJames Wright CeedScalar(*q_data) = out[0]; 443d65b166SJames Wright 45baadde1fSJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 46baadde1fSJames Wright CeedScalar dXdx[2][2], detJ; 47baadde1fSJames Wright InvertMappingJacobian_2D(Q, i, J, dXdx, &detJ); 48baadde1fSJames Wright const CeedScalar wdetJ = w[i] * detJ; 49a515125bSLeila Ghaffari 50baadde1fSJames Wright StoredValuesPack(Q, i, 0, 1, &wdetJ, q_data); 51baadde1fSJames Wright StoredValuesPack(Q, i, 1, 4, (const CeedScalar *)dXdx, q_data); 52baadde1fSJames Wright } 53a515125bSLeila Ghaffari return 0; 54a515125bSLeila Ghaffari } 55a515125bSLeila Ghaffari 56a515125bSLeila Ghaffari // ***************************************************************************** 5704e40bb6SJeremy L Thompson // This QFunction sets up the geometric factor required for integration when reference coordinates are in 1D and the physical coordinates are in 2D 58a515125bSLeila Ghaffari // 59a515125bSLeila Ghaffari // Reference (parent) 1D coordinates: X 60a515125bSLeila Ghaffari // Physical (current) 2D coordinates: x 61a515125bSLeila Ghaffari // Change of coordinate vector: 62a515125bSLeila Ghaffari // J1 = dx_1/dX 63a515125bSLeila Ghaffari // J2 = dx_2/dX 64a515125bSLeila Ghaffari // 65a515125bSLeila Ghaffari // detJb is the magnitude of (J1,J2) 66a515125bSLeila Ghaffari // 67a515125bSLeila Ghaffari // All quadrature data is stored in 3 field vector of quadrature data. 68a515125bSLeila Ghaffari // 6904e40bb6SJeremy L Thompson // We require the determinant of the Jacobian to properly compute integrals of the form: int( u v ) 70a515125bSLeila Ghaffari // 71a515125bSLeila Ghaffari // Stored: w detJb 72a515125bSLeila Ghaffari // in q_data_sur[0] 73a515125bSLeila Ghaffari // 74a515125bSLeila Ghaffari // Normal vector is given by the cross product of (J1,J2)/detJ and ẑ 75a515125bSLeila Ghaffari // 76a515125bSLeila Ghaffari // Stored: (J1,J2,0) x (0,0,1) / detJb 77a515125bSLeila Ghaffari // in q_data_sur[1:2] as 78a515125bSLeila Ghaffari // (detJb^-1) * [ J2 ] 79a515125bSLeila Ghaffari // [-J1 ] 80a515125bSLeila Ghaffari // ***************************************************************************** 812b916ea7SJeremy L Thompson CEED_QFUNCTION(SetupBoundary2d)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 823d65b166SJames Wright const CeedScalar(*J)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0]; 833d65b166SJames Wright const CeedScalar(*w) = in[1]; 842c512a7bSJames Wright CeedScalar(*q_data_sur) = out[0]; 853d65b166SJames Wright 862c512a7bSJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 872c512a7bSJames Wright CeedScalar normal[2], detJb; 882c512a7bSJames Wright NormalVectorFromdxdX_2D(Q, i, J, normal, &detJb); 892c512a7bSJames Wright const CeedScalar wdetJ = w[i] * detJb; 90a515125bSLeila Ghaffari 912c512a7bSJames Wright StoredValuesPack(Q, i, 0, 1, &wdetJ, q_data_sur); 922c512a7bSJames Wright StoredValuesPack(Q, i, 1, 2, normal, q_data_sur); 932c512a7bSJames Wright } 94a515125bSLeila Ghaffari return 0; 95a515125bSLeila Ghaffari } 96c864c5abSJames Wright 97c864c5abSJames Wright // ***************************************************************************** 98c8549705SJames Wright // This QFunction sets up the geometric factor required for integration when reference coordinates are 2D and the physical coordinates are in 3D 99c8549705SJames Wright // 100c8549705SJames Wright // In otherwords, when a 2D topology element is embedded in a 3D physical space. 101c864c5abSJames Wright // 102c864c5abSJames Wright // Reference (parent) 2D coordinates: X 103c864c5abSJames Wright // Physical (current) 3D coordinates: x 104c864c5abSJames Wright // Change of coordinate matrix: 105c864c5abSJames Wright // dxdX_{i,j} = dx_i/dX_j (indicial notation) [3 * 2] 106c864c5abSJames Wright // Inverse change of coordinate matrix: 107c864c5abSJames Wright // dXdx_{i,j} = dX_i/dx_j (indicial notation) [2 * 3] 108c864c5abSJames Wright // 109c864c5abSJames Wright // (J1,J2,J3) is given by the cross product of the columns of dxdX_{i,j} 110c864c5abSJames Wright // 111c864c5abSJames Wright // detJb is the magnitude of (J1,J2,J3) 112c864c5abSJames Wright // 113c864c5abSJames Wright // dXdx is calculated via Moore–Penrose inverse: 114c864c5abSJames Wright // 115c864c5abSJames Wright // dX_i/dx_j = (dxdX^T dxdX)^(-1) dxdX 116c864c5abSJames Wright // = (dx_l/dX_i * dx_l/dX_k)^(-1) dx_j/dX_k 117c864c5abSJames Wright // 118c864c5abSJames Wright // All quadrature data is stored in 10 field vector of quadrature data. 119c864c5abSJames Wright // 120c864c5abSJames Wright // We require the determinant of the Jacobian to properly compute integrals of 121c864c5abSJames Wright // the form: int( u v ) 122c864c5abSJames Wright // 123c864c5abSJames Wright // Stored: w detJb 124c864c5abSJames Wright // in q_data_sur[0] 125c864c5abSJames Wright // 126c864c5abSJames Wright // Normal vector = (J1,J2,J3) / detJb 127c864c5abSJames Wright // 128c864c5abSJames Wright // Stored: (J1,J2,J3) / detJb 129c864c5abSJames Wright // 130c864c5abSJames Wright // Stored: dXdx_{i,j} 131c864c5abSJames Wright // in q_data_sur[1:6] as 132c864c5abSJames Wright // [dXdx_11 dXdx_12 dXdx_13] 133c864c5abSJames Wright // [dXdx_21 dXdx_22 dXdx_23] 134c864c5abSJames Wright // ***************************************************************************** 135c864c5abSJames Wright CEED_QFUNCTION(Setup2D_3Dcoords)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 136c864c5abSJames Wright const CeedScalar(*J)[3][CEED_Q_VLA] = (const CeedScalar(*)[3][CEED_Q_VLA])in[0]; 137c864c5abSJames Wright const CeedScalar(*w) = in[1]; 138c864c5abSJames Wright CeedScalar(*q_data_sur) = out[0]; 139c864c5abSJames Wright 140c864c5abSJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 141c864c5abSJames Wright CeedScalar detJb, normal[3], dXdx[2][3]; 142c864c5abSJames Wright 143c864c5abSJames Wright NormalVectorFromdxdX_3D(Q, i, J, normal, &detJb); 144c864c5abSJames Wright InvertBoundaryMappingJacobian_3D(Q, i, J, dXdx); 145c864c5abSJames Wright const CeedScalar wdetJ = w[i] * detJb; 146c864c5abSJames Wright 147c864c5abSJames Wright StoredValuesPack(Q, i, 0, 1, &wdetJ, q_data_sur); 148c864c5abSJames Wright StoredValuesPack(Q, i, 1, 6, (const CeedScalar *)dXdx, q_data_sur); 149c864c5abSJames Wright } 150c864c5abSJames Wright return 0; 151c864c5abSJames Wright } 152da8b59d6SJames Wright 153da8b59d6SJames Wright /** 154da8b59d6SJames Wright @brief Compute geometric factors for integration, gradient transformations, and coordinate transformations on element faces. 155da8b59d6SJames Wright 156da8b59d6SJames Wright Reference (parent) 1D coordinates are given by `X` and physical (current) 2D coordinates are given by `x`. 157da8b59d6SJames Wright The change of coordinate matrix is given by`dxdX_{i,j} = dx_i/dX_j (indicial notation) [2 * 1]`. 158da8b59d6SJames Wright 159da8b59d6SJames Wright @param[in] ctx QFunction context, unused 160da8b59d6SJames Wright @param[in] Q Number of quadrature points 161da8b59d6SJames Wright @param[in] in Input arrays 162da8b59d6SJames Wright - 0 - Jacobian of cell coordinates 163da8b59d6SJames Wright - 1 - Jacobian of face coordinates 164da8b59d6SJames Wright - 2 - quadrature weights 165da8b59d6SJames Wright @param[out] out Output array 166da8b59d6SJames Wright - 0 - qdata, `w detNb`, `dXdx`, and `N` 167da8b59d6SJames Wright 168da8b59d6SJames Wright @return An error code: 0 - success, otherwise - failure 169da8b59d6SJames Wright **/ 170da8b59d6SJames Wright CEED_QFUNCTION(Setup2DBoundaryGradient)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 171da8b59d6SJames Wright const CeedScalar(*J_cell)[2][CEED_Q_VLA] = (const CeedScalar(*)[2][CEED_Q_VLA])in[0]; 172da8b59d6SJames Wright const CeedScalar(*J_face)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[1]; 173da8b59d6SJames Wright const CeedScalar(*w) = in[2]; 174da8b59d6SJames Wright CeedScalar(*q_data_sur) = out[0]; 175da8b59d6SJames Wright 176da8b59d6SJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 177da8b59d6SJames Wright CeedScalar detJ_face, normal[2], dXdx[2][2]; 178da8b59d6SJames Wright 179da8b59d6SJames Wright NormalVectorFromdxdX_2D(Q, i, J_face, normal, &detJ_face); 180da8b59d6SJames Wright const CeedScalar wdetJ = w[i] * detJ_face; 181da8b59d6SJames Wright InvertMappingJacobian_2D(Q, i, J_cell, dXdx, NULL); 182da8b59d6SJames Wright 183da8b59d6SJames Wright StoredValuesPack(Q, i, 0, 1, &wdetJ, q_data_sur); 184da8b59d6SJames Wright StoredValuesPack(Q, i, 1, 4, (CeedScalar *)dXdx, q_data_sur); 185da8b59d6SJames Wright StoredValuesPack(Q, i, 5, 2, normal, q_data_sur); 186da8b59d6SJames Wright } 187da8b59d6SJames Wright return CEED_ERROR_SUCCESS; 188da8b59d6SJames Wright } 189