xref: /libCEED/tests/t541-operator.h (revision 15ed3f7d2aab6752fefb2179d6eb9b13e01d2e9d)
1*15ed3f7dSjeremylt // Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC.
2*15ed3f7dSjeremylt // Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707.
3*15ed3f7dSjeremylt // All Rights reserved. See files LICENSE and NOTICE for details.
4*15ed3f7dSjeremylt //
5*15ed3f7dSjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software
6*15ed3f7dSjeremylt // libraries and APIs for efficient high-order finite element and spectral
7*15ed3f7dSjeremylt // element discretizations for exascale applications. For more information and
8*15ed3f7dSjeremylt // source code availability see http://github.com/ceed.
9*15ed3f7dSjeremylt //
10*15ed3f7dSjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11*15ed3f7dSjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office
12*15ed3f7dSjeremylt // of Science and the National Nuclear Security Administration) responsible for
13*15ed3f7dSjeremylt // the planning and preparation of a capable exascale ecosystem, including
14*15ed3f7dSjeremylt // software, applications, hardware, advanced system engineering and early
15*15ed3f7dSjeremylt // testbed platforms, in support of the nation's exascale computing imperative.
16*15ed3f7dSjeremylt 
17*15ed3f7dSjeremylt CEED_QFUNCTION(setup_diff)(void *ctx, const CeedInt Q,
18*15ed3f7dSjeremylt                            const CeedScalar *const *in,
19*15ed3f7dSjeremylt                            CeedScalar *const *out) {
20*15ed3f7dSjeremylt   // in[0] is Jacobians with shape [2, nc=2, Q]
21*15ed3f7dSjeremylt   // in[1] is quadrature weights, size (Q)
22*15ed3f7dSjeremylt   const CeedScalar *J = in[0], *w = in[1];
23*15ed3f7dSjeremylt 
24*15ed3f7dSjeremylt   // out[0] is qdata, size (Q)
25*15ed3f7dSjeremylt   CeedScalar *q_data = out[0];
26*15ed3f7dSjeremylt 
27*15ed3f7dSjeremylt   // Quadrature point loop
28*15ed3f7dSjeremylt   CeedPragmaSIMD
29*15ed3f7dSjeremylt   for (CeedInt i=0; i<Q; i++) {
30*15ed3f7dSjeremylt     // Qdata stored in Voigt convention
31*15ed3f7dSjeremylt     // J: 0 2   q_data: 0 2   adj(J):  J22 -J12
32*15ed3f7dSjeremylt     //    1 3           2 1           -J21  J11
33*15ed3f7dSjeremylt     const CeedScalar J11 = J[i+Q*0];
34*15ed3f7dSjeremylt     const CeedScalar J21 = J[i+Q*1];
35*15ed3f7dSjeremylt     const CeedScalar J12 = J[i+Q*2];
36*15ed3f7dSjeremylt     const CeedScalar J22 = J[i+Q*3];
37*15ed3f7dSjeremylt     const CeedScalar qw = w[i] / (J11*J22 - J21*J12);
38*15ed3f7dSjeremylt     q_data[i+Q*0] =   qw * (J12*J12 + J22*J22);
39*15ed3f7dSjeremylt     q_data[i+Q*1] =   qw * (J11*J11 + J21*J21);
40*15ed3f7dSjeremylt     q_data[i+Q*2] = - qw * (J11*J12 + J21*J22);
41*15ed3f7dSjeremylt   } // End of Quadrature Point Loop
42*15ed3f7dSjeremylt   return 0;
43*15ed3f7dSjeremylt }
44*15ed3f7dSjeremylt 
45*15ed3f7dSjeremylt CEED_QFUNCTION(apply)(void *ctx, const CeedInt Q, const CeedScalar *const *in,
46*15ed3f7dSjeremylt                       CeedScalar *const *out) {
47*15ed3f7dSjeremylt   // in[0] is gradient u, shape [2, nc=1, Q]
48*15ed3f7dSjeremylt   // in[1] is quadrature data, size (3*Q)
49*15ed3f7dSjeremylt   const CeedScalar *ug = in[0], *q_data = in[1];
50*15ed3f7dSjeremylt 
51*15ed3f7dSjeremylt   // out[0] is output to multiply against gradient v, shape [2, nc=1, Q]
52*15ed3f7dSjeremylt   CeedScalar *vg = out[0];
53*15ed3f7dSjeremylt 
54*15ed3f7dSjeremylt   // Quadrature point loop
55*15ed3f7dSjeremylt   CeedPragmaSIMD
56*15ed3f7dSjeremylt   for (CeedInt i=0; i<Q; i++) {
57*15ed3f7dSjeremylt     // Read spatial derivatives of u
58*15ed3f7dSjeremylt     const CeedScalar du[2]        =  {ug[i+Q*0],
59*15ed3f7dSjeremylt                                       ug[i+Q*1]
60*15ed3f7dSjeremylt                                      };
61*15ed3f7dSjeremylt 
62*15ed3f7dSjeremylt     // Read qdata (dXdxdXdxT symmetric matrix)
63*15ed3f7dSjeremylt     // Stored in Voigt convention
64*15ed3f7dSjeremylt     // 0 2
65*15ed3f7dSjeremylt     // 2 1
66*15ed3f7dSjeremylt     // *INDENT-OFF*
67*15ed3f7dSjeremylt     const CeedScalar dXdxdXdxT[2][2] = {{q_data[i+0*Q],
68*15ed3f7dSjeremylt                                          q_data[i+2*Q]},
69*15ed3f7dSjeremylt                                         {q_data[i+2*Q],
70*15ed3f7dSjeremylt                                          q_data[i+1*Q]}
71*15ed3f7dSjeremylt                                        };
72*15ed3f7dSjeremylt     // *INDENT-ON*
73*15ed3f7dSjeremylt 
74*15ed3f7dSjeremylt     // Apply Poisson operator
75*15ed3f7dSjeremylt     // j = direction of vg
76*15ed3f7dSjeremylt     for (int j=0; j<2; j++)
77*15ed3f7dSjeremylt       vg[i+j*Q] = (du[0] * dXdxdXdxT[0][j] +
78*15ed3f7dSjeremylt                    du[1] * dXdxdXdxT[1][j]);
79*15ed3f7dSjeremylt   } // End of Quadrature Point Loop
80*15ed3f7dSjeremylt 
81*15ed3f7dSjeremylt   return 0;
82*15ed3f7dSjeremylt }
83