1 /// @file
2 /// Test setting QFunctionContext fields from Operator
3 /// \test Test setting QFunctionContext fields from Operator
4 #include <ceed.h>
5 #include <stddef.h>
6 #include <stdio.h>
7
8 #include "t500-operator.h"
9
10 typedef struct {
11 int count;
12 double other;
13 } TestContext1;
14
15 typedef struct {
16 double time;
17 double other;
18 } TestContext2;
19
main(int argc,char ** argv)20 int main(int argc, char **argv) {
21 Ceed ceed;
22 CeedQFunctionContext qf_ctx_sub_1, qf_ctx_sub_2;
23 CeedContextFieldLabel count_label, other_label, time_label, bad_label;
24 CeedQFunction qf_sub_1, qf_sub_2;
25 CeedOperator op_sub_1, op_sub_2, op_composite;
26
27 TestContext1 ctx_data_1 = {
28 .count = 42,
29 .other = -3.0,
30 };
31 TestContext2 ctx_data_2 = {
32 .time = 1.0,
33 .other = -3.0,
34 };
35
36 CeedInit(argv[1], &ceed);
37
38 // First sub-operator
39 CeedQFunctionContextCreate(ceed, &qf_ctx_sub_1);
40 CeedQFunctionContextSetData(qf_ctx_sub_1, CEED_MEM_HOST, CEED_USE_POINTER, sizeof(TestContext1), &ctx_data_1);
41 CeedQFunctionContextRegisterInt32(qf_ctx_sub_1, "count", offsetof(TestContext1, count), 1, "some sort of counter");
42 CeedQFunctionContextRegisterDouble(qf_ctx_sub_1, "other", offsetof(TestContext1, other), 1, "some other value");
43
44 CeedQFunctionCreateInterior(ceed, 1, setup, setup_loc, &qf_sub_1);
45 CeedQFunctionSetContext(qf_sub_1, qf_ctx_sub_1);
46
47 CeedOperatorCreate(ceed, qf_sub_1, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_sub_1);
48
49 // Check setting field in operator
50 CeedOperatorGetContextFieldLabel(op_sub_1, "count", &count_label);
51 int value_count = 43;
52 CeedOperatorSetContextInt32(op_sub_1, count_label, &value_count);
53 if (ctx_data_1.count != 43) printf("Incorrect context data for count: %" CeedInt_FMT " != 43", ctx_data_1.count);
54 {
55 const int *values;
56 size_t num_values;
57
58 CeedOperatorGetContextInt32Read(op_sub_1, count_label, &num_values, &values);
59 if (num_values != 1) printf("Incorrect number of count values, found %zu but expected 1", num_values);
60 if (values[0] != ctx_data_1.count) printf("Incorrect value found, found %d but expected %d", values[0], ctx_data_1.count);
61 CeedOperatorRestoreContextInt32Read(op_sub_1, count_label, &values);
62 }
63
64 // Second sub-operator
65 CeedQFunctionContextCreate(ceed, &qf_ctx_sub_2);
66 CeedQFunctionContextSetData(qf_ctx_sub_2, CEED_MEM_HOST, CEED_USE_POINTER, sizeof(TestContext2), &ctx_data_2);
67 CeedQFunctionContextRegisterDouble(qf_ctx_sub_2, "time", offsetof(TestContext2, time), 1, "current time");
68 CeedQFunctionContextRegisterDouble(qf_ctx_sub_2, "other", offsetof(TestContext2, other), 1, "some other value");
69
70 CeedQFunctionCreateInterior(ceed, 1, mass, mass_loc, &qf_sub_2);
71 CeedQFunctionSetContext(qf_sub_2, qf_ctx_sub_2);
72
73 CeedOperatorCreate(ceed, qf_sub_2, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_sub_2);
74
75 // Composite operator
76 CeedOperatorCreateComposite(ceed, &op_composite);
77 CeedOperatorCompositeAddSub(op_composite, op_sub_1);
78 CeedOperatorCompositeAddSub(op_composite, op_sub_2);
79
80 // Check setting field in context of single sub-operator for composite operator
81 CeedOperatorGetContextFieldLabel(op_composite, "time", &time_label);
82 double value_time = 2.0;
83 CeedOperatorSetContextDouble(op_composite, time_label, &value_time);
84 if (ctx_data_2.time != 2.0) printf("Incorrect context data for time: %f != 2.0\n", ctx_data_2.time);
85 {
86 const double *values;
87 size_t num_values;
88
89 CeedOperatorGetContextDoubleRead(op_composite, time_label, &num_values, &values);
90 if (num_values != 1) printf("Incorrect number of time values, found %zu but expected 1", num_values);
91 if (values[0] != ctx_data_2.time) printf("Incorrect value found, found %f but expected %f", values[0], ctx_data_2.time);
92 CeedOperatorRestoreContextDoubleRead(op_composite, time_label, &values);
93 }
94
95 // Check setting field in context of multiple sub-operators for composite operator
96 CeedOperatorGetContextFieldLabel(op_composite, "other", &other_label);
97 // No issue requesting same label twice
98 CeedOperatorGetContextFieldLabel(op_composite, "other", &other_label);
99 double value_other = 9000.;
100
101 CeedOperatorSetContextDouble(op_composite, other_label, &value_other);
102 if (ctx_data_1.other != 9000.0) printf("Incorrect context data for other: %f != 2.0\n", ctx_data_1.other);
103 if (ctx_data_2.other != 9000.0) printf("Incorrect context data for other: %f != 2.0\n", ctx_data_2.other);
104
105 // Check requesting label for field that doesn't exist returns NULL
106 CeedOperatorGetContextFieldLabel(op_composite, "bad", &bad_label);
107 if (bad_label) printf("Incorrect context label returned\n");
108
109 {
110 // Check getting reference to QFunctionContext
111 CeedQFunctionContext ctx_copy = NULL;
112
113 CeedOperatorGetContext(op_sub_1, &ctx_copy);
114 if (ctx_copy != qf_ctx_sub_1) printf("Incorrect QFunctionContext retrieved");
115 CeedQFunctionContextDestroy(&ctx_copy);
116
117 CeedOperatorGetContext(op_sub_2, &ctx_copy); // Destroys reference to qf_ctx_sub_1
118 if (ctx_copy != qf_ctx_sub_2) printf("Incorrect QFunctionContext retrieved");
119 CeedQFunctionContextDestroy(&ctx_copy); // Cleanup to prevent leak
120 }
121
122 CeedQFunctionContextDestroy(&qf_ctx_sub_1);
123 CeedQFunctionContextDestroy(&qf_ctx_sub_2);
124 CeedQFunctionDestroy(&qf_sub_1);
125 CeedQFunctionDestroy(&qf_sub_2);
126 CeedOperatorDestroy(&op_sub_1);
127 CeedOperatorDestroy(&op_sub_2);
128 CeedOperatorDestroy(&op_composite);
129 CeedDestroy(&ceed);
130 return 0;
131 }
132