xref: /libCEED/tests/t414-qfunction.c (revision 49aac155e7a09736f56fb3abac0f57dab29f7cbf)
1b249f0c7SJeremy L Thompson /// @file
2b249f0c7SJeremy L Thompson /// Test creation, evaluation, and destruction for vector mass QFunction by name
3b249f0c7SJeremy L Thompson /// \test Test creation, evaluation, and destruction for vector mass QFunction by name
4b249f0c7SJeremy L Thompson #include <ceed.h>
5b249f0c7SJeremy L Thompson #include <math.h>
6*49aac155SJeremy L Thompson #include <stdio.h>
7b249f0c7SJeremy L Thompson #include <string.h>
8b249f0c7SJeremy L Thompson 
main(int argc,char ** argv)9b249f0c7SJeremy L Thompson int main(int argc, char **argv) {
10b249f0c7SJeremy L Thompson   Ceed          ceed;
11b249f0c7SJeremy L Thompson   CeedVector    in[16], out[16];
124fee36f0SJeremy L Thompson   CeedVector    q_data, dx, w, u, v;
13b249f0c7SJeremy L Thompson   CeedQFunction qf_setup, qf_mass;
144fee36f0SJeremy L Thompson   CeedInt       q        = 8;
15b249f0c7SJeremy L Thompson   const CeedInt num_comp = 3;
16b249f0c7SJeremy L Thompson 
17b249f0c7SJeremy L Thompson   CeedInit(argv[1], &ceed);
18b249f0c7SJeremy L Thompson 
19b249f0c7SJeremy L Thompson   for (CeedInt dim = 2; dim <= 3; dim++) {
204fee36f0SJeremy L Thompson     CeedInt num_qpts = CeedIntPow(q, dim);
21b249f0c7SJeremy L Thompson 
224fee36f0SJeremy L Thompson     CeedVectorCreate(ceed, num_qpts * dim * dim, &dx);
234fee36f0SJeremy L Thompson     CeedVectorCreate(ceed, num_qpts, &w);
244fee36f0SJeremy L Thompson     CeedVectorCreate(ceed, num_qpts * num_comp, &u);
254fee36f0SJeremy L Thompson     {
264fee36f0SJeremy L Thompson       CeedScalar dx_array[num_qpts * dim * dim], w_array[num_qpts], u_array[num_qpts * num_comp];
27b249f0c7SJeremy L Thompson 
28b249f0c7SJeremy L Thompson       for (CeedInt i = 0; i < num_qpts; i++) {
294fee36f0SJeremy L Thompson         w_array[i] = 1.0 / num_qpts;
30b249f0c7SJeremy L Thompson       }
31b249f0c7SJeremy L Thompson       for (CeedInt d = 0; d < dim; d++) {
32b249f0c7SJeremy L Thompson         for (CeedInt g = 0; g < dim; g++) {
33b249f0c7SJeremy L Thompson           for (CeedInt i = 0; i < num_qpts; i++) {
344fee36f0SJeremy L Thompson             dx_array[i + (g * dim + d) * num_qpts] = d == g;
35b249f0c7SJeremy L Thompson           }
36b249f0c7SJeremy L Thompson         }
37b249f0c7SJeremy L Thompson       }
38b249f0c7SJeremy L Thompson       for (CeedInt c = 0; c < num_comp; c++) {
39b249f0c7SJeremy L Thompson         for (CeedInt i = 0; i < num_qpts; i++) {
404fee36f0SJeremy L Thompson           u_array[i + c * num_qpts] = c + 1;
41b249f0c7SJeremy L Thompson         }
42b249f0c7SJeremy L Thompson       }
434fee36f0SJeremy L Thompson       CeedVectorSetArray(dx, CEED_MEM_HOST, CEED_COPY_VALUES, dx_array);
444fee36f0SJeremy L Thompson       CeedVectorSetArray(w, CEED_MEM_HOST, CEED_COPY_VALUES, w_array);
454fee36f0SJeremy L Thompson       CeedVectorSetArray(u, CEED_MEM_HOST, CEED_COPY_VALUES, u_array);
464fee36f0SJeremy L Thompson     }
474fee36f0SJeremy L Thompson     CeedVectorCreate(ceed, num_qpts, &q_data);
484fee36f0SJeremy L Thompson     CeedVectorSetValue(q_data, 0.0);
494fee36f0SJeremy L Thompson     CeedVectorCreate(ceed, num_qpts * num_comp, &v);
504fee36f0SJeremy L Thompson     CeedVectorSetValue(v, 0.0);
51b249f0c7SJeremy L Thompson 
524fee36f0SJeremy L Thompson     char name[13] = "";
534fee36f0SJeremy L Thompson     snprintf(name, sizeof name, "Mass%" CeedInt_FMT "DBuild", dim);
544fee36f0SJeremy L Thompson     CeedQFunctionCreateInteriorByName(ceed, name, &qf_setup);
55b249f0c7SJeremy L Thompson     {
564fee36f0SJeremy L Thompson       in[0]  = dx;
574fee36f0SJeremy L Thompson       in[1]  = w;
584fee36f0SJeremy L Thompson       out[0] = q_data;
59b249f0c7SJeremy L Thompson       CeedQFunctionApply(qf_setup, num_qpts, in, out);
60b249f0c7SJeremy L Thompson     }
614fee36f0SJeremy L Thompson 
624fee36f0SJeremy L Thompson     CeedQFunctionCreateInteriorByName(ceed, "Vector3MassApply", &qf_mass);
63b249f0c7SJeremy L Thompson     {
644fee36f0SJeremy L Thompson       in[0]  = u;
654fee36f0SJeremy L Thompson       in[1]  = q_data;
664fee36f0SJeremy L Thompson       out[0] = v;
67b249f0c7SJeremy L Thompson       CeedQFunctionApply(qf_mass, num_qpts, in, out);
68b249f0c7SJeremy L Thompson     }
69b249f0c7SJeremy L Thompson 
704fee36f0SJeremy L Thompson     // Verify results
714fee36f0SJeremy L Thompson     {
724fee36f0SJeremy L Thompson       const CeedScalar *v_array;
734fee36f0SJeremy L Thompson 
744fee36f0SJeremy L Thompson       CeedVectorGetArrayRead(v, CEED_MEM_HOST, &v_array);
75b249f0c7SJeremy L Thompson       for (CeedInt c = 0; c < num_comp; c++) {
76b249f0c7SJeremy L Thompson         CeedScalar sum = 0;
774fee36f0SJeremy L Thompson         for (CeedInt i = 0; i < num_qpts; i++) sum += v_array[i + c * num_qpts];
782b730f8bSJeremy L Thompson         if (fabs(sum - (c + 1)) > 10 * CEED_EPSILON) {
79b249f0c7SJeremy L Thompson           // LCOV_EXCL_START
802b730f8bSJeremy L Thompson           printf("%" CeedInt_FMT "D volume error in component %" CeedInt_FMT ": %f != %f\n", dim, c, sum, (c + 1.0));
81b249f0c7SJeremy L Thompson           // LCOV_EXCL_STOP
82b249f0c7SJeremy L Thompson         }
832b730f8bSJeremy L Thompson       }
844fee36f0SJeremy L Thompson       CeedVectorRestoreArrayRead(v, &v_array);
854fee36f0SJeremy L Thompson     }
86b249f0c7SJeremy L Thompson 
874fee36f0SJeremy L Thompson     CeedVectorDestroy(&dx);
884fee36f0SJeremy L Thompson     CeedVectorDestroy(&w);
894fee36f0SJeremy L Thompson     CeedVectorDestroy(&u);
904fee36f0SJeremy L Thompson     CeedVectorDestroy(&v);
914fee36f0SJeremy L Thompson     CeedVectorDestroy(&q_data);
92b249f0c7SJeremy L Thompson     CeedQFunctionDestroy(&qf_setup);
93b249f0c7SJeremy L Thompson     CeedQFunctionDestroy(&qf_mass);
94b249f0c7SJeremy L Thompson   }
95b249f0c7SJeremy L Thompson 
96b249f0c7SJeremy L Thompson   CeedDestroy(&ceed);
97b249f0c7SJeremy L Thompson   return 0;
98b249f0c7SJeremy L Thompson }
99