xref: /libCEED/tests/t414-qfunction.c (revision daadeac6547c0bce0e170b8a41c931051f52e9a3)
1 /// @file
2 /// Test creation, evaluation, and destruction for vector mass QFunction by name
3 /// \test Test creation, evaluation, and destruction for vector mass 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, U, V;
12   CeedQFunction     qf_setup, qf_mass;
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 = 2; dim <= 3; dim++) {
20     CeedInt    num_qpts = CeedIntPow(Q, dim);
21     CeedScalar j[num_qpts * dim * dim], w[num_qpts], u[num_qpts * num_comp];
22 
23     char name[13] = "";
24     snprintf(name, sizeof name, "Mass%" CeedInt_FMT "DBuild", dim);
25     CeedQFunctionCreateInteriorByName(ceed, name, &qf_setup);
26     CeedQFunctionCreateInteriorByName(ceed, "Vector3MassApply", &qf_mass);
27 
28     for (CeedInt i = 0; i < num_qpts; i++) {
29       w[i] = 1.0 / num_qpts;
30     }
31     for (CeedInt d = 0; d < dim; d++) {
32       for (CeedInt g = 0; g < dim; g++) {
33         for (CeedInt i = 0; i < num_qpts; i++) {
34           j[i + (g * dim + d) * num_qpts] = d == g;
35         }
36       }
37     }
38     for (CeedInt c = 0; c < num_comp; c++) {
39       for (CeedInt i = 0; i < num_qpts; i++) {
40         u[i + c * num_qpts] = c + 1;
41       }
42     }
43 
44     CeedVectorCreate(ceed, num_qpts * dim * dim, &J);
45     CeedVectorSetArray(J, CEED_MEM_HOST, CEED_USE_POINTER, j);
46     CeedVectorCreate(ceed, num_qpts, &W);
47     CeedVectorSetArray(W, CEED_MEM_HOST, CEED_USE_POINTER, w);
48     CeedVectorCreate(ceed, num_qpts, &Q_data);
49     CeedVectorSetValue(Q_data, 0.0);
50     CeedVectorCreate(ceed, num_qpts * num_comp, &U);
51     CeedVectorSetArray(U, CEED_MEM_HOST, CEED_USE_POINTER, u);
52     CeedVectorCreate(ceed, num_qpts * num_comp, &V);
53     CeedVectorSetValue(V, 0.0);
54 
55     {
56       in[0]  = J;
57       in[1]  = W;
58       out[0] = Q_data;
59       CeedQFunctionApply(qf_setup, num_qpts, in, out);
60     }
61     {
62       in[0]  = U;
63       in[1]  = Q_data;
64       out[0] = V;
65       CeedQFunctionApply(qf_mass, num_qpts, in, out);
66     }
67 
68     CeedVectorGetArrayRead(V, CEED_MEM_HOST, &vv);
69     for (CeedInt c = 0; c < num_comp; c++) {
70       CeedScalar sum = 0;
71       for (CeedInt i = 0; i < num_qpts; i++) sum += vv[i + c * num_qpts];
72       if (fabs(sum - (c + 1)) > 10 * CEED_EPSILON) {
73         // LCOV_EXCL_START
74         printf("%" CeedInt_FMT "D volume error in component %" CeedInt_FMT ": %f != %f\n", dim, c, sum, (c + 1.0));
75         // LCOV_EXCL_STOP
76       }
77     }
78     CeedVectorRestoreArrayRead(V, &vv);
79 
80     CeedVectorDestroy(&J);
81     CeedVectorDestroy(&W);
82     CeedVectorDestroy(&U);
83     CeedVectorDestroy(&V);
84     CeedVectorDestroy(&Q_data);
85     CeedQFunctionDestroy(&qf_setup);
86     CeedQFunctionDestroy(&qf_mass);
87   }
88 
89   CeedDestroy(&ceed);
90   return 0;
91 }
92