1*ae2b091fSJames Wright // SPDX-FileCopyrightText: Copyright (c) 2017-2024, HONEE contributors. 2*ae2b091fSJames Wright // SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause 3a515125bSLeila Ghaffari 4a515125bSLeila Ghaffari /// @file 5a515125bSLeila Ghaffari /// Geometric factors (2D) for Navier-Stokes example using PETSc 6493642f1SJames Wright #include <ceed.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 // ***************************************************************************** 98c864c5abSJames Wright // This QFunction sets up the geometric factor required for integration when reference coordinates are in 2D and the physical coordinates are in 3D 99c864c5abSJames Wright // 100c864c5abSJames Wright // Reference (parent) 2D coordinates: X 101c864c5abSJames Wright // Physical (current) 3D coordinates: x 102c864c5abSJames Wright // Change of coordinate matrix: 103c864c5abSJames Wright // dxdX_{i,j} = dx_i/dX_j (indicial notation) [3 * 2] 104c864c5abSJames Wright // Inverse change of coordinate matrix: 105c864c5abSJames Wright // dXdx_{i,j} = dX_i/dx_j (indicial notation) [2 * 3] 106c864c5abSJames Wright // 107c864c5abSJames Wright // (J1,J2,J3) is given by the cross product of the columns of dxdX_{i,j} 108c864c5abSJames Wright // 109c864c5abSJames Wright // detJb is the magnitude of (J1,J2,J3) 110c864c5abSJames Wright // 111c864c5abSJames Wright // dXdx is calculated via Moore–Penrose inverse: 112c864c5abSJames Wright // 113c864c5abSJames Wright // dX_i/dx_j = (dxdX^T dxdX)^(-1) dxdX 114c864c5abSJames Wright // = (dx_l/dX_i * dx_l/dX_k)^(-1) dx_j/dX_k 115c864c5abSJames Wright // 116c864c5abSJames Wright // All quadrature data is stored in 10 field vector of quadrature data. 117c864c5abSJames Wright // 118c864c5abSJames Wright // We require the determinant of the Jacobian to properly compute integrals of 119c864c5abSJames Wright // the form: int( u v ) 120c864c5abSJames Wright // 121c864c5abSJames Wright // Stored: w detJb 122c864c5abSJames Wright // in q_data_sur[0] 123c864c5abSJames Wright // 124c864c5abSJames Wright // Normal vector = (J1,J2,J3) / detJb 125c864c5abSJames Wright // 126c864c5abSJames Wright // Stored: (J1,J2,J3) / detJb 127c864c5abSJames Wright // 128c864c5abSJames Wright // Stored: dXdx_{i,j} 129c864c5abSJames Wright // in q_data_sur[1:6] as 130c864c5abSJames Wright // [dXdx_11 dXdx_12 dXdx_13] 131c864c5abSJames Wright // [dXdx_21 dXdx_22 dXdx_23] 132c864c5abSJames Wright // ***************************************************************************** 133c864c5abSJames Wright CEED_QFUNCTION(Setup2D_3Dcoords)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 134c864c5abSJames Wright const CeedScalar(*J)[3][CEED_Q_VLA] = (const CeedScalar(*)[3][CEED_Q_VLA])in[0]; 135c864c5abSJames Wright const CeedScalar(*w) = in[1]; 136c864c5abSJames Wright CeedScalar(*q_data_sur) = out[0]; 137c864c5abSJames Wright 138c864c5abSJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 139c864c5abSJames Wright CeedScalar detJb, normal[3], dXdx[2][3]; 140c864c5abSJames Wright 141c864c5abSJames Wright NormalVectorFromdxdX_3D(Q, i, J, normal, &detJb); 142c864c5abSJames Wright InvertBoundaryMappingJacobian_3D(Q, i, J, dXdx); 143c864c5abSJames Wright const CeedScalar wdetJ = w[i] * detJb; 144c864c5abSJames Wright 145c864c5abSJames Wright StoredValuesPack(Q, i, 0, 1, &wdetJ, q_data_sur); 146c864c5abSJames Wright StoredValuesPack(Q, i, 1, 6, (const CeedScalar *)dXdx, q_data_sur); 147c864c5abSJames Wright } 148c864c5abSJames Wright return 0; 149c864c5abSJames Wright } 150