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 // *****************************************************************************
Setup2d(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)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 // *****************************************************************************
SetupBoundary2d(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)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 // *****************************************************************************
Setup2D_3Dcoords(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)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 **/
Setup2DBoundaryGradient(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)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