xref: /libCEED/tests/t580-operator.h (revision 506b1a0c535297a01950817d4491440b9ddb5287)
1*506b1a0cSSebastian Grimberg // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors.
2*506b1a0cSSebastian Grimberg // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3*506b1a0cSSebastian Grimberg //
4*506b1a0cSSebastian Grimberg // SPDX-License-Identifier: BSD-2-Clause
5*506b1a0cSSebastian Grimberg //
6*506b1a0cSSebastian Grimberg // This file is part of CEED:  http://github.com/ceed
7*506b1a0cSSebastian Grimberg 
8*506b1a0cSSebastian Grimberg #include <ceed.h>
9*506b1a0cSSebastian Grimberg 
10*506b1a0cSSebastian Grimberg // Compute det(A)
11*506b1a0cSSebastian Grimberg CEED_QFUNCTION_HELPER CeedScalar MatDet2x2(const CeedScalar A[2][2]) { return A[0][0] * A[1][1] - A[1][0] * A[0][1]; }
12*506b1a0cSSebastian Grimberg 
13*506b1a0cSSebastian Grimberg // Compute alpha * A^T * B = C
14*506b1a0cSSebastian Grimberg CEED_QFUNCTION_HELPER int AlphaMatTransposeMatMult2x2(const CeedScalar alpha, const CeedScalar A[2][2], const CeedScalar B[2][2],
15*506b1a0cSSebastian Grimberg                                                       CeedScalar C[2][2]) {
16*506b1a0cSSebastian Grimberg   for (CeedInt j = 0; j < 2; j++) {
17*506b1a0cSSebastian Grimberg     for (CeedInt k = 0; k < 2; k++) {
18*506b1a0cSSebastian Grimberg       C[j][k] = 0;
19*506b1a0cSSebastian Grimberg       for (CeedInt m = 0; m < 2; m++) {
20*506b1a0cSSebastian Grimberg         C[j][k] += alpha * A[m][j] * B[m][k];
21*506b1a0cSSebastian Grimberg       }
22*506b1a0cSSebastian Grimberg     }
23*506b1a0cSSebastian Grimberg   }
24*506b1a0cSSebastian Grimberg 
25*506b1a0cSSebastian Grimberg   return 0;
26*506b1a0cSSebastian Grimberg }
27*506b1a0cSSebastian Grimberg 
28*506b1a0cSSebastian Grimberg CEED_QFUNCTION(mass)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
29*506b1a0cSSebastian Grimberg   // Inputs
30*506b1a0cSSebastian Grimberg   const CeedScalar(*w) = in[0], (*dxdX)[2][CEED_Q_VLA] = (const CeedScalar(*)[2][CEED_Q_VLA])in[1],
31*506b1a0cSSebastian Grimberg         (*u)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2];
32*506b1a0cSSebastian Grimberg 
33*506b1a0cSSebastian Grimberg   // Outputs
34*506b1a0cSSebastian Grimberg   CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0];
35*506b1a0cSSebastian Grimberg 
36*506b1a0cSSebastian Grimberg   // Quadrature Point Loop
37*506b1a0cSSebastian Grimberg   CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
38*506b1a0cSSebastian Grimberg     // Setup, J = dx/dX
39*506b1a0cSSebastian Grimberg     const CeedScalar J[2][2] = {
40*506b1a0cSSebastian Grimberg         {dxdX[0][0][i], dxdX[1][0][i]},
41*506b1a0cSSebastian Grimberg         {dxdX[0][1][i], dxdX[1][1][i]}
42*506b1a0cSSebastian Grimberg     };
43*506b1a0cSSebastian Grimberg     const CeedScalar det_J = MatDet2x2(J);
44*506b1a0cSSebastian Grimberg 
45*506b1a0cSSebastian Grimberg     // Piola map: J^T*J*u*w/detJ
46*506b1a0cSSebastian Grimberg     // 1) Compute J^T * J
47*506b1a0cSSebastian Grimberg     CeedScalar JT_J[2][2];
48*506b1a0cSSebastian Grimberg     AlphaMatTransposeMatMult2x2(1., J, J, JT_J);
49*506b1a0cSSebastian Grimberg 
50*506b1a0cSSebastian Grimberg     // 2) Compute J^T*J*u * w /detJ
51*506b1a0cSSebastian Grimberg     for (CeedInt k = 0; k < 2; k++) {
52*506b1a0cSSebastian Grimberg       v[k][i] = 0;
53*506b1a0cSSebastian Grimberg       for (CeedInt m = 0; m < 2; m++) v[k][i] += JT_J[k][m] * u[m][i] * w[i] / det_J;
54*506b1a0cSSebastian Grimberg     }
55*506b1a0cSSebastian Grimberg   }  // End of Quadrature Point Loop
56*506b1a0cSSebastian Grimberg 
57*506b1a0cSSebastian Grimberg   return 0;
58*506b1a0cSSebastian Grimberg }
59