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