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