xref: /libCEED/tests/t415-qfunction.c (revision 600b7929b98f3d8efad5f619bace308a359a46af)
1b249f0c7SJeremy L Thompson /// @file
2b249f0c7SJeremy L Thompson /// Test creation, evaluation, and destruction for vector Poisson QFunction by name
3b249f0c7SJeremy L Thompson /// \test Test creation, evaluation, and destruction for vector Poisson QFunction by name
4b249f0c7SJeremy L Thompson #include <ceed.h>
5b249f0c7SJeremy L Thompson #include <math.h>
6b249f0c7SJeremy L Thompson #include <string.h>
7b249f0c7SJeremy L Thompson 
8b249f0c7SJeremy L Thompson int main(int argc, char **argv) {
9b249f0c7SJeremy L Thompson   Ceed ceed;
10b249f0c7SJeremy L Thompson   CeedVector in[16], out[16];
11b249f0c7SJeremy L Thompson   CeedVector Q_data, J, W, dU, dV;
12b249f0c7SJeremy L Thompson   CeedQFunction qf_setup, qf_diff;
13b249f0c7SJeremy L Thompson   CeedInt Q = 8;
14b249f0c7SJeremy L Thompson   const CeedInt num_comp = 3;
15b249f0c7SJeremy L Thompson   const CeedScalar *vv;
16b249f0c7SJeremy L Thompson 
17b249f0c7SJeremy L Thompson   CeedInit(argv[1], &ceed);
18b249f0c7SJeremy L Thompson 
19b249f0c7SJeremy L Thompson   for (CeedInt dim = 1; dim <= 3; dim++) {
20b249f0c7SJeremy L Thompson     CeedInt num_qpts = CeedIntPow(Q, dim);
21b249f0c7SJeremy L Thompson     CeedScalar j[num_qpts * dim * dim], w[num_qpts],
22b249f0c7SJeremy L Thompson                du[num_qpts * dim * num_comp];
23b249f0c7SJeremy L Thompson 
24b249f0c7SJeremy L Thompson     char name_setup[26] = "", name_apply[26] = "";
25*600b7929SJeremy L Thompson     snprintf(name_setup, sizeof name_setup, "Poisson%" CeedInt_FMT "DBuild", dim);
26b249f0c7SJeremy L Thompson     CeedQFunctionCreateInteriorByName(ceed, name_setup, &qf_setup);
27*600b7929SJeremy L Thompson     snprintf(name_apply, sizeof name_apply, "Vector3Poisson%" CeedInt_FMT "DApply",
28*600b7929SJeremy L Thompson              dim);
29b249f0c7SJeremy L Thompson     CeedQFunctionCreateInteriorByName(ceed, name_apply, &qf_diff);
30b249f0c7SJeremy L Thompson 
31b249f0c7SJeremy L Thompson     for (CeedInt i=0; i<num_qpts; i++) {
32b249f0c7SJeremy L Thompson       w[i] = 1.0 / num_qpts;
33b249f0c7SJeremy L Thompson     }
34b249f0c7SJeremy L Thompson     for (CeedInt d=0; d<dim; d++) {
35b249f0c7SJeremy L Thompson       for (CeedInt g=0; g<dim; g++) {
36b249f0c7SJeremy L Thompson         for (CeedInt i=0; i<num_qpts; i++) {
37b249f0c7SJeremy L Thompson           j[i + (g * dim + d) * num_qpts] = d == g;
38b249f0c7SJeremy L Thompson         }
39b249f0c7SJeremy L Thompson       }
40b249f0c7SJeremy L Thompson     }
41b249f0c7SJeremy L Thompson     for (CeedInt c=0; c<num_comp; c++) {
42b249f0c7SJeremy L Thompson       for (CeedInt g=0; g<dim; g++) {
43b249f0c7SJeremy L Thompson         for (CeedInt i=0; i<num_qpts; i++) {
44b249f0c7SJeremy L Thompson           du[i + (g * num_comp + c) * num_qpts] = c + 1;
45b249f0c7SJeremy L Thompson         }
46b249f0c7SJeremy L Thompson       }
47b249f0c7SJeremy L Thompson     }
48b249f0c7SJeremy L Thompson 
49b249f0c7SJeremy L Thompson     CeedVectorCreate(ceed, num_qpts * dim * dim, &J);
50b249f0c7SJeremy L Thompson     CeedVectorSetArray(J, CEED_MEM_HOST, CEED_USE_POINTER, j);
51b249f0c7SJeremy L Thompson     CeedVectorCreate(ceed, num_qpts, &W);
52b249f0c7SJeremy L Thompson     CeedVectorSetArray(W, CEED_MEM_HOST, CEED_USE_POINTER, w);
53b249f0c7SJeremy L Thompson     CeedVectorCreate(ceed, num_qpts * dim * (dim + 1) / 2, &Q_data);
54b249f0c7SJeremy L Thompson     CeedVectorSetValue(Q_data, 0.0);
55b249f0c7SJeremy L Thompson     CeedVectorCreate(ceed, num_qpts * dim * num_comp, &dU);
56b249f0c7SJeremy L Thompson     CeedVectorSetArray(dU, CEED_MEM_HOST, CEED_USE_POINTER, du);
57b249f0c7SJeremy L Thompson     CeedVectorCreate(ceed, num_qpts * dim * num_comp, &dV);
58b249f0c7SJeremy L Thompson     CeedVectorSetValue(dV, 0.0);
59b249f0c7SJeremy L Thompson 
60b249f0c7SJeremy L Thompson     {
61b249f0c7SJeremy L Thompson       in[0] = J;
62b249f0c7SJeremy L Thompson       in[1] = W;
63b249f0c7SJeremy L Thompson       out[0] = Q_data;
64b249f0c7SJeremy L Thompson       CeedQFunctionApply(qf_setup, num_qpts, in, out);
65b249f0c7SJeremy L Thompson     }
66b249f0c7SJeremy L Thompson     {
67b249f0c7SJeremy L Thompson       in[0] = dU;
68b249f0c7SJeremy L Thompson       in[1] = Q_data;
69b249f0c7SJeremy L Thompson       out[0] = dV;
70b249f0c7SJeremy L Thompson       CeedQFunctionApply(qf_diff, num_qpts, in, out);
71b249f0c7SJeremy L Thompson     }
72b249f0c7SJeremy L Thompson 
73b249f0c7SJeremy L Thompson     CeedVectorGetArrayRead(dV, CEED_MEM_HOST, &vv);
74b249f0c7SJeremy L Thompson     for (CeedInt c=0; c<num_comp; c++) {
75b249f0c7SJeremy L Thompson       CeedScalar sum = 0;
76b249f0c7SJeremy L Thompson       for (CeedInt i=0; i<num_qpts; i++)
77b249f0c7SJeremy L Thompson         for (CeedInt g=0; g<dim; g++)
78b249f0c7SJeremy L Thompson           sum += vv[i + (g * num_comp + c) * num_qpts];
79b249f0c7SJeremy L Thompson       if (fabs(sum - dim * (c + 1)) > 10*CEED_EPSILON)
80b249f0c7SJeremy L Thompson         // LCOV_EXCL_START
81*600b7929SJeremy L Thompson         printf("%" CeedInt_FMT "D volume error in component %" CeedInt_FMT
82*600b7929SJeremy L Thompson                ": %f != %f\n", dim, c, sum, dim * (c + 1.0));
83b249f0c7SJeremy L Thompson       // LCOV_EXCL_STOP
84b249f0c7SJeremy L Thompson     }
85b249f0c7SJeremy L Thompson     CeedVectorRestoreArrayRead(dV, &vv);
86b249f0c7SJeremy L Thompson 
87b249f0c7SJeremy L Thompson     CeedVectorDestroy(&J);
88b249f0c7SJeremy L Thompson     CeedVectorDestroy(&W);
89b249f0c7SJeremy L Thompson     CeedVectorDestroy(&dU);
90b249f0c7SJeremy L Thompson     CeedVectorDestroy(&dV);
91b249f0c7SJeremy L Thompson     CeedVectorDestroy(&Q_data);
92b249f0c7SJeremy L Thompson     CeedQFunctionDestroy(&qf_setup);
93b249f0c7SJeremy L Thompson     CeedQFunctionDestroy(&qf_diff);
94b249f0c7SJeremy L Thompson   }
95b249f0c7SJeremy L Thompson 
96b249f0c7SJeremy L Thompson   CeedDestroy(&ceed);
97b249f0c7SJeremy L Thompson   return 0;
98b249f0c7SJeremy L Thompson }
99