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