xref: /libCEED/tests/t356-basis.c (revision edfbf3a6ecdc64ed3c23c2b517cc2ccd94396914)
1*edfbf3a6SJeremy L Thompson /// @file
2*edfbf3a6SJeremy L Thompson /// Test polynomial gradient to arbirtary points in multiple dimensions
3*edfbf3a6SJeremy L Thompson /// \test Test polynomial graient to arbitrary points in multiple dimensions
4*edfbf3a6SJeremy L Thompson #include <ceed.h>
5*edfbf3a6SJeremy L Thompson #include <math.h>
6*edfbf3a6SJeremy L Thompson #include <stdio.h>
7*edfbf3a6SJeremy L Thompson 
8*edfbf3a6SJeremy L Thompson static CeedScalar Eval(CeedInt dim, const CeedScalar x[]) {
9*edfbf3a6SJeremy L Thompson   CeedScalar result = 1, center = 0.1;
10*edfbf3a6SJeremy L Thompson   for (CeedInt d = 0; d < dim; d++) {
11*edfbf3a6SJeremy L Thompson     result *= tanh(x[d] - center);
12*edfbf3a6SJeremy L Thompson     center += 0.1;
13*edfbf3a6SJeremy L Thompson   }
14*edfbf3a6SJeremy L Thompson   return result;
15*edfbf3a6SJeremy L Thompson }
16*edfbf3a6SJeremy L Thompson 
17*edfbf3a6SJeremy L Thompson static CeedScalar EvalGrad(CeedInt dim, const CeedScalar x[], CeedInt direction) {
18*edfbf3a6SJeremy L Thompson   CeedScalar result = 1, center = 0.1;
19*edfbf3a6SJeremy L Thompson   for (CeedInt d = 0; d < dim; d++) {
20*edfbf3a6SJeremy L Thompson     if (d == direction) result *= 1.0 / cosh(x[d] - center) / cosh(x[d] - center);
21*edfbf3a6SJeremy L Thompson     else result *= tanh(x[d] - center);
22*edfbf3a6SJeremy L Thompson     center += 0.1;
23*edfbf3a6SJeremy L Thompson   }
24*edfbf3a6SJeremy L Thompson   return result;
25*edfbf3a6SJeremy L Thompson }
26*edfbf3a6SJeremy L Thompson 
27*edfbf3a6SJeremy L Thompson int main(int argc, char **argv) {
28*edfbf3a6SJeremy L Thompson   Ceed ceed;
29*edfbf3a6SJeremy L Thompson 
30*edfbf3a6SJeremy L Thompson   CeedInit(argv[1], &ceed);
31*edfbf3a6SJeremy L Thompson 
32*edfbf3a6SJeremy L Thompson   for (CeedInt dim = 1; dim <= 3; dim++) {
33*edfbf3a6SJeremy L Thompson     CeedVector    x, x_nodes, x_points, u, v;
34*edfbf3a6SJeremy L Thompson     CeedBasis     basis_x, basis_u;
35*edfbf3a6SJeremy L Thompson     const CeedInt p = 9, q = 9, num_points = 4, x_dim = CeedIntPow(2, dim), p_dim = CeedIntPow(p, dim);
36*edfbf3a6SJeremy L Thompson 
37*edfbf3a6SJeremy L Thompson     CeedVectorCreate(ceed, x_dim * dim, &x);
38*edfbf3a6SJeremy L Thompson     CeedVectorCreate(ceed, p_dim * dim, &x_nodes);
39*edfbf3a6SJeremy L Thompson     CeedVectorCreate(ceed, num_points * dim, &x_points);
40*edfbf3a6SJeremy L Thompson     CeedVectorCreate(ceed, p_dim, &u);
41*edfbf3a6SJeremy L Thompson     CeedVectorCreate(ceed, num_points * dim, &v);
42*edfbf3a6SJeremy L Thompson 
43*edfbf3a6SJeremy L Thompson     // Get nodal coordinates
44*edfbf3a6SJeremy L Thompson     CeedBasisCreateTensorH1Lagrange(ceed, dim, dim, 2, p, CEED_GAUSS_LOBATTO, &basis_x);
45*edfbf3a6SJeremy L Thompson     {
46*edfbf3a6SJeremy L Thompson       CeedScalar x_array[x_dim * dim];
47*edfbf3a6SJeremy L Thompson 
48*edfbf3a6SJeremy L Thompson       for (CeedInt d = 0; d < dim; d++) {
49*edfbf3a6SJeremy 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;
50*edfbf3a6SJeremy L Thompson       }
51*edfbf3a6SJeremy L Thompson       CeedVectorSetArray(x, CEED_MEM_HOST, CEED_COPY_VALUES, x_array);
52*edfbf3a6SJeremy L Thompson     }
53*edfbf3a6SJeremy L Thompson     CeedBasisApply(basis_x, 1, CEED_NOTRANSPOSE, CEED_EVAL_INTERP, x, x_nodes);
54*edfbf3a6SJeremy L Thompson 
55*edfbf3a6SJeremy L Thompson     // Set values of u at nodes
56*edfbf3a6SJeremy L Thompson     {
57*edfbf3a6SJeremy L Thompson       const CeedScalar *x_array;
58*edfbf3a6SJeremy L Thompson       CeedScalar        u_array[p_dim];
59*edfbf3a6SJeremy L Thompson 
60*edfbf3a6SJeremy L Thompson       CeedVectorGetArrayRead(x_nodes, CEED_MEM_HOST, &x_array);
61*edfbf3a6SJeremy L Thompson       for (CeedInt i = 0; i < p_dim; i++) {
62*edfbf3a6SJeremy L Thompson         CeedScalar coord[dim];
63*edfbf3a6SJeremy L Thompson 
64*edfbf3a6SJeremy L Thompson         for (CeedInt d = 0; d < dim; d++) coord[d] = x_array[d * p_dim + i];
65*edfbf3a6SJeremy L Thompson         u_array[i] = Eval(dim, coord);
66*edfbf3a6SJeremy L Thompson       }
67*edfbf3a6SJeremy L Thompson       CeedVectorRestoreArrayRead(x_nodes, &x_array);
68*edfbf3a6SJeremy L Thompson       CeedVectorSetArray(u, CEED_MEM_HOST, CEED_COPY_VALUES, (CeedScalar *)&u_array);
69*edfbf3a6SJeremy L Thompson     }
70*edfbf3a6SJeremy L Thompson 
71*edfbf3a6SJeremy L Thompson     // Interpolate to arbitrary points
72*edfbf3a6SJeremy L Thompson     CeedBasisCreateTensorH1Lagrange(ceed, dim, 1, p, q, CEED_GAUSS, &basis_u);
73*edfbf3a6SJeremy L Thompson     {
74*edfbf3a6SJeremy L Thompson       CeedScalar x_array[12] = {-0.33, -0.65, 0.16, 0.99, -0.65, 0.16, 0.99, -0.33, 0.16, 0.99, -0.33, -0.65};
75*edfbf3a6SJeremy L Thompson 
76*edfbf3a6SJeremy L Thompson       CeedVectorSetArray(x_points, CEED_MEM_HOST, CEED_COPY_VALUES, x_array);
77*edfbf3a6SJeremy L Thompson     }
78*edfbf3a6SJeremy L Thompson     CeedBasisApplyAtPoints(basis_u, num_points, CEED_NOTRANSPOSE, CEED_EVAL_GRAD, x_points, u, v);
79*edfbf3a6SJeremy L Thompson 
80*edfbf3a6SJeremy L Thompson     {
81*edfbf3a6SJeremy L Thompson       const CeedScalar *x_array, *v_array;
82*edfbf3a6SJeremy L Thompson 
83*edfbf3a6SJeremy L Thompson       CeedVectorGetArrayRead(x_points, CEED_MEM_HOST, &x_array);
84*edfbf3a6SJeremy L Thompson       CeedVectorGetArrayRead(v, CEED_MEM_HOST, &v_array);
85*edfbf3a6SJeremy L Thompson       for (CeedInt i = 0; i < num_points; i++) {
86*edfbf3a6SJeremy L Thompson         CeedScalar coord[dim];
87*edfbf3a6SJeremy L Thompson 
88*edfbf3a6SJeremy L Thompson         for (CeedInt d = 0; d < dim; d++) coord[d] = x_array[d + i * dim];
89*edfbf3a6SJeremy L Thompson         for (CeedInt d = 0; d < dim; d++) {
90*edfbf3a6SJeremy L Thompson           const CeedScalar dfx = EvalGrad(dim, coord, d);
91*edfbf3a6SJeremy L Thompson           if (fabs(v_array[i * dim + d] - dfx) > 1E-3) {
92*edfbf3a6SJeremy L Thompson             // LCOV_EXCL_START
93*edfbf3a6SJeremy L Thompson             printf("[%" CeedInt_FMT "] %f != %f = df(%f", dim, v_array[i * dim + d], dfx, coord[0]);
94*edfbf3a6SJeremy L Thompson             for (CeedInt d = 1; d < dim; d++) printf(", %f", coord[d]);
95*edfbf3a6SJeremy L Thompson             puts(")");
96*edfbf3a6SJeremy L Thompson             // LCOV_EXCL_STOP
97*edfbf3a6SJeremy L Thompson           }
98*edfbf3a6SJeremy L Thompson         }
99*edfbf3a6SJeremy L Thompson       }
100*edfbf3a6SJeremy L Thompson       CeedVectorRestoreArrayRead(x_points, &x_array);
101*edfbf3a6SJeremy L Thompson       CeedVectorRestoreArrayRead(v, &v_array);
102*edfbf3a6SJeremy L Thompson     }
103*edfbf3a6SJeremy L Thompson 
104*edfbf3a6SJeremy L Thompson     CeedVectorDestroy(&x);
105*edfbf3a6SJeremy L Thompson     CeedVectorDestroy(&x_nodes);
106*edfbf3a6SJeremy L Thompson     CeedVectorDestroy(&x_points);
107*edfbf3a6SJeremy L Thompson     CeedVectorDestroy(&u);
108*edfbf3a6SJeremy L Thompson     CeedVectorDestroy(&v);
109*edfbf3a6SJeremy L Thompson     CeedBasisDestroy(&basis_x);
110*edfbf3a6SJeremy L Thompson     CeedBasisDestroy(&basis_u);
111*edfbf3a6SJeremy L Thompson   }
112*edfbf3a6SJeremy L Thompson 
113*edfbf3a6SJeremy L Thompson   CeedDestroy(&ceed);
114*edfbf3a6SJeremy L Thompson   return 0;
115*edfbf3a6SJeremy L Thompson }
116