xref: /libCEED/tests/t415-qfunction.c (revision 11b88dda510d0aa70e79dc59ad165e2a5539c3c3)
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 <stdio.h>
7 #include <string.h>
8 
9 int main(int argc, char **argv) {
10   Ceed          ceed;
11   CeedVector    in[16], out[16];
12   CeedVector    q_data, dx, w, du, dv;
13   CeedQFunction qf_setup, qf_diff;
14   CeedInt       q        = 8;
15   const CeedInt num_comp = 3;
16 
17   CeedInit(argv[1], &ceed);
18 
19   for (CeedInt dim = 1; dim <= 3; dim++) {
20     CeedInt num_qpts = CeedIntPow(q, dim);
21 
22     CeedVectorCreate(ceed, num_qpts * dim * dim, &dx);
23     CeedVectorCreate(ceed, num_qpts, &w);
24     CeedVectorCreate(ceed, num_qpts * dim * num_comp, &du);
25     {
26       CeedScalar dx_array[num_qpts * dim * dim], w_array[num_qpts], du_array[num_qpts * dim * num_comp];
27 
28       for (CeedInt i = 0; i < num_qpts; i++) {
29         w_array[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             dx_array[i + (g * dim + d) * num_qpts] = d == g;
35           }
36         }
37       }
38       for (CeedInt c = 0; c < num_comp; c++) {
39         for (CeedInt g = 0; g < dim; g++) {
40           for (CeedInt i = 0; i < num_qpts; i++) {
41             du_array[i + (g * num_comp + c) * num_qpts] = c + 1;
42           }
43         }
44       }
45 
46       CeedVectorSetArray(dx, CEED_MEM_HOST, CEED_COPY_VALUES, dx_array);
47       CeedVectorSetArray(w, CEED_MEM_HOST, CEED_COPY_VALUES, w_array);
48       CeedVectorSetArray(du, CEED_MEM_HOST, CEED_COPY_VALUES, du_array);
49     }
50     CeedVectorCreate(ceed, num_qpts * dim * (dim + 1) / 2, &q_data);
51     CeedVectorSetValue(q_data, 0.0);
52     CeedVectorCreate(ceed, num_qpts * dim * num_comp, &dv);
53     CeedVectorSetValue(dv, 0.0);
54 
55     char name_setup[26] = "", name_apply[26] = "";
56     snprintf(name_setup, sizeof name_setup, "Poisson%" CeedInt_FMT "DBuild", dim);
57     CeedQFunctionCreateInteriorByName(ceed, name_setup, &qf_setup);
58     {
59       in[0]  = dx;
60       in[1]  = w;
61       out[0] = q_data;
62       CeedQFunctionApply(qf_setup, num_qpts, in, out);
63     }
64 
65     snprintf(name_apply, sizeof name_apply, "Vector3Poisson%" CeedInt_FMT "DApply", dim);
66     CeedQFunctionCreateInteriorByName(ceed, name_apply, &qf_diff);
67     {
68       in[0]  = du;
69       in[1]  = q_data;
70       out[0] = dv;
71       CeedQFunctionApply(qf_diff, num_qpts, in, out);
72     }
73 
74     // Verify results
75     {
76       const CeedScalar *v_array;
77 
78       CeedVectorGetArrayRead(dv, CEED_MEM_HOST, &v_array);
79       for (CeedInt c = 0; c < num_comp; c++) {
80         CeedScalar sum = 0;
81         for (CeedInt i = 0; i < num_qpts; i++) {
82           for (CeedInt g = 0; g < dim; g++) sum += v_array[i + (g * num_comp + c) * num_qpts];
83         }
84         if (fabs(sum - dim * (c + 1)) > 10 * CEED_EPSILON) {
85           // LCOV_EXCL_START
86           printf("%" CeedInt_FMT "D volume error in component %" CeedInt_FMT ": %f != %f\n", dim, c, sum, dim * (c + 1.0));
87           // LCOV_EXCL_STOP
88         }
89       }
90       CeedVectorRestoreArrayRead(dv, &v_array);
91     }
92 
93     CeedVectorDestroy(&dx);
94     CeedVectorDestroy(&w);
95     CeedVectorDestroy(&du);
96     CeedVectorDestroy(&dv);
97     CeedVectorDestroy(&q_data);
98     CeedQFunctionDestroy(&qf_setup);
99     CeedQFunctionDestroy(&qf_diff);
100   }
101 
102   CeedDestroy(&ceed);
103   return 0;
104 }
105