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 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 %ld 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 CeedCompositeOperatorCreate(ceed, &op_composite); 77 CeedCompositeOperatorAddSub(op_composite, op_sub_1); 78 CeedCompositeOperatorAddSub(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 %ld 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 CeedOperatorSetContextDouble(op_composite, other_label, &value_other); 101 if (ctx_data_1.other != 9000.0) printf("Incorrect context data for other: %f != 2.0\n", ctx_data_1.other); 102 if (ctx_data_2.other != 9000.0) printf("Incorrect context data for other: %f != 2.0\n", ctx_data_2.other); 103 104 // Check requesting label for field that doesn't exist returns NULL 105 CeedOperatorGetContextFieldLabel(op_composite, "bad", &bad_label); 106 if (bad_label) printf("Incorrect context label returned\n"); 107 108 { 109 // Check getting reference to QFunctionContext 110 CeedQFunctionContext ctx_copy = NULL; 111 112 CeedOperatorGetContext(op_sub_1, &ctx_copy); 113 if (ctx_copy != qf_ctx_sub_1) printf("Incorrect QFunctionContext retrieved"); 114 115 CeedOperatorGetContext(op_sub_2, &ctx_copy); // Destroys reference to qf_ctx_sub_1 116 if (ctx_copy != qf_ctx_sub_2) printf("Incorrect QFunctionContext retrieved"); 117 CeedQFunctionContextDestroy(&ctx_copy); // Cleanup to prevent leak 118 } 119 120 CeedQFunctionContextDestroy(&qf_ctx_sub_1); 121 CeedQFunctionContextDestroy(&qf_ctx_sub_2); 122 CeedQFunctionDestroy(&qf_sub_1); 123 CeedQFunctionDestroy(&qf_sub_2); 124 CeedOperatorDestroy(&op_sub_1); 125 CeedOperatorDestroy(&op_sub_2); 126 CeedOperatorDestroy(&op_composite); 127 CeedDestroy(&ceed); 128 return 0; 129 } 130