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