xref: /libCEED/tests/t580-operator.h (revision d4cc18453651bd0f94c1a2e078b2646a92dafdcc)
1*9ba83ac0SJeremy L Thompson // Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors.
2506b1a0cSSebastian Grimberg // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3506b1a0cSSebastian Grimberg //
4506b1a0cSSebastian Grimberg // SPDX-License-Identifier: BSD-2-Clause
5506b1a0cSSebastian Grimberg //
6506b1a0cSSebastian Grimberg // This file is part of CEED:  http://github.com/ceed
7506b1a0cSSebastian Grimberg 
8c0b5abf0SJeremy L Thompson #include <ceed/types.h>
9506b1a0cSSebastian Grimberg 
10506b1a0cSSebastian Grimberg // Compute det(A)
MatDet2x2(const CeedScalar A[2][2])11506b1a0cSSebastian Grimberg CEED_QFUNCTION_HELPER CeedScalar MatDet2x2(const CeedScalar A[2][2]) { return A[0][0] * A[1][1] - A[1][0] * A[0][1]; }
12506b1a0cSSebastian Grimberg 
13506b1a0cSSebastian Grimberg // Compute alpha * A^T * B = C
AlphaMatTransposeMatMult2x2(const CeedScalar alpha,const CeedScalar A[2][2],const CeedScalar B[2][2],CeedScalar C[2][2])14506b1a0cSSebastian Grimberg CEED_QFUNCTION_HELPER int AlphaMatTransposeMatMult2x2(const CeedScalar alpha, const CeedScalar A[2][2], const CeedScalar B[2][2],
15506b1a0cSSebastian Grimberg                                                       CeedScalar C[2][2]) {
16506b1a0cSSebastian Grimberg   for (CeedInt j = 0; j < 2; j++) {
17506b1a0cSSebastian Grimberg     for (CeedInt k = 0; k < 2; k++) {
18506b1a0cSSebastian Grimberg       C[j][k] = 0;
19506b1a0cSSebastian Grimberg       for (CeedInt m = 0; m < 2; m++) {
20506b1a0cSSebastian Grimberg         C[j][k] += alpha * A[m][j] * B[m][k];
21506b1a0cSSebastian Grimberg       }
22506b1a0cSSebastian Grimberg     }
23506b1a0cSSebastian Grimberg   }
24506b1a0cSSebastian Grimberg 
25506b1a0cSSebastian Grimberg   return 0;
26506b1a0cSSebastian Grimberg }
27506b1a0cSSebastian Grimberg 
mass(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)28506b1a0cSSebastian Grimberg CEED_QFUNCTION(mass)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
29506b1a0cSSebastian Grimberg   // Inputs
30506b1a0cSSebastian Grimberg   const CeedScalar(*w) = in[0], (*dxdX)[2][CEED_Q_VLA] = (const CeedScalar(*)[2][CEED_Q_VLA])in[1],
31506b1a0cSSebastian Grimberg         (*u)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2];
32506b1a0cSSebastian Grimberg 
33506b1a0cSSebastian Grimberg   // Outputs
34506b1a0cSSebastian Grimberg   CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0];
35506b1a0cSSebastian Grimberg 
36506b1a0cSSebastian Grimberg   // Quadrature Point Loop
37506b1a0cSSebastian Grimberg   CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
38506b1a0cSSebastian Grimberg     // Setup, J = dx/dX
39506b1a0cSSebastian Grimberg     const CeedScalar J[2][2] = {
40506b1a0cSSebastian Grimberg         {dxdX[0][0][i], dxdX[1][0][i]},
41506b1a0cSSebastian Grimberg         {dxdX[0][1][i], dxdX[1][1][i]}
42506b1a0cSSebastian Grimberg     };
43506b1a0cSSebastian Grimberg     const CeedScalar det_J = MatDet2x2(J);
44506b1a0cSSebastian Grimberg 
45506b1a0cSSebastian Grimberg     // Piola map: J^T*J*u*w/detJ
46506b1a0cSSebastian Grimberg     // 1) Compute J^T * J
47506b1a0cSSebastian Grimberg     CeedScalar JT_J[2][2];
48506b1a0cSSebastian Grimberg     AlphaMatTransposeMatMult2x2(1., J, J, JT_J);
49506b1a0cSSebastian Grimberg 
50506b1a0cSSebastian Grimberg     // 2) Compute J^T*J*u * w /detJ
51506b1a0cSSebastian Grimberg     for (CeedInt k = 0; k < 2; k++) {
52506b1a0cSSebastian Grimberg       v[k][i] = 0;
53506b1a0cSSebastian Grimberg       for (CeedInt m = 0; m < 2; m++) v[k][i] += JT_J[k][m] * u[m][i] * w[i] / det_J;
54506b1a0cSSebastian Grimberg     }
55506b1a0cSSebastian Grimberg   }  // End of Quadrature Point Loop
56506b1a0cSSebastian Grimberg 
57506b1a0cSSebastian Grimberg   return 0;
58506b1a0cSSebastian Grimberg }
59