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