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