xref: /libCEED/examples/mfem/bp3.h (revision ea61e9ac44808524e4667c1525a05976f536c19c)
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
142b730f8bSJeremy L Thompson struct BuildContext {
152b730f8bSJeremy L Thompson   CeedInt dim, space_dim;
162b730f8bSJeremy L Thompson };
174d537eeaSYohann 
184d537eeaSYohann /// libCEED Q-function for building quadrature data for a diffusion operator
192b730f8bSJeremy 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   //
24*ea61e9acSJeremy L Thompson   // At every quadrature point, compute w/det(J).adj(J).adj(J)^T and store 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
312b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { qdata[i] = w[i] / J[i]; }
324d537eeaSYohann       break;
334d537eeaSYohann     case 22:
34ee07ded2SValeria Barra       // Quadrature Point Loop
352b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
36a2fa7910SValeria Barra         // J: 0 2   qdata: 0 2   adj(J):  J22 -J12
37288c0443SJeremy L Thompson         //    1 3          2 1           -J21  J11
384d537eeaSYohann         const CeedScalar J11 = J[i + Q * 0];
394d537eeaSYohann         const CeedScalar J21 = J[i + Q * 1];
404d537eeaSYohann         const CeedScalar J12 = J[i + Q * 2];
414d537eeaSYohann         const CeedScalar J22 = J[i + Q * 3];
42a2fa7910SValeria Barra         const CeedScalar qw  = w[i] / (J11 * J22 - J21 * J12);
43a2fa7910SValeria Barra         qdata[i + Q * 0]     = qw * (J12 * J12 + J22 * J22);
44a2fa7910SValeria Barra         qdata[i + Q * 1]     = qw * (J11 * J11 + J21 * J21);
45a2fa7910SValeria Barra         qdata[i + Q * 2]     = -qw * (J11 * J12 + J21 * J22);
464d537eeaSYohann       }
474d537eeaSYohann       break;
484d537eeaSYohann     case 33:
49ee07ded2SValeria Barra       // Quadrature Point Loop
502b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
51a2fa7910SValeria Barra         // J: 0 3 6   qdata: 0 5 4
52288c0443SJeremy L Thompson         //    1 4 7          5 1 3
53288c0443SJeremy L Thompson         //    2 5 8          4 3 2
544d537eeaSYohann         const CeedScalar J11 = J[i + Q * 0];
554d537eeaSYohann         const CeedScalar J21 = J[i + Q * 1];
564d537eeaSYohann         const CeedScalar J31 = J[i + Q * 2];
574d537eeaSYohann         const CeedScalar J12 = J[i + Q * 3];
584d537eeaSYohann         const CeedScalar J22 = J[i + Q * 4];
594d537eeaSYohann         const CeedScalar J32 = J[i + Q * 5];
604d537eeaSYohann         const CeedScalar J13 = J[i + Q * 6];
614d537eeaSYohann         const CeedScalar J23 = J[i + Q * 7];
624d537eeaSYohann         const CeedScalar J33 = J[i + Q * 8];
634d537eeaSYohann         const CeedScalar A11 = J22 * J33 - J23 * J32;
644d537eeaSYohann         const CeedScalar A12 = J13 * J32 - J12 * J33;
654d537eeaSYohann         const CeedScalar A13 = J12 * J23 - J13 * J22;
664d537eeaSYohann         const CeedScalar A21 = J23 * J31 - J21 * J33;
674d537eeaSYohann         const CeedScalar A22 = J11 * J33 - J13 * J31;
684d537eeaSYohann         const CeedScalar A23 = J13 * J21 - J11 * J23;
694d537eeaSYohann         const CeedScalar A31 = J21 * J32 - J22 * J31;
704d537eeaSYohann         const CeedScalar A32 = J12 * J31 - J11 * J32;
714d537eeaSYohann         const CeedScalar A33 = J11 * J22 - J12 * J21;
72a2fa7910SValeria Barra         const CeedScalar qw  = w[i] / (J11 * A11 + J21 * A12 + J31 * A13);
73a2fa7910SValeria Barra         qdata[i + Q * 0]     = qw * (A11 * A11 + A12 * A12 + A13 * A13);
74a2fa7910SValeria Barra         qdata[i + Q * 1]     = qw * (A21 * A21 + A22 * A22 + A23 * A23);
75a2fa7910SValeria Barra         qdata[i + Q * 2]     = qw * (A31 * A31 + A32 * A32 + A33 * A33);
76a2fa7910SValeria Barra         qdata[i + Q * 3]     = qw * (A21 * A31 + A22 * A32 + A23 * A33);
77a2fa7910SValeria Barra         qdata[i + Q * 4]     = qw * (A11 * A31 + A12 * A32 + A13 * A33);
78a2fa7910SValeria Barra         qdata[i + Q * 5]     = qw * (A11 * A21 + A12 * A22 + A13 * A23);
794d537eeaSYohann       }
804d537eeaSYohann       break;
814d537eeaSYohann   }
824d537eeaSYohann   return 0;
834d537eeaSYohann }
844d537eeaSYohann 
854d537eeaSYohann /// libCEED Q-function for applying a diff operator
862b730f8bSJeremy L Thompson CEED_QFUNCTION(f_apply_diff)(void *ctx, const CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
874d537eeaSYohann   BuildContext *bc = (BuildContext *)ctx;
884d537eeaSYohann   // in[0], out[0] have shape [dim, nc=1, Q]
89a2fa7910SValeria Barra   const CeedScalar *ug = in[0], *qdata = in[1];
904d537eeaSYohann   CeedScalar       *vg = out[0];
91ee07ded2SValeria Barra 
924d537eeaSYohann   switch (bc->dim) {
934d537eeaSYohann     case 1:
94ee07ded2SValeria Barra       // Quadrature Point Loop
952b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { vg[i] = ug[i] * qdata[i]; }
964d537eeaSYohann       break;
974d537eeaSYohann     case 2:
98ee07ded2SValeria Barra       // Quadrature Point Loop
992b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
1004d537eeaSYohann         const CeedScalar ug0 = ug[i + Q * 0];
1014d537eeaSYohann         const CeedScalar ug1 = ug[i + Q * 1];
102a2fa7910SValeria Barra         vg[i + Q * 0]        = qdata[i + Q * 0] * ug0 + qdata[i + Q * 2] * ug1;
103a2fa7910SValeria Barra         vg[i + Q * 1]        = qdata[i + Q * 2] * ug0 + qdata[i + Q * 1] * ug1;
1044d537eeaSYohann       }
1054d537eeaSYohann       break;
1064d537eeaSYohann     case 3:
107ee07ded2SValeria Barra       // Quadrature Point Loop
1082b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
1094d537eeaSYohann         const CeedScalar ug0 = ug[i + Q * 0];
1104d537eeaSYohann         const CeedScalar ug1 = ug[i + Q * 1];
1114d537eeaSYohann         const CeedScalar ug2 = ug[i + Q * 2];
112a2fa7910SValeria Barra         vg[i + Q * 0]        = qdata[i + Q * 0] * ug0 + qdata[i + Q * 5] * ug1 + qdata[i + Q * 4] * ug2;
113a2fa7910SValeria Barra         vg[i + Q * 1]        = qdata[i + Q * 5] * ug0 + qdata[i + Q * 1] * ug1 + qdata[i + Q * 3] * ug2;
114a2fa7910SValeria Barra         vg[i + Q * 2]        = qdata[i + Q * 4] * ug0 + qdata[i + Q * 3] * ug1 + qdata[i + Q * 2] * ug2;
1154d537eeaSYohann       }
1164d537eeaSYohann       break;
1174d537eeaSYohann   }
1184d537eeaSYohann   return 0;
1194d537eeaSYohann }
120288c0443SJeremy L Thompson 
121a57ca787Svaleriabarra #endif  // bp3_h
122