xref: /libCEED/examples/mfem/bp3.h (revision 2b730f8b5a9c809740a0b3b302db43a719c636b1)
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