xref: /libCEED/tests/t330-basis.h (revision 50c301a53d2cec48a2aa861bf6f38393f4831c2f)
1*50c301a5SRezgar Shakeri // Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC.
2*50c301a5SRezgar Shakeri // Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707.
3*50c301a5SRezgar Shakeri // All Rights reserved. See files LICENSE and NOTICE for details.
4*50c301a5SRezgar Shakeri //
5*50c301a5SRezgar Shakeri // This file is part of CEED, a collection of benchmarks, miniapps, software
6*50c301a5SRezgar Shakeri // libraries and APIs for efficient high-order finite element and spectral
7*50c301a5SRezgar Shakeri // element discretizations for exascale applications. For more information and
8*50c301a5SRezgar Shakeri // source code availability see http://github.com/ceed.
9*50c301a5SRezgar Shakeri //
10*50c301a5SRezgar Shakeri // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11*50c301a5SRezgar Shakeri // a collaborative effort of two U.S. Department of Energy organizations (Office
12*50c301a5SRezgar Shakeri // of Science and the National Nuclear Security Administration) responsible for
13*50c301a5SRezgar Shakeri // the planning and preparation of a capable exascale ecosystem, including
14*50c301a5SRezgar Shakeri // software, applications, hardware, advanced system engineering and early
15*50c301a5SRezgar Shakeri // testbed platforms, in support of the nation's exascale computing imperative.
16*50c301a5SRezgar Shakeri 
17*50c301a5SRezgar Shakeri // Hdiv basis for quadrilateral linear BDMelement in 2D
18*50c301a5SRezgar Shakeri // Local numbering is as follow (each edge has 2 vector dof)
19*50c301a5SRezgar Shakeri //     b4     b5
20*50c301a5SRezgar Shakeri //    2---------3
21*50c301a5SRezgar Shakeri //  b7|         |b3
22*50c301a5SRezgar Shakeri //    |         |
23*50c301a5SRezgar Shakeri //  b6|         |b2
24*50c301a5SRezgar Shakeri //    0---------1
25*50c301a5SRezgar Shakeri //     b0     b1
26*50c301a5SRezgar Shakeri // Bx[0-->7] = b0_x-->b7_x, By[0-->7] = b0_y-->b7_y
27*50c301a5SRezgar Shakeri // To see how the nodal basis is constructed visit:
28*50c301a5SRezgar Shakeri // https://github.com/rezgarshakeri/H-div-Tests
29*50c301a5SRezgar Shakeri int NodalHdivBasisQuad(CeedScalar *X, CeedScalar *Bx, CeedScalar *By) {
30*50c301a5SRezgar Shakeri   CeedScalar x_hat = X[0];
31*50c301a5SRezgar Shakeri   CeedScalar y_hat = X[1];
32*50c301a5SRezgar Shakeri   Bx[0] = -0.125 + 0.125*x_hat*x_hat;
33*50c301a5SRezgar Shakeri   By[0] = -0.25 + 0.25*x_hat + 0.25*y_hat + -0.25*x_hat*y_hat;
34*50c301a5SRezgar Shakeri   Bx[1] = 0.125 + -0.125*x_hat*x_hat;
35*50c301a5SRezgar Shakeri   By[1] = -0.25 + -0.25*x_hat + 0.25*y_hat + 0.25*x_hat*y_hat;
36*50c301a5SRezgar Shakeri   Bx[2] = 0.25 + 0.25*x_hat + -0.25*y_hat + -0.25*x_hat*y_hat;
37*50c301a5SRezgar Shakeri   By[2] = -0.125 + 0.125*y_hat*y_hat;
38*50c301a5SRezgar Shakeri   Bx[3] = 0.25 + 0.25*x_hat + 0.25*y_hat + 0.25*x_hat*y_hat;
39*50c301a5SRezgar Shakeri   By[3] = 0.125 + -0.125*y_hat*y_hat;
40*50c301a5SRezgar Shakeri   Bx[4] = -0.125 + 0.125*x_hat*x_hat;
41*50c301a5SRezgar Shakeri   By[4] = 0.25 + -0.25*x_hat + 0.25*y_hat + -0.25*x_hat*y_hat;
42*50c301a5SRezgar Shakeri   Bx[5] = 0.125 + -0.125*x_hat*x_hat;
43*50c301a5SRezgar Shakeri   By[5] = 0.25 + 0.25*x_hat + 0.25*y_hat + 0.25*x_hat*y_hat;
44*50c301a5SRezgar Shakeri   Bx[6] = -0.25 + 0.25*x_hat + 0.25*y_hat + -0.25*x_hat*y_hat;
45*50c301a5SRezgar Shakeri   By[6] = -0.125 + 0.125*y_hat*y_hat;
46*50c301a5SRezgar Shakeri   Bx[7] = -0.25 + 0.25*x_hat + -0.25*y_hat + 0.25*x_hat*y_hat;
47*50c301a5SRezgar Shakeri   By[7] = 0.125 + -0.125*y_hat*y_hat;
48*50c301a5SRezgar Shakeri   return 0;
49*50c301a5SRezgar Shakeri }
50*50c301a5SRezgar Shakeri static void HdivBasisQuad(CeedInt Q, CeedScalar *q_ref, CeedScalar *q_weights,
51*50c301a5SRezgar Shakeri                           CeedScalar *interp, CeedScalar *div, CeedQuadMode quad_mode) {
52*50c301a5SRezgar Shakeri 
53*50c301a5SRezgar Shakeri   // Get 1D quadrature on [-1,1]
54*50c301a5SRezgar Shakeri   CeedScalar q_ref_1d[Q], q_weight_1d[Q];
55*50c301a5SRezgar Shakeri   switch (quad_mode) {
56*50c301a5SRezgar Shakeri   case CEED_GAUSS:
57*50c301a5SRezgar Shakeri     CeedGaussQuadrature(Q, q_ref_1d, q_weight_1d);
58*50c301a5SRezgar Shakeri     break;
59*50c301a5SRezgar Shakeri   case CEED_GAUSS_LOBATTO:
60*50c301a5SRezgar Shakeri     CeedLobattoQuadrature(Q, q_ref_1d, q_weight_1d);
61*50c301a5SRezgar Shakeri     break;
62*50c301a5SRezgar Shakeri   }
63*50c301a5SRezgar Shakeri 
64*50c301a5SRezgar Shakeri   // Divergence operator; Divergence of nodal basis for ref element
65*50c301a5SRezgar Shakeri   CeedScalar D[8] = {0.25,0.25,0.25,0.25,0.25,0.25,0.25,0.25};
66*50c301a5SRezgar Shakeri   // Loop over quadrature points
67*50c301a5SRezgar Shakeri   CeedScalar Bx[8], By[8];
68*50c301a5SRezgar Shakeri   CeedScalar X[2];
69*50c301a5SRezgar Shakeri 
70*50c301a5SRezgar Shakeri   for (CeedInt i=0; i<Q; i++) {
71*50c301a5SRezgar Shakeri     for (CeedInt j=0; j<Q; j++) {
72*50c301a5SRezgar Shakeri       CeedInt k1 = Q*i+j;
73*50c301a5SRezgar Shakeri       q_ref[k1] = q_ref_1d[j];
74*50c301a5SRezgar Shakeri       q_ref[k1 + Q*Q] = q_ref_1d[i];
75*50c301a5SRezgar Shakeri       q_weights[k1] = q_weight_1d[j]*q_weight_1d[i];
76*50c301a5SRezgar Shakeri       X[0] = q_ref_1d[j];
77*50c301a5SRezgar Shakeri       X[1] = q_ref_1d[i];
78*50c301a5SRezgar Shakeri       NodalHdivBasisQuad(X, Bx, By);
79*50c301a5SRezgar Shakeri       for (CeedInt k=0; k<8; k++) {
80*50c301a5SRezgar Shakeri         interp[k1*8+k] = Bx[k];
81*50c301a5SRezgar Shakeri         interp[k1*8+k+8*Q*Q] = By[k];
82*50c301a5SRezgar Shakeri         div[k1*8+k] = D[k];
83*50c301a5SRezgar Shakeri       }
84*50c301a5SRezgar Shakeri     }
85*50c301a5SRezgar Shakeri   }
86*50c301a5SRezgar Shakeri }