xref: /libCEED/tests/t532-operator.h (revision 1d102b48beba01a4e67ef28409a80cc546ae2651)
1*1d102b48SJeremy L Thompson // Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC.
2*1d102b48SJeremy L Thompson // Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707.
3*1d102b48SJeremy L Thompson // All Rights reserved. See files LICENSE and NOTICE for details.
4*1d102b48SJeremy L Thompson //
5*1d102b48SJeremy L Thompson // This file is part of CEED, a collection of benchmarks, miniapps, software
6*1d102b48SJeremy L Thompson // libraries and APIs for efficient high-order finite element and spectral
7*1d102b48SJeremy L Thompson // element discretizations for exascale applications. For more information and
8*1d102b48SJeremy L Thompson // source code availability see http://github.com/ceed.
9*1d102b48SJeremy L Thompson //
10*1d102b48SJeremy L Thompson // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11*1d102b48SJeremy L Thompson // a collaborative effort of two U.S. Department of Energy organizations (Office
12*1d102b48SJeremy L Thompson // of Science and the National Nuclear Security Administration) responsible for
13*1d102b48SJeremy L Thompson // the planning and preparation of a capable exascale ecosystem, including
14*1d102b48SJeremy L Thompson // software, applications, hardware, advanced system engineering and early
15*1d102b48SJeremy L Thompson // testbed platforms, in support of the nation's exascale computing imperative.
16*1d102b48SJeremy L Thompson 
17*1d102b48SJeremy L Thompson CEED_QFUNCTION(setup_mass)(void *ctx, const CeedInt Q,
18*1d102b48SJeremy L Thompson                            const CeedScalar *const *in,
19*1d102b48SJeremy L Thompson                            CeedScalar *const *out) {
20*1d102b48SJeremy L Thompson   const CeedScalar *J = in[0], *weight = in[1];
21*1d102b48SJeremy L Thompson   CeedScalar *rho = out[0];
22*1d102b48SJeremy L Thompson   for (CeedInt i=0; i<Q; i++) {
23*1d102b48SJeremy L Thompson     rho[i] = weight[i] * (J[i+Q*0]*J[i+Q*3] - J[i+Q*1]*J[i+Q*2]);
24*1d102b48SJeremy L Thompson   }
25*1d102b48SJeremy L Thompson   return 0;
26*1d102b48SJeremy L Thompson }
27*1d102b48SJeremy L Thompson 
28*1d102b48SJeremy L Thompson CEED_QFUNCTION(setup_diff)(void *ctx, const CeedInt Q,
29*1d102b48SJeremy L Thompson                            const CeedScalar *const *in,
30*1d102b48SJeremy L Thompson                            CeedScalar *const *out) {
31*1d102b48SJeremy L Thompson   // At every quadrature point, compute qw/det(J).adj(J).adj(J)^T and store
32*1d102b48SJeremy L Thompson   // the symmetric part of the result.
33*1d102b48SJeremy L Thompson 
34*1d102b48SJeremy L Thompson   // in[0] is Jacobians with shape [2, nc=2, Q]
35*1d102b48SJeremy L Thompson   // in[1] is quadrature weights, size (Q)
36*1d102b48SJeremy L Thompson   const CeedScalar *J = in[0], *qw = in[1];
37*1d102b48SJeremy L Thompson 
38*1d102b48SJeremy L Thompson   // out[0] is qdata, size (Q)
39*1d102b48SJeremy L Thompson   CeedScalar *qd = out[0];
40*1d102b48SJeremy L Thompson 
41*1d102b48SJeremy L Thompson   // Quadrature point loop
42*1d102b48SJeremy L Thompson   for (CeedInt i=0; i<Q; i++) {
43*1d102b48SJeremy L Thompson     // J: 0 2   qd: 0 2   adj(J):  J22 -J12
44*1d102b48SJeremy L Thompson     //    1 3       2 1           -J21  J11
45*1d102b48SJeremy L Thompson     const CeedScalar J11 = J[i+Q*0];
46*1d102b48SJeremy L Thompson     const CeedScalar J21 = J[i+Q*1];
47*1d102b48SJeremy L Thompson     const CeedScalar J12 = J[i+Q*2];
48*1d102b48SJeremy L Thompson     const CeedScalar J22 = J[i+Q*3];
49*1d102b48SJeremy L Thompson     const CeedScalar w = qw[i] / (J11*J22 - J21*J12);
50*1d102b48SJeremy L Thompson     qd[i+Q*0] =   w * (J12*J12 + J22*J22);
51*1d102b48SJeremy L Thompson     qd[i+Q*1] =   w * (J11*J11 + J21*J21);
52*1d102b48SJeremy L Thompson     qd[i+Q*2] = - w * (J11*J12 + J21*J22);
53*1d102b48SJeremy L Thompson   }
54*1d102b48SJeremy L Thompson 
55*1d102b48SJeremy L Thompson   return 0;
56*1d102b48SJeremy L Thompson }
57*1d102b48SJeremy L Thompson 
58*1d102b48SJeremy L Thompson CEED_QFUNCTION(apply)(void *ctx, const CeedInt Q, const CeedScalar *const *in,
59*1d102b48SJeremy L Thompson                       CeedScalar *const *out) {
60*1d102b48SJeremy L Thompson   // in[0] is gradient u, shape [2, nc=1, Q]
61*1d102b48SJeremy L Thompson   // in[1] is mass quadrature data, size (Q)
62*1d102b48SJeremy L Thompson   // in[2] is Poisson quadrature data, size (Q)
63*1d102b48SJeremy L Thompson   // in[3] is u, size (Q)
64*1d102b48SJeremy L Thompson   const CeedScalar *du = in[0], *qd_mass = in[1], *qd_diff = in[2], *u = in[3];
65*1d102b48SJeremy L Thompson 
66*1d102b48SJeremy L Thompson   // out[0] is output to multiply against v, size (Q)
67*1d102b48SJeremy L Thompson   // out[1] is output to multiply against gradient v, shape [2, nc=1, Q]
68*1d102b48SJeremy L Thompson   CeedScalar *v = out[0], *dv = out[1];
69*1d102b48SJeremy L Thompson 
70*1d102b48SJeremy L Thompson   // Quadrature point loop
71*1d102b48SJeremy L Thompson   for (CeedInt i=0; i<Q; i++) {
72*1d102b48SJeremy L Thompson     // Mass
73*1d102b48SJeremy L Thompson     v[i] = qd_mass[i]*u[i];
74*1d102b48SJeremy L Thompson     // Diff
75*1d102b48SJeremy L Thompson     const CeedScalar du0 = du[i+Q*0];
76*1d102b48SJeremy L Thompson     const CeedScalar du1 = du[i+Q*1];
77*1d102b48SJeremy L Thompson     dv[i+Q*0] = qd_diff[i+Q*0]*du0 + qd_diff[i+Q*2]*du1;
78*1d102b48SJeremy L Thompson     dv[i+Q*1] = qd_diff[i+Q*2]*du0 + qd_diff[i+Q*1]*du1;
79*1d102b48SJeremy L Thompson   }
80*1d102b48SJeremy L Thompson 
81*1d102b48SJeremy L Thompson   return 0;
82*1d102b48SJeremy L Thompson }
83*1d102b48SJeremy L Thompson 
84*1d102b48SJeremy L Thompson CEED_QFUNCTION(apply_lin)(void *ctx, const CeedInt Q,
85*1d102b48SJeremy L Thompson                           const CeedScalar *const *in,
86*1d102b48SJeremy L Thompson                           CeedScalar *const *out) {
87*1d102b48SJeremy L Thompson   // in[0] is gradient u, shape [2, nc=1, Q]
88*1d102b48SJeremy L Thompson   // in[1] is mass quadrature data, size (9*Q)
89*1d102b48SJeremy L Thompson   // in[2] is u, size (Q)
90*1d102b48SJeremy L Thompson   const CeedScalar *du = in[0], *qd = in[1], *u = in[2];
91*1d102b48SJeremy L Thompson 
92*1d102b48SJeremy L Thompson   // out[0] is output to multiply against v, size (Q)
93*1d102b48SJeremy L Thompson   // out[1] is output to multiply against gradient v, shape [2, nc=1, Q]
94*1d102b48SJeremy L Thompson   CeedScalar *v = out[0], *dv = out[1];
95*1d102b48SJeremy L Thompson 
96*1d102b48SJeremy L Thompson   // Quadrature point loop
97*1d102b48SJeremy L Thompson   for (CeedInt i=0; i<Q; i++) {
98*1d102b48SJeremy L Thompson     const CeedScalar du0 = du[i+Q*0];
99*1d102b48SJeremy L Thompson     const CeedScalar du1 = du[i+Q*1];
100*1d102b48SJeremy L Thompson     v[i+Q*0] = qd[i+Q*0]*du0 + qd[i+Q*3]*du1 + qd[i+Q*6]*u[i];
101*1d102b48SJeremy L Thompson     dv[i+Q*0] = qd[i+Q*1]*du0 + qd[i+Q*4]*du1 + qd[i+Q*7]*u[i];
102*1d102b48SJeremy L Thompson     dv[i+Q*1] = qd[i+Q*2]*du0 + qd[i+Q*5]*du1 + qd[i+Q*8]*u[i];
103*1d102b48SJeremy L Thompson   }
104*1d102b48SJeremy L Thompson 
105*1d102b48SJeremy L Thompson   return 0;
106*1d102b48SJeremy L Thompson }
107