13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 34d537eeaSYohann // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 54d537eeaSYohann // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 74d537eeaSYohann 8a57ca787Svaleriabarra #ifndef bp3_h 9a57ca787Svaleriabarra #define bp3_h 104d537eeaSYohann 11*c9c2c079SJeremy L Thompson #include <ceed.h> 12*c9c2c079SJeremy L Thompson 134d537eeaSYohann /// A structure used to pass additional data to f_build_diff and f_apply_diff 144d537eeaSYohann struct BuildContext { CeedInt dim, space_dim; }; 154d537eeaSYohann 164d537eeaSYohann /// libCEED Q-function for building quadrature data for a diffusion operator 174d537eeaSYohann CEED_QFUNCTION(f_build_diff)(void *ctx, const CeedInt Q, 184d537eeaSYohann const CeedScalar *const *in, CeedScalar *const *out) { 194d537eeaSYohann BuildContext *bc = (BuildContext *)ctx; 204d537eeaSYohann // in[0] is Jacobians with shape [dim, nc=dim, Q] 214d537eeaSYohann // in[1] is quadrature weights, size (Q) 224d537eeaSYohann // 23a2fa7910SValeria Barra // At every quadrature point, compute w/det(J).adj(J).adj(J)^T and store 244d537eeaSYohann // the symmetric part of the result. 25a2fa7910SValeria Barra const CeedScalar *J = in[0], *w = in[1]; 26a2fa7910SValeria Barra CeedScalar *qdata = out[0]; 27ee07ded2SValeria Barra 284d537eeaSYohann switch (bc->dim + 10*bc->space_dim) { 294d537eeaSYohann case 11: 30ee07ded2SValeria Barra // Quadrature Point Loop 31ee07ded2SValeria Barra CeedPragmaSIMD 324d537eeaSYohann for (CeedInt i=0; i<Q; i++) { 33a2fa7910SValeria Barra qdata[i] = w[i] / J[i]; 344d537eeaSYohann } 354d537eeaSYohann break; 364d537eeaSYohann case 22: 37ee07ded2SValeria Barra // Quadrature Point Loop 38ee07ded2SValeria Barra CeedPragmaSIMD 394d537eeaSYohann for (CeedInt i=0; i<Q; i++) { 40a2fa7910SValeria Barra // J: 0 2 qdata: 0 2 adj(J): J22 -J12 41288c0443SJeremy L Thompson // 1 3 2 1 -J21 J11 424d537eeaSYohann const CeedScalar J11 = J[i+Q*0]; 434d537eeaSYohann const CeedScalar J21 = J[i+Q*1]; 444d537eeaSYohann const CeedScalar J12 = J[i+Q*2]; 454d537eeaSYohann const CeedScalar J22 = J[i+Q*3]; 46a2fa7910SValeria Barra const CeedScalar qw = w[i] / (J11*J22 - J21*J12); 47a2fa7910SValeria Barra qdata[i+Q*0] = qw * (J12*J12 + J22*J22); 48a2fa7910SValeria Barra qdata[i+Q*1] = qw * (J11*J11 + J21*J21); 49a2fa7910SValeria Barra qdata[i+Q*2] = - qw * (J11*J12 + J21*J22); 504d537eeaSYohann } 514d537eeaSYohann break; 524d537eeaSYohann case 33: 53ee07ded2SValeria Barra // Quadrature Point Loop 54ee07ded2SValeria Barra CeedPragmaSIMD 554d537eeaSYohann for (CeedInt i=0; i<Q; i++) { 56a2fa7910SValeria Barra // J: 0 3 6 qdata: 0 5 4 57288c0443SJeremy L Thompson // 1 4 7 5 1 3 58288c0443SJeremy L Thompson // 2 5 8 4 3 2 594d537eeaSYohann const CeedScalar J11 = J[i+Q*0]; 604d537eeaSYohann const CeedScalar J21 = J[i+Q*1]; 614d537eeaSYohann const CeedScalar J31 = J[i+Q*2]; 624d537eeaSYohann const CeedScalar J12 = J[i+Q*3]; 634d537eeaSYohann const CeedScalar J22 = J[i+Q*4]; 644d537eeaSYohann const CeedScalar J32 = J[i+Q*5]; 654d537eeaSYohann const CeedScalar J13 = J[i+Q*6]; 664d537eeaSYohann const CeedScalar J23 = J[i+Q*7]; 674d537eeaSYohann const CeedScalar J33 = J[i+Q*8]; 684d537eeaSYohann const CeedScalar A11 = J22*J33 - J23*J32; 694d537eeaSYohann const CeedScalar A12 = J13*J32 - J12*J33; 704d537eeaSYohann const CeedScalar A13 = J12*J23 - J13*J22; 714d537eeaSYohann const CeedScalar A21 = J23*J31 - J21*J33; 724d537eeaSYohann const CeedScalar A22 = J11*J33 - J13*J31; 734d537eeaSYohann const CeedScalar A23 = J13*J21 - J11*J23; 744d537eeaSYohann const CeedScalar A31 = J21*J32 - J22*J31; 754d537eeaSYohann const CeedScalar A32 = J12*J31 - J11*J32; 764d537eeaSYohann const CeedScalar A33 = J11*J22 - J12*J21; 77a2fa7910SValeria Barra const CeedScalar qw = w[i] / (J11*A11 + J21*A12 + J31*A13); 78a2fa7910SValeria Barra qdata[i+Q*0] = qw * (A11*A11 + A12*A12 + A13*A13); 79a2fa7910SValeria Barra qdata[i+Q*1] = qw * (A21*A21 + A22*A22 + A23*A23); 80a2fa7910SValeria Barra qdata[i+Q*2] = qw * (A31*A31 + A32*A32 + A33*A33); 81a2fa7910SValeria Barra qdata[i+Q*3] = qw * (A21*A31 + A22*A32 + A23*A33); 82a2fa7910SValeria Barra qdata[i+Q*4] = qw * (A11*A31 + A12*A32 + A13*A33); 83a2fa7910SValeria Barra qdata[i+Q*5] = qw * (A11*A21 + A12*A22 + A13*A23); 844d537eeaSYohann } 854d537eeaSYohann break; 864d537eeaSYohann } 874d537eeaSYohann return 0; 884d537eeaSYohann } 894d537eeaSYohann 904d537eeaSYohann /// libCEED Q-function for applying a diff operator 914d537eeaSYohann CEED_QFUNCTION(f_apply_diff)(void *ctx, const CeedInt Q, 924d537eeaSYohann const CeedScalar *const *in, CeedScalar *const *out) { 934d537eeaSYohann BuildContext *bc = (BuildContext *)ctx; 944d537eeaSYohann // in[0], out[0] have shape [dim, nc=1, Q] 95a2fa7910SValeria Barra const CeedScalar *ug = in[0], *qdata = in[1]; 964d537eeaSYohann CeedScalar *vg = out[0]; 97ee07ded2SValeria Barra 984d537eeaSYohann switch (bc->dim) { 994d537eeaSYohann case 1: 100ee07ded2SValeria Barra // Quadrature Point Loop 101ee07ded2SValeria Barra CeedPragmaSIMD 1024d537eeaSYohann for (CeedInt i=0; i<Q; i++) { 103a2fa7910SValeria Barra vg[i] = ug[i] * qdata[i]; 1044d537eeaSYohann } 1054d537eeaSYohann break; 1064d537eeaSYohann case 2: 107ee07ded2SValeria Barra // Quadrature Point Loop 108ee07ded2SValeria Barra CeedPragmaSIMD 1094d537eeaSYohann for (CeedInt i=0; i<Q; i++) { 1104d537eeaSYohann const CeedScalar ug0 = ug[i+Q*0]; 1114d537eeaSYohann const CeedScalar ug1 = ug[i+Q*1]; 112a2fa7910SValeria Barra vg[i+Q*0] = qdata[i+Q*0]*ug0 + qdata[i+Q*2]*ug1; 113a2fa7910SValeria Barra vg[i+Q*1] = qdata[i+Q*2]*ug0 + qdata[i+Q*1]*ug1; 1144d537eeaSYohann } 1154d537eeaSYohann break; 1164d537eeaSYohann case 3: 117ee07ded2SValeria Barra // Quadrature Point Loop 118ee07ded2SValeria Barra CeedPragmaSIMD 1194d537eeaSYohann for (CeedInt i=0; i<Q; i++) { 1204d537eeaSYohann const CeedScalar ug0 = ug[i+Q*0]; 1214d537eeaSYohann const CeedScalar ug1 = ug[i+Q*1]; 1224d537eeaSYohann const CeedScalar ug2 = ug[i+Q*2]; 123a2fa7910SValeria Barra vg[i+Q*0] = qdata[i+Q*0]*ug0 + qdata[i+Q*5]*ug1 + qdata[i+Q*4]*ug2; 124a2fa7910SValeria Barra vg[i+Q*1] = qdata[i+Q*5]*ug0 + qdata[i+Q*1]*ug1 + qdata[i+Q*3]*ug2; 125a2fa7910SValeria Barra vg[i+Q*2] = qdata[i+Q*4]*ug0 + qdata[i+Q*3]*ug1 + qdata[i+Q*2]*ug2; 1264d537eeaSYohann } 1274d537eeaSYohann break; 1284d537eeaSYohann } 1294d537eeaSYohann return 0; 1304d537eeaSYohann } 131288c0443SJeremy L Thompson 132a57ca787Svaleriabarra #endif // bp3_h 133