xref: /libCEED/tests/t409-qfunction.c (revision a2e5d304d0c7d96eecfcbbd32f1ea5194beb84ca)
1 /// @file
2 /// Test creation, evaluation, and destruction for QFunction
3 /// \test Test creation, evaluation, and destruction for QFunction
4 #include "t409-qfunction.h"
5 
6 #include <ceed.h>
7 #include <math.h>
8 
9 int main(int argc, char **argv) {
10   Ceed                 ceed;
11   CeedVector           in[16], out[16];
12   CeedVector           u, v;
13   CeedQFunction        qf;
14   CeedQFunctionContext ctx;
15   CeedInt              q           = 8;
16   bool                 is_writable = true;
17   CeedScalar           ctx_data[5] = {1, 2, 3, 4, 5};
18 
19   CeedInit(argv[1], &ceed);
20 
21   CeedVectorCreate(ceed, q, &u);
22   CeedVectorSetValue(u, 1.0);
23   CeedVectorCreate(ceed, q, &v);
24   CeedVectorSetValue(v, 0.0);
25 
26   CeedQFunctionCreateInterior(ceed, 1, scale, scale_loc, &qf);
27   CeedQFunctionAddInput(qf, "u", 1, CEED_EVAL_INTERP);
28   CeedQFunctionAddOutput(qf, "v", 1, CEED_EVAL_INTERP);
29 
30   CeedQFunctionContextCreate(ceed, &ctx);
31   CeedQFunctionContextSetData(ctx, CEED_MEM_HOST, CEED_COPY_VALUES, sizeof(ctx_data), &ctx_data);
32   CeedQFunctionSetContext(qf, ctx);
33   CeedQFunctionSetContextWritable(qf, is_writable);
34   {
35     in[0]  = u;
36     out[0] = v;
37     CeedQFunctionApply(qf, q, in, out);
38   }
39 
40   {
41     const CeedScalar *v_array;
42 
43     CeedVectorGetArrayRead(v, CEED_MEM_HOST, &v_array);
44     for (CeedInt i = 0; i < q; i++)
45       if (fabs(v_array[i] - ctx_data[1]) > 100. * CEED_EPSILON)
46         // LCOV_EXCL_START
47         printf("v[%" CeedInt_FMT "] %f != 2.0\n", i, v_array[i]);
48     // LCOV_EXCL_STOP
49     CeedVectorRestoreArrayRead(v, &v_array);
50   }
51 
52   // Check for written context data
53   CeedScalar *ctx_data_new;
54   CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &ctx_data_new);
55   if (ctx_data_new[0] != 42)
56     // LCOV_EXCL_START
57     printf("Context data not written: %f != 42\n", ctx_data_new[0]);
58   // LCOV_EXCL_STOP
59   CeedQFunctionContextRestoreDataRead(ctx, &ctx_data_new);
60 
61   // Assert that context will not be written
62   // Note: The interface cannot enforce this in user code
63   //   so setting is_writable == false and then calling
64   //   CeedQFunctionApply to mutate the context would lead
65   //   to inconsistent data on the GPU.
66   //   Only the `/cpu/self/memcheck/*` backends verify that
67   //   read-only access resulted in no changes to the context data
68   CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &ctx_data_new);
69   ctx_data_new[0] = 5;
70   CeedQFunctionContextRestoreData(ctx, &ctx_data_new);
71   is_writable = false;
72   CeedQFunctionSetContextWritable(qf, is_writable);
73   {
74     in[0]  = u;
75     out[0] = v;
76     // Will only error in `/cpu/self/memcheck/*` backends
77     CeedQFunctionApply(qf, q, in, out);
78   }
79 
80   CeedVectorDestroy(&u);
81   CeedVectorDestroy(&v);
82   CeedQFunctionDestroy(&qf);
83   CeedQFunctionContextDestroy(&ctx);
84   CeedDestroy(&ceed);
85   return 0;
86 }
87