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 11c9c2c079SJeremy L Thompson #include <ceed.h> 12c9c2c079SJeremy L Thompson 134d537eeaSYohann /// A structure used to pass additional data to f_build_diff and f_apply_diff 14*2b730f8bSJeremy L Thompson struct BuildContext { 15*2b730f8bSJeremy L Thompson CeedInt dim, space_dim; 16*2b730f8bSJeremy L Thompson }; 174d537eeaSYohann 184d537eeaSYohann /// libCEED Q-function for building quadrature data for a diffusion operator 19*2b730f8bSJeremy L Thompson CEED_QFUNCTION(f_build_diff)(void *ctx, const CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 204d537eeaSYohann BuildContext *bc = (BuildContext *)ctx; 214d537eeaSYohann // in[0] is Jacobians with shape [dim, nc=dim, Q] 224d537eeaSYohann // in[1] is quadrature weights, size (Q) 234d537eeaSYohann // 24a2fa7910SValeria Barra // At every quadrature point, compute w/det(J).adj(J).adj(J)^T and store 254d537eeaSYohann // the symmetric part of the result. 26a2fa7910SValeria Barra const CeedScalar *J = in[0], *w = in[1]; 27a2fa7910SValeria Barra CeedScalar *qdata = out[0]; 28ee07ded2SValeria Barra 294d537eeaSYohann switch (bc->dim + 10 * bc->space_dim) { 304d537eeaSYohann case 11: 31ee07ded2SValeria Barra // Quadrature Point Loop 32*2b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { qdata[i] = w[i] / J[i]; } 334d537eeaSYohann break; 344d537eeaSYohann case 22: 35ee07ded2SValeria Barra // Quadrature Point Loop 36*2b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 37a2fa7910SValeria Barra // J: 0 2 qdata: 0 2 adj(J): J22 -J12 38288c0443SJeremy L Thompson // 1 3 2 1 -J21 J11 394d537eeaSYohann const CeedScalar J11 = J[i + Q * 0]; 404d537eeaSYohann const CeedScalar J21 = J[i + Q * 1]; 414d537eeaSYohann const CeedScalar J12 = J[i + Q * 2]; 424d537eeaSYohann const CeedScalar J22 = J[i + Q * 3]; 43a2fa7910SValeria Barra const CeedScalar qw = w[i] / (J11 * J22 - J21 * J12); 44a2fa7910SValeria Barra qdata[i + Q * 0] = qw * (J12 * J12 + J22 * J22); 45a2fa7910SValeria Barra qdata[i + Q * 1] = qw * (J11 * J11 + J21 * J21); 46a2fa7910SValeria Barra qdata[i + Q * 2] = -qw * (J11 * J12 + J21 * J22); 474d537eeaSYohann } 484d537eeaSYohann break; 494d537eeaSYohann case 33: 50ee07ded2SValeria Barra // Quadrature Point Loop 51*2b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 52a2fa7910SValeria Barra // J: 0 3 6 qdata: 0 5 4 53288c0443SJeremy L Thompson // 1 4 7 5 1 3 54288c0443SJeremy L Thompson // 2 5 8 4 3 2 554d537eeaSYohann const CeedScalar J11 = J[i + Q * 0]; 564d537eeaSYohann const CeedScalar J21 = J[i + Q * 1]; 574d537eeaSYohann const CeedScalar J31 = J[i + Q * 2]; 584d537eeaSYohann const CeedScalar J12 = J[i + Q * 3]; 594d537eeaSYohann const CeedScalar J22 = J[i + Q * 4]; 604d537eeaSYohann const CeedScalar J32 = J[i + Q * 5]; 614d537eeaSYohann const CeedScalar J13 = J[i + Q * 6]; 624d537eeaSYohann const CeedScalar J23 = J[i + Q * 7]; 634d537eeaSYohann const CeedScalar J33 = J[i + Q * 8]; 644d537eeaSYohann const CeedScalar A11 = J22 * J33 - J23 * J32; 654d537eeaSYohann const CeedScalar A12 = J13 * J32 - J12 * J33; 664d537eeaSYohann const CeedScalar A13 = J12 * J23 - J13 * J22; 674d537eeaSYohann const CeedScalar A21 = J23 * J31 - J21 * J33; 684d537eeaSYohann const CeedScalar A22 = J11 * J33 - J13 * J31; 694d537eeaSYohann const CeedScalar A23 = J13 * J21 - J11 * J23; 704d537eeaSYohann const CeedScalar A31 = J21 * J32 - J22 * J31; 714d537eeaSYohann const CeedScalar A32 = J12 * J31 - J11 * J32; 724d537eeaSYohann const CeedScalar A33 = J11 * J22 - J12 * J21; 73a2fa7910SValeria Barra const CeedScalar qw = w[i] / (J11 * A11 + J21 * A12 + J31 * A13); 74a2fa7910SValeria Barra qdata[i + Q * 0] = qw * (A11 * A11 + A12 * A12 + A13 * A13); 75a2fa7910SValeria Barra qdata[i + Q * 1] = qw * (A21 * A21 + A22 * A22 + A23 * A23); 76a2fa7910SValeria Barra qdata[i + Q * 2] = qw * (A31 * A31 + A32 * A32 + A33 * A33); 77a2fa7910SValeria Barra qdata[i + Q * 3] = qw * (A21 * A31 + A22 * A32 + A23 * A33); 78a2fa7910SValeria Barra qdata[i + Q * 4] = qw * (A11 * A31 + A12 * A32 + A13 * A33); 79a2fa7910SValeria Barra qdata[i + Q * 5] = qw * (A11 * A21 + A12 * A22 + A13 * A23); 804d537eeaSYohann } 814d537eeaSYohann break; 824d537eeaSYohann } 834d537eeaSYohann return 0; 844d537eeaSYohann } 854d537eeaSYohann 864d537eeaSYohann /// libCEED Q-function for applying a diff operator 87*2b730f8bSJeremy L Thompson CEED_QFUNCTION(f_apply_diff)(void *ctx, const CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 884d537eeaSYohann BuildContext *bc = (BuildContext *)ctx; 894d537eeaSYohann // in[0], out[0] have shape [dim, nc=1, Q] 90a2fa7910SValeria Barra const CeedScalar *ug = in[0], *qdata = in[1]; 914d537eeaSYohann CeedScalar *vg = out[0]; 92ee07ded2SValeria Barra 934d537eeaSYohann switch (bc->dim) { 944d537eeaSYohann case 1: 95ee07ded2SValeria Barra // Quadrature Point Loop 96*2b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { vg[i] = ug[i] * qdata[i]; } 974d537eeaSYohann break; 984d537eeaSYohann case 2: 99ee07ded2SValeria Barra // Quadrature Point Loop 100*2b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 1014d537eeaSYohann const CeedScalar ug0 = ug[i + Q * 0]; 1024d537eeaSYohann const CeedScalar ug1 = ug[i + Q * 1]; 103a2fa7910SValeria Barra vg[i + Q * 0] = qdata[i + Q * 0] * ug0 + qdata[i + Q * 2] * ug1; 104a2fa7910SValeria Barra vg[i + Q * 1] = qdata[i + Q * 2] * ug0 + qdata[i + Q * 1] * ug1; 1054d537eeaSYohann } 1064d537eeaSYohann break; 1074d537eeaSYohann case 3: 108ee07ded2SValeria Barra // Quadrature Point Loop 109*2b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 1104d537eeaSYohann const CeedScalar ug0 = ug[i + Q * 0]; 1114d537eeaSYohann const CeedScalar ug1 = ug[i + Q * 1]; 1124d537eeaSYohann const CeedScalar ug2 = ug[i + Q * 2]; 113a2fa7910SValeria Barra vg[i + Q * 0] = qdata[i + Q * 0] * ug0 + qdata[i + Q * 5] * ug1 + qdata[i + Q * 4] * ug2; 114a2fa7910SValeria Barra vg[i + Q * 1] = qdata[i + Q * 5] * ug0 + qdata[i + Q * 1] * ug1 + qdata[i + Q * 3] * ug2; 115a2fa7910SValeria Barra vg[i + Q * 2] = qdata[i + Q * 4] * ug0 + qdata[i + Q * 3] * ug1 + qdata[i + Q * 2] * ug2; 1164d537eeaSYohann } 1174d537eeaSYohann break; 1184d537eeaSYohann } 1194d537eeaSYohann return 0; 1204d537eeaSYohann } 121288c0443SJeremy L Thompson 122a57ca787Svaleriabarra #endif // bp3_h 123