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