xref: /libCEED/tests/t315-basis.c (revision 4fee36f0a30516a0b5ad51bf7eb3b32d83efd623)
152bfb9bbSJeremy L Thompson /// @file
252bfb9bbSJeremy L Thompson /// Test collocated grad in multiple dimensions
352bfb9bbSJeremy L Thompson /// \test Test collocated grad in multiple dimensions
452bfb9bbSJeremy L Thompson #include <ceed.h>
552bfb9bbSJeremy L Thompson #include <math.h>
652bfb9bbSJeremy L Thompson 
752bfb9bbSJeremy L Thompson static CeedScalar Eval(CeedInt dim, const CeedScalar x[]) {
852bfb9bbSJeremy L Thompson   CeedScalar result = tanh(x[0] + 0.1);
952bfb9bbSJeremy L Thompson   if (dim > 1) result += atan(x[1] + 0.2);
1052bfb9bbSJeremy L Thompson   if (dim > 2) result += exp(-(x[2] + 0.3) * (x[2] + 0.3));
1152bfb9bbSJeremy L Thompson   return result;
1252bfb9bbSJeremy L Thompson }
1352bfb9bbSJeremy L Thompson 
1480a9ef05SNatalie Beams static CeedScalar GetTolerance(CeedScalarType scalar_type, int dim) {
1580a9ef05SNatalie Beams   CeedScalar tol;
1680a9ef05SNatalie Beams   if (scalar_type == CEED_SCALAR_FP32) {
172b730f8bSJeremy L Thompson     if (dim == 3) tol = 1.e-3;
182b730f8bSJeremy L Thompson     else tol = 1.e-4;
1980a9ef05SNatalie Beams   } else {
2080a9ef05SNatalie Beams     tol = 1.e-11;
2180a9ef05SNatalie Beams   }
2280a9ef05SNatalie Beams   return tol;
2380a9ef05SNatalie Beams }
2480a9ef05SNatalie Beams 
2552bfb9bbSJeremy L Thompson int main(int argc, char **argv) {
2652bfb9bbSJeremy L Thompson   Ceed ceed;
2752bfb9bbSJeremy L Thompson 
2852bfb9bbSJeremy L Thompson   CeedInit(argv[1], &ceed);
2952bfb9bbSJeremy L Thompson 
3052bfb9bbSJeremy L Thompson   for (CeedInt dim = 1; dim <= 3; dim++) {
31*4fee36f0SJeremy L Thompson     CeedVector x, x_q, u, u_q, ones, v;
32d1d35e2fSjeremylt     CeedBasis  basis_x_lobatto, basis_u_gauss;
33*4fee36f0SJeremy L Thompson     CeedInt    p = 8, q = 8, p_dim = CeedIntPow(p, dim), q_dim = CeedIntPow(q, dim), x_dim = CeedIntPow(2, dim);
34d1d35e2fSjeremylt     CeedScalar sum_1 = 0, sum_2 = 0;
3552bfb9bbSJeremy L Thompson 
36*4fee36f0SJeremy L Thompson     CeedVectorCreate(ceed, x_dim * dim, &x);
37*4fee36f0SJeremy L Thompson     {
38*4fee36f0SJeremy L Thompson       CeedScalar x_array[x_dim * dim];
3952bfb9bbSJeremy L Thompson 
40*4fee36f0SJeremy L Thompson       for (CeedInt d = 0; d < dim; d++) {
41*4fee36f0SJeremy L Thompson         for (CeedInt i = 0; i < x_dim; i++) x_array[d * x_dim + i] = (i % CeedIntPow(2, dim - d)) / CeedIntPow(2, dim - d - 1) ? 1 : -1;
42*4fee36f0SJeremy L Thompson       }
43*4fee36f0SJeremy L Thompson       CeedVectorSetArray(x, CEED_MEM_HOST, CEED_COPY_VALUES, x_array);
44*4fee36f0SJeremy L Thompson     }
45*4fee36f0SJeremy L Thompson     CeedVectorCreate(ceed, p_dim * dim, &x_q);
46*4fee36f0SJeremy L Thompson     CeedVectorSetValue(x_q, 0);
47*4fee36f0SJeremy L Thompson     CeedVectorCreate(ceed, p_dim, &u);
48*4fee36f0SJeremy L Thompson     CeedVectorCreate(ceed, q_dim * dim, &u_q);
49*4fee36f0SJeremy L Thompson     CeedVectorSetValue(u_q, 0);
50*4fee36f0SJeremy L Thompson     CeedVectorCreate(ceed, q_dim * dim, &ones);
51d1d35e2fSjeremylt     CeedVectorSetValue(ones, 1);
52*4fee36f0SJeremy L Thompson     CeedVectorCreate(ceed, p_dim, &v);
53*4fee36f0SJeremy L Thompson     CeedVectorSetValue(v, 0);
5452bfb9bbSJeremy L Thompson 
5552bfb9bbSJeremy L Thompson     // Get function values at quadrature points
56*4fee36f0SJeremy L Thompson     CeedBasisCreateTensorH1Lagrange(ceed, dim, dim, 2, p, CEED_GAUSS_LOBATTO, &basis_x_lobatto);
57*4fee36f0SJeremy L Thompson     CeedBasisApply(basis_x_lobatto, 1, CEED_NOTRANSPOSE, CEED_EVAL_INTERP, x, x_q);
5852bfb9bbSJeremy L Thompson 
59*4fee36f0SJeremy L Thompson     {
60*4fee36f0SJeremy L Thompson       const CeedScalar *x_q_array;
61*4fee36f0SJeremy L Thompson       CeedScalar        u_array[p_dim];
62*4fee36f0SJeremy L Thompson 
63*4fee36f0SJeremy L Thompson       CeedVectorGetArrayRead(x_q, CEED_MEM_HOST, &x_q_array);
64*4fee36f0SJeremy L Thompson       for (CeedInt i = 0; i < p_dim; i++) {
65*4fee36f0SJeremy L Thompson         CeedScalar coord[dim];
66*4fee36f0SJeremy L Thompson         for (CeedInt d = 0; d < dim; d++) coord[d] = x_q_array[d * p_dim + i];
67*4fee36f0SJeremy L Thompson         u_array[i] = Eval(dim, coord);
6852bfb9bbSJeremy L Thompson       }
69*4fee36f0SJeremy L Thompson       CeedVectorRestoreArrayRead(x_q, &x_q_array);
70*4fee36f0SJeremy L Thompson       CeedVectorSetArray(u, CEED_MEM_HOST, CEED_COPY_VALUES, u_array);
71*4fee36f0SJeremy L Thompson     }
7252bfb9bbSJeremy L Thompson 
7352bfb9bbSJeremy L Thompson     // Calculate G u at quadrature points, G' * 1 at dofs
74*4fee36f0SJeremy L Thompson     CeedBasisCreateTensorH1Lagrange(ceed, dim, 1, p, q, CEED_GAUSS_LOBATTO, &basis_u_gauss);
75*4fee36f0SJeremy L Thompson     CeedBasisApply(basis_u_gauss, 1, CEED_NOTRANSPOSE, CEED_EVAL_GRAD, u, u_q);
76*4fee36f0SJeremy L Thompson     CeedBasisApply(basis_u_gauss, 1, CEED_TRANSPOSE, CEED_EVAL_GRAD, ones, v);
7752bfb9bbSJeremy L Thompson 
7852bfb9bbSJeremy L Thompson     // Check if 1' * G * u = u' * (G' * 1)
79*4fee36f0SJeremy L Thompson     {
80*4fee36f0SJeremy L Thompson       const CeedScalar *u_array, *v_array, *u_q_array;
81*4fee36f0SJeremy L Thompson 
82*4fee36f0SJeremy L Thompson       CeedVectorGetArrayRead(u, CEED_MEM_HOST, &u_array);
83*4fee36f0SJeremy L Thompson       CeedVectorGetArrayRead(v, CEED_MEM_HOST, &v_array);
84*4fee36f0SJeremy L Thompson       CeedVectorGetArrayRead(u_q, CEED_MEM_HOST, &u_q_array);
85*4fee36f0SJeremy L Thompson       for (CeedInt i = 0; i < p_dim; i++) sum_1 += v_array[i] * u_array[i];
86*4fee36f0SJeremy L Thompson       for (CeedInt i = 0; i < dim * q_dim; i++) sum_2 += u_q_array[i];
87*4fee36f0SJeremy L Thompson       CeedVectorRestoreArrayRead(u, &u_array);
88*4fee36f0SJeremy L Thompson       CeedVectorRestoreArrayRead(v, &v_array);
89*4fee36f0SJeremy L Thompson       CeedVectorRestoreArrayRead(u_q, &u_q_array);
90*4fee36f0SJeremy L Thompson     }
9180a9ef05SNatalie Beams     CeedScalar tol = GetTolerance(CEED_SCALAR_TYPE, dim);
922b730f8bSJeremy L Thompson     if (fabs(sum_1 - sum_2) > tol) printf("[%" CeedInt_FMT "] %f != %f\n", dim, sum_1, sum_2);
9352bfb9bbSJeremy L Thompson 
94*4fee36f0SJeremy L Thompson     CeedVectorDestroy(&x);
95*4fee36f0SJeremy L Thompson     CeedVectorDestroy(&x_q);
96*4fee36f0SJeremy L Thompson     CeedVectorDestroy(&u);
97*4fee36f0SJeremy L Thompson     CeedVectorDestroy(&u_q);
98d1d35e2fSjeremylt     CeedVectorDestroy(&ones);
99*4fee36f0SJeremy L Thompson     CeedVectorDestroy(&v);
100d1d35e2fSjeremylt     CeedBasisDestroy(&basis_x_lobatto);
101d1d35e2fSjeremylt     CeedBasisDestroy(&basis_u_gauss);
10252bfb9bbSJeremy L Thompson   }
10352bfb9bbSJeremy L Thompson   CeedDestroy(&ceed);
10452bfb9bbSJeremy L Thompson   return 0;
10552bfb9bbSJeremy L Thompson }
106