xref: /honee/qfunctions/setupgeo.h (revision ade4951188ee005b66ffd0a9de0bd2ad8f48d7f6)
11a74fa30SJames Wright // Copyright (c) 2017-2023, Lawrence Livermore National Security, LLC and other CEED contributors.
2727da7e7SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3a515125bSLeila Ghaffari //
4727da7e7SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
5a515125bSLeila Ghaffari //
6727da7e7SJeremy L Thompson // This file is part of CEED:  http://github.com/ceed
7a515125bSLeila Ghaffari 
8a515125bSLeila Ghaffari /// @file
9a515125bSLeila Ghaffari /// Geometric factors (3D) for Navier-Stokes example using PETSc
10a515125bSLeila Ghaffari 
11a515125bSLeila Ghaffari #ifndef setup_geo_h
12a515125bSLeila Ghaffari #define setup_geo_h
13a515125bSLeila Ghaffari 
143a8779fbSJames Wright #include <ceed.h>
15d0cce58aSJeremy L Thompson #include <math.h>
16a515125bSLeila Ghaffari 
171a74fa30SJames Wright #include "setupgeo_helpers.h"
18*ade49511SJames Wright #include "utils.h"
191a74fa30SJames Wright 
20a515125bSLeila Ghaffari // *****************************************************************************
2104e40bb6SJeremy L Thompson // This QFunction sets up the geometric factors required for integration and coordinate transformations
22a515125bSLeila Ghaffari //
23a515125bSLeila Ghaffari // Reference (parent) coordinates: X
24a515125bSLeila Ghaffari // Physical (current) coordinates: x
25a515125bSLeila Ghaffari // Change of coordinate matrix: dxdX_{i,j} = x_{i,j} (indicial notation)
26a515125bSLeila Ghaffari // Inverse of change of coordinate matrix: dXdx_{i,j} = (detJ^-1) * X_{i,j}
27a515125bSLeila Ghaffari //
28a515125bSLeila Ghaffari // All quadrature data is stored in 10 field vector of quadrature data.
29a515125bSLeila Ghaffari //
3004e40bb6SJeremy L Thompson // We require the determinant of the Jacobian to properly compute integrals of the form: int( v u )
31a515125bSLeila Ghaffari //
32a515125bSLeila Ghaffari // Determinant of Jacobian:
33a515125bSLeila Ghaffari //   detJ = J11*A11 + J21*A12 + J31*A13
34a515125bSLeila Ghaffari //     Jij = Jacobian entry ij
351a74fa30SJames Wright //     Aij = Adjugate ij
36a515125bSLeila Ghaffari //
37a515125bSLeila Ghaffari // Stored: w detJ
38a515125bSLeila Ghaffari //   in q_data[0]
39a515125bSLeila Ghaffari //
4004e40bb6SJeremy L Thompson // We require the transpose of the inverse of the Jacobian to properly compute integrals of the form: int( gradv u )
41a515125bSLeila Ghaffari //
42a515125bSLeila Ghaffari // Inverse of Jacobian:
43a515125bSLeila Ghaffari //   dXdx_i,j = Aij / detJ
44a515125bSLeila Ghaffari //
45a515125bSLeila Ghaffari // Stored: Aij / detJ
46a515125bSLeila Ghaffari //   in q_data[1:9] as
47a515125bSLeila Ghaffari //   (detJ^-1) * [A11 A12 A13]
48a515125bSLeila Ghaffari //               [A21 A22 A23]
49a515125bSLeila Ghaffari //               [A31 A32 A33]
50a515125bSLeila Ghaffari // *****************************************************************************
512b916ea7SJeremy L Thompson CEED_QFUNCTION(Setup)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
523d65b166SJames Wright   const CeedScalar(*J)[3][CEED_Q_VLA] = (const CeedScalar(*)[3][CEED_Q_VLA])in[0];
533d65b166SJames Wright   const CeedScalar(*w)                = in[1];
54*ade49511SJames Wright   CeedScalar(*q_data)                 = out[0];
55a515125bSLeila Ghaffari 
561a74fa30SJames Wright   CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
571a74fa30SJames Wright     CeedScalar detJ, dXdx[3][3];
581a74fa30SJames Wright     InvertMappingJacobian_3D(Q, i, J, dXdx, &detJ);
59*ade49511SJames Wright     const CeedScalar wdetJ = w[i] * detJ;
60*ade49511SJames Wright 
61*ade49511SJames Wright     StoredValuesPack(Q, i, 0, 1, &wdetJ, q_data);
62*ade49511SJames Wright     StoredValuesPack(Q, i, 1, 9, (const CeedScalar *)dXdx, q_data);
631a74fa30SJames Wright   }
64a515125bSLeila Ghaffari   return 0;
65a515125bSLeila Ghaffari }
66a515125bSLeila Ghaffari 
67a515125bSLeila Ghaffari // *****************************************************************************
6804e40bb6SJeremy L Thompson // This QFunction sets up the geometric factor required for integration when reference coordinates are in 2D and the physical coordinates are in 3D
69a515125bSLeila Ghaffari //
70a515125bSLeila Ghaffari // Reference (parent) 2D coordinates: X
71a515125bSLeila Ghaffari // Physical (current) 3D coordinates: x
72a515125bSLeila Ghaffari // Change of coordinate matrix:
73a515125bSLeila Ghaffari //   dxdX_{i,j} = dx_i/dX_j (indicial notation) [3 * 2]
74493642f1SJames Wright // Inverse change of coordinate matrix:
75493642f1SJames Wright //   dXdx_{i,j} = dX_i/dx_j (indicial notation) [2 * 3]
76a515125bSLeila Ghaffari //
77a515125bSLeila Ghaffari // (J1,J2,J3) is given by the cross product of the columns of dxdX_{i,j}
78a515125bSLeila Ghaffari //
79a515125bSLeila Ghaffari // detJb is the magnitude of (J1,J2,J3)
80a515125bSLeila Ghaffari //
81493642f1SJames Wright // dXdx is calculated via Moore–Penrose inverse:
82493642f1SJames Wright //
83493642f1SJames Wright //   dX_i/dx_j = (dxdX^T dxdX)^(-1) dxdX
84493642f1SJames Wright //             = (dx_l/dX_i * dx_l/dX_k)^(-1) dx_j/dX_k
85493642f1SJames Wright //
86493642f1SJames Wright // All quadrature data is stored in 10 field vector of quadrature data.
87a515125bSLeila Ghaffari //
88a515125bSLeila Ghaffari // We require the determinant of the Jacobian to properly compute integrals of
89a515125bSLeila Ghaffari //   the form: int( u v )
90a515125bSLeila Ghaffari //
91a515125bSLeila Ghaffari // Stored: w detJb
92a515125bSLeila Ghaffari //   in q_data_sur[0]
93a515125bSLeila Ghaffari //
94a515125bSLeila Ghaffari // Normal vector = (J1,J2,J3) / detJb
95a515125bSLeila Ghaffari //
96493642f1SJames Wright //   - TODO Could possibly remove normal vector, as it could be calculated in the Qfunction from dXdx
971a74fa30SJames Wright //    See https://github.com/CEED/libCEED/pull/868#discussion_r871979484
98a515125bSLeila Ghaffari // Stored: (J1,J2,J3) / detJb
99a515125bSLeila Ghaffari //   in q_data_sur[1:3] as
100a515125bSLeila Ghaffari //   (detJb^-1) * [ J1 ]
101a515125bSLeila Ghaffari //                [ J2 ]
102a515125bSLeila Ghaffari //                [ J3 ]
103a515125bSLeila Ghaffari //
104493642f1SJames Wright // Stored: dXdx_{i,j}
105493642f1SJames Wright //   in q_data_sur[4:9] as
106493642f1SJames Wright //    [dXdx_11 dXdx_12 dXdx_13]
107493642f1SJames Wright //    [dXdx_21 dXdx_22 dXdx_23]
108a515125bSLeila Ghaffari // *****************************************************************************
1092b916ea7SJeremy L Thompson CEED_QFUNCTION(SetupBoundary)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
1103d65b166SJames Wright   const CeedScalar(*J)[3][CEED_Q_VLA] = (const CeedScalar(*)[3][CEED_Q_VLA])in[0];
1113d65b166SJames Wright   const CeedScalar(*w)                = in[1];
112*ade49511SJames Wright   CeedScalar(*q_data_sur)             = out[0];
113a515125bSLeila Ghaffari 
1141a74fa30SJames Wright   CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
1151a74fa30SJames Wright     CeedScalar detJb, normal[3], dXdx[2][3];
116a515125bSLeila Ghaffari 
1171a74fa30SJames Wright     NormalVectorFromdxdX_3D(Q, i, J, normal, &detJb);
1181a74fa30SJames Wright     InvertBoundaryMappingJacobian_3D(Q, i, J, dXdx);
119*ade49511SJames Wright     const CeedScalar wdetJ = w[i] * detJb;
120*ade49511SJames Wright 
121*ade49511SJames Wright     StoredValuesPack(Q, i, 0, 1, &wdetJ, q_data_sur);
122*ade49511SJames Wright     StoredValuesPack(Q, i, 1, 3, normal, q_data_sur);
123*ade49511SJames Wright     StoredValuesPack(Q, i, 4, 6, (const CeedScalar *)dXdx, q_data_sur);
1241a74fa30SJames Wright   }
125a515125bSLeila Ghaffari   return 0;
126a515125bSLeila Ghaffari }
127a515125bSLeila Ghaffari 
128a515125bSLeila Ghaffari // *****************************************************************************
129a515125bSLeila Ghaffari 
130a515125bSLeila Ghaffari #endif  // setup_geo_h
131