xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-qfunctioncontext.c (revision ca94c3ddc8f82b7d93a79f9e4812e99b8be840ff)
13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors.
23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3777ff853SJeremy L Thompson //
43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
5777ff853SJeremy L Thompson //
63d8e8822SJeremy L Thompson // This file is part of CEED:  http://github.com/ceed
7777ff853SJeremy L Thompson 
83d576824SJeremy L Thompson #include <ceed-impl.h>
949aac155SJeremy L Thompson #include <ceed.h>
102b730f8bSJeremy L Thompson #include <ceed/backend.h>
1149aac155SJeremy L Thompson #include <stdbool.h>
123d576824SJeremy L Thompson #include <stdint.h>
133d576824SJeremy L Thompson #include <stdio.h>
14cdf32b93SJeremy L Thompson #include <string.h>
15777ff853SJeremy L Thompson 
16777ff853SJeremy L Thompson /// @file
17777ff853SJeremy L Thompson /// Implementation of public CeedQFunctionContext interfaces
18777ff853SJeremy L Thompson 
19777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
20cdf32b93SJeremy L Thompson /// CeedQFunctionContext Library Internal Functions
21cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
22cdf32b93SJeremy L Thompson /// @addtogroup CeedQFunctionDeveloper
23cdf32b93SJeremy L Thompson /// @{
24cdf32b93SJeremy L Thompson 
25cdf32b93SJeremy L Thompson /**
26*ca94c3ddSJeremy L Thompson   @brief Get index for `CeedQFunctionContext` field
27cdf32b93SJeremy L Thompson 
28*ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
29ea61e9acSJeremy L Thompson   @param[in]  field_name  Name of field
30*ca94c3ddSJeremy L Thompson   @param[out] field_index Index of field, or `-1` if field is not registered
31cdf32b93SJeremy L Thompson 
32cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
33cdf32b93SJeremy L Thompson 
34cdf32b93SJeremy L Thompson   @ref Developer
35cdf32b93SJeremy L Thompson **/
362b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx, const char *field_name, CeedInt *field_index) {
37cdf32b93SJeremy L Thompson   *field_index = -1;
382b730f8bSJeremy L Thompson   for (CeedInt i = 0; i < ctx->num_fields; i++) {
392b730f8bSJeremy L Thompson     if (!strcmp(ctx->field_labels[i]->name, field_name)) *field_index = i;
402b730f8bSJeremy L Thompson   }
41cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
42cdf32b93SJeremy L Thompson }
43cdf32b93SJeremy L Thompson 
44cdf32b93SJeremy L Thompson /**
45*ca94c3ddSJeremy L Thompson   @brief Common function for registering `CeedQFunctionContext` fields
46cdf32b93SJeremy L Thompson 
47*ca94c3ddSJeremy L Thompson   @param[in,out] ctx               `CeedQFunctionContext`
48ea61e9acSJeremy L Thompson   @param[in]     field_name        Name of field to register
49ea61e9acSJeremy L Thompson   @param[in]     field_offset      Offset of field to register
50*ca94c3ddSJeremy L Thompson   @param[in]     field_description Description of field, or `NULL` for none
51*ca94c3ddSJeremy L Thompson   @param[in]     field_type        @ref CeedContextFieldType
52ea61e9acSJeremy L Thompson   @param[in]     num_values        Number of values to register, must be contiguous in memory
53cdf32b93SJeremy L Thompson 
54cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
55cdf32b93SJeremy L Thompson 
56cdf32b93SJeremy L Thompson   @ref Developer
57cdf32b93SJeremy L Thompson **/
582b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, const char *field_description,
595b6ec284SJeremy L Thompson                                         CeedContextFieldType field_type, size_t num_values) {
605b6ec284SJeremy L Thompson   size_t  field_size  = 0;
61cdf32b93SJeremy L Thompson   CeedInt field_index = -1;
621c66c397SJeremy L Thompson 
631c66c397SJeremy L Thompson   // Check for duplicate
642b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index));
656574a04fSJeremy L Thompson   CeedCheck(field_index == -1, ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" already registered", field_name);
66cdf32b93SJeremy L Thompson 
67cdf32b93SJeremy L Thompson   // Allocate space for field data
68cdf32b93SJeremy L Thompson   if (ctx->num_fields == 0) {
692b730f8bSJeremy L Thompson     CeedCall(CeedCalloc(1, &ctx->field_labels));
70cdf32b93SJeremy L Thompson     ctx->max_fields = 1;
71cdf32b93SJeremy L Thompson   } else if (ctx->num_fields == ctx->max_fields) {
722b730f8bSJeremy L Thompson     CeedCall(CeedRealloc(2 * ctx->max_fields, &ctx->field_labels));
73cdf32b93SJeremy L Thompson     ctx->max_fields *= 2;
74cdf32b93SJeremy L Thompson   }
752b730f8bSJeremy L Thompson   CeedCall(CeedCalloc(1, &ctx->field_labels[ctx->num_fields]));
76cdf32b93SJeremy L Thompson 
775b6ec284SJeremy L Thompson   // Compute field size
785b6ec284SJeremy L Thompson   switch (field_type) {
795b6ec284SJeremy L Thompson     case CEED_CONTEXT_FIELD_DOUBLE:
805b6ec284SJeremy L Thompson       field_size = sizeof(double);
815b6ec284SJeremy L Thompson       break;
825b6ec284SJeremy L Thompson     case CEED_CONTEXT_FIELD_INT32:
835b6ec284SJeremy L Thompson       field_size = sizeof(int);
845b6ec284SJeremy L Thompson       break;
855b6ec284SJeremy L Thompson     case CEED_CONTEXT_FIELD_BOOL:
865b6ec284SJeremy L Thompson       field_size = sizeof(bool);
875b6ec284SJeremy L Thompson       break;
885b6ec284SJeremy L Thompson   }
895b6ec284SJeremy L Thompson 
90cdf32b93SJeremy L Thompson   // Copy field data
912b730f8bSJeremy L Thompson   CeedCall(CeedStringAllocCopy(field_name, (char **)&ctx->field_labels[ctx->num_fields]->name));
922b730f8bSJeremy L Thompson   CeedCall(CeedStringAllocCopy(field_description, (char **)&ctx->field_labels[ctx->num_fields]->description));
933668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->type       = field_type;
943668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->offset     = field_offset;
957bfe0f0eSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->size       = field_size * num_values;
967bfe0f0eSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->num_values = num_values;
97cdf32b93SJeremy L Thompson   ctx->num_fields++;
98cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
99cdf32b93SJeremy L Thompson }
100cdf32b93SJeremy L Thompson 
1013b190ab8SJeremy L Thompson /**
102*ca94c3ddSJeremy L Thompson   @brief Destroy user data held by `CeedQFunctionContext`, using function set by @ref CeedQFunctionContextSetDataDestroy(), if applicable
1033b190ab8SJeremy L Thompson 
104*ca94c3ddSJeremy L Thompson   @param[in,out] ctx `CeedQFunctionContext` to destroy user data
1053b190ab8SJeremy L Thompson 
1063b190ab8SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1073b190ab8SJeremy L Thompson 
1083b190ab8SJeremy L Thompson   @ref Developer
1093b190ab8SJeremy L Thompson **/
1103b190ab8SJeremy L Thompson static int CeedQFunctionContextDestroyData(CeedQFunctionContext ctx) {
1113b190ab8SJeremy L Thompson   if (ctx->DataDestroy) {
1122b730f8bSJeremy L Thompson     CeedCall(ctx->DataDestroy(ctx));
1133b190ab8SJeremy L Thompson   } else {
1143b190ab8SJeremy L Thompson     CeedMemType                         data_destroy_mem_type;
1151c66c397SJeremy L Thompson     CeedQFunctionContextDataDestroyUser data_destroy_function;
1163b190ab8SJeremy L Thompson 
1172b730f8bSJeremy L Thompson     CeedCall(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function));
1183b190ab8SJeremy L Thompson     if (data_destroy_function) {
1193b190ab8SJeremy L Thompson       void *data;
1203b190ab8SJeremy L Thompson 
1212b730f8bSJeremy L Thompson       CeedCall(CeedQFunctionContextGetData(ctx, data_destroy_mem_type, &data));
1222b730f8bSJeremy L Thompson       CeedCall(data_destroy_function(data));
1232b730f8bSJeremy L Thompson       CeedCall(CeedQFunctionContextRestoreData(ctx, &data));
1243b190ab8SJeremy L Thompson     }
1253b190ab8SJeremy L Thompson   }
1263b190ab8SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1273b190ab8SJeremy L Thompson }
1283b190ab8SJeremy L Thompson 
129cdf32b93SJeremy L Thompson /// @}
130cdf32b93SJeremy L Thompson 
131cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
132777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API
133777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
134777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend
135777ff853SJeremy L Thompson /// @{
136777ff853SJeremy L Thompson 
137777ff853SJeremy L Thompson /**
138*ca94c3ddSJeremy L Thompson   @brief Get the `Ceed` associated with a `CeedQFunctionContext`
139777ff853SJeremy L Thompson 
140*ca94c3ddSJeremy L Thompson   @param[in]  ctx  `CeedQFunctionContext`
141*ca94c3ddSJeremy L Thompson   @param[out] ceed Variable to store `Ceed`
142777ff853SJeremy L Thompson 
143777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
144777ff853SJeremy L Thompson 
145777ff853SJeremy L Thompson   @ref Backend
146777ff853SJeremy L Thompson **/
147777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) {
148777ff853SJeremy L Thompson   *ceed = ctx->ceed;
149e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
150777ff853SJeremy L Thompson }
151777ff853SJeremy L Thompson 
152777ff853SJeremy L Thompson /**
153*ca94c3ddSJeremy L Thompson   @brief Check for valid data in a `CeedQFunctionContext`
1549c774eddSJeremy L Thompson 
155*ca94c3ddSJeremy L Thompson   @param[in]  ctx            `CeedQFunctionContext` to check validity
1569c774eddSJeremy L Thompson   @param[out] has_valid_data Variable to store validity
1579c774eddSJeremy L Thompson 
1589c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1599c774eddSJeremy L Thompson 
1609c774eddSJeremy L Thompson   @ref Backend
1619c774eddSJeremy L Thompson **/
1622b730f8bSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx, bool *has_valid_data) {
163*ca94c3ddSJeremy L Thompson   CeedCheck(ctx->HasValidData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextHasValidData");
1642b730f8bSJeremy L Thompson   CeedCall(ctx->HasValidData(ctx, has_valid_data));
1659c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1669c774eddSJeremy L Thompson }
1679c774eddSJeremy L Thompson 
1689c774eddSJeremy L Thompson /**
169*ca94c3ddSJeremy L Thompson   @brief Check for borrowed data of a specific @ref CeedMemType in a `CeedQFunctionContext`
1709c774eddSJeremy L Thompson 
171*ca94c3ddSJeremy L Thompson   @param[in]  ctx                       `CeedQFunctionContext` to check
172ea61e9acSJeremy L Thompson   @param[in]  mem_type                  Memory type to check
1739c774eddSJeremy L Thompson   @param[out] has_borrowed_data_of_type Variable to store result
1749c774eddSJeremy L Thompson 
1759c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1769c774eddSJeremy L Thompson 
1779c774eddSJeremy L Thompson   @ref Backend
1789c774eddSJeremy L Thompson **/
1792b730f8bSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx, CeedMemType mem_type, bool *has_borrowed_data_of_type) {
180*ca94c3ddSJeremy L Thompson   CeedCheck(ctx->HasBorrowedDataOfType, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextHasBorrowedDataOfType");
1812b730f8bSJeremy L Thompson   CeedCall(ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type));
1829c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1839c774eddSJeremy L Thompson }
1849c774eddSJeremy L Thompson 
1859c774eddSJeremy L Thompson /**
186*ca94c3ddSJeremy L Thompson   @brief Get the state of a `CeedQFunctionContext`
187777ff853SJeremy L Thompson 
188*ca94c3ddSJeremy L Thompson   @param[in]  ctx   `CeedQFunctionContext` to retrieve state
189777ff853SJeremy L Thompson   @param[out] state Variable to store state
190777ff853SJeremy L Thompson 
191777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
192777ff853SJeremy L Thompson 
193777ff853SJeremy L Thompson   @ref Backend
194777ff853SJeremy L Thompson **/
195777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) {
196777ff853SJeremy L Thompson   *state = ctx->state;
197e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
198777ff853SJeremy L Thompson }
199777ff853SJeremy L Thompson 
200777ff853SJeremy L Thompson /**
201*ca94c3ddSJeremy L Thompson   @brief Get backend data of a `CeedQFunctionContext`
202777ff853SJeremy L Thompson 
203*ca94c3ddSJeremy L Thompson   @param[in]  ctx  `CeedQFunctionContext`
204777ff853SJeremy L Thompson   @param[out] data Variable to store data
205777ff853SJeremy L Thompson 
206777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
207777ff853SJeremy L Thompson 
208777ff853SJeremy L Thompson   @ref Backend
209777ff853SJeremy L Thompson **/
210777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) {
211777ff853SJeremy L Thompson   *(void **)data = ctx->data;
212e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
213777ff853SJeremy L Thompson }
214777ff853SJeremy L Thompson 
215777ff853SJeremy L Thompson /**
216*ca94c3ddSJeremy L Thompson   @brief Set backend data of a `CeedQFunctionContext`
217777ff853SJeremy L Thompson 
218*ca94c3ddSJeremy L Thompson   @param[in,out] ctx  `CeedQFunctionContext`
219ea61e9acSJeremy L Thompson   @param[in]     data Data to set
220777ff853SJeremy L Thompson 
221777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
222777ff853SJeremy L Thompson 
223777ff853SJeremy L Thompson   @ref Backend
224777ff853SJeremy L Thompson **/
225777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) {
226777ff853SJeremy L Thompson   ctx->data = data;
227e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
228777ff853SJeremy L Thompson }
229777ff853SJeremy L Thompson 
23034359f16Sjeremylt /**
231*ca94c3ddSJeremy L Thompson   @brief Get label for a registered `CeedQFunctionContext` field, or `NULL` if no field has been registered with this `field_name`
232e6a0ab89SJeremy L Thompson 
233*ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
234e6a0ab89SJeremy L Thompson   @param[in]  field_name  Name of field to retrieve label
235e6a0ab89SJeremy L Thompson   @param[out] field_label Variable to field label
236e6a0ab89SJeremy L Thompson 
237e6a0ab89SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
238e6a0ab89SJeremy L Thompson 
2393e1e85abSJeremy L Thompson   @ref Backend
240e6a0ab89SJeremy L Thompson **/
2412b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx, const char *field_name, CeedContextFieldLabel *field_label) {
242e6a0ab89SJeremy L Thompson   CeedInt field_index;
2431c66c397SJeremy L Thompson 
2442b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index));
245e6a0ab89SJeremy L Thompson 
246e6a0ab89SJeremy L Thompson   if (field_index != -1) {
247e6a0ab89SJeremy L Thompson     *field_label = ctx->field_labels[field_index];
248e6a0ab89SJeremy L Thompson   } else {
249e6a0ab89SJeremy L Thompson     *field_label = NULL;
250e6a0ab89SJeremy L Thompson   }
251e6a0ab89SJeremy L Thompson   return CEED_ERROR_SUCCESS;
252e6a0ab89SJeremy L Thompson }
253e6a0ab89SJeremy L Thompson 
254e6a0ab89SJeremy L Thompson /**
255*ca94c3ddSJeremy L Thompson   @brief Set `CeedQFunctionContext` field
256d8dd9a91SJeremy L Thompson 
257*ca94c3ddSJeremy L Thompson   @param[in,out] ctx         `CeedQFunctionContext`
258ea61e9acSJeremy L Thompson   @param[in]     field_label Label of field to set
259ea61e9acSJeremy L Thompson   @param[in]     field_type  Type of field to set
2602788fa27SJeremy L Thompson   @param[in]     values      Value to set
261d8dd9a91SJeremy L Thompson 
262d8dd9a91SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
263d8dd9a91SJeremy L Thompson 
2643e1e85abSJeremy L Thompson   @ref Backend
265d8dd9a91SJeremy L Thompson **/
2662788fa27SJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *values) {
2671a34d7dcSJeremy L Thompson   bool  is_different;
2681c66c397SJeremy L Thompson   char *data;
2691c66c397SJeremy L Thompson 
2703668ca4bSJeremy L Thompson   // Check field type
2716574a04fSJeremy L Thompson   CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED,
2726574a04fSJeremy L Thompson             "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name,
2736574a04fSJeremy L Thompson             CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
274d8dd9a91SJeremy L Thompson 
2751a34d7dcSJeremy L Thompson   CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data));
2761a34d7dcSJeremy L Thompson   is_different = memcmp(&data[field_label->offset], values, field_label->size);
2771a34d7dcSJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreDataRead(ctx, &data));
2781a34d7dcSJeremy L Thompson   if (is_different) {
2792b730f8bSJeremy L Thompson     CeedCall(CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data));
2802788fa27SJeremy L Thompson     memcpy(&data[field_label->offset], values, field_label->size);
2812b730f8bSJeremy L Thompson     CeedCall(CeedQFunctionContextRestoreData(ctx, &data));
2821a34d7dcSJeremy L Thompson   }
283d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
284d8dd9a91SJeremy L Thompson }
285d8dd9a91SJeremy L Thompson 
286d8dd9a91SJeremy L Thompson /**
287*ca94c3ddSJeremy L Thompson   @brief Get `CeedQFunctionContext` field data, read-only
2882788fa27SJeremy L Thompson 
289*ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
2902788fa27SJeremy L Thompson   @param[in]  field_label Label of field to read
2912788fa27SJeremy L Thompson   @param[in]  field_type  Type of field to read
2922788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
2932788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
2942788fa27SJeremy L Thompson 
2952788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
2962788fa27SJeremy L Thompson 
2972788fa27SJeremy L Thompson   @ref Backend
2982788fa27SJeremy L Thompson **/
2992788fa27SJeremy L Thompson int CeedQFunctionContextGetGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type,
3002788fa27SJeremy L Thompson                                        size_t *num_values, void *values) {
3011c66c397SJeremy L Thompson   char *data;
3021c66c397SJeremy L Thompson 
3032788fa27SJeremy L Thompson   // Check field type
3046574a04fSJeremy L Thompson   CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED,
3056574a04fSJeremy L Thompson             "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name,
3066574a04fSJeremy L Thompson             CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
3072788fa27SJeremy L Thompson 
3082788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data));
3092788fa27SJeremy L Thompson   *(void **)values = &data[field_label->offset];
3102788fa27SJeremy L Thompson   switch (field_type) {
3112788fa27SJeremy L Thompson     case CEED_CONTEXT_FIELD_INT32:
3122788fa27SJeremy L Thompson       *num_values = field_label->size / sizeof(int);
3132788fa27SJeremy L Thompson       break;
3142788fa27SJeremy L Thompson     case CEED_CONTEXT_FIELD_DOUBLE:
3152788fa27SJeremy L Thompson       *num_values = field_label->size / sizeof(double);
3162788fa27SJeremy L Thompson       break;
3175b6ec284SJeremy L Thompson     case CEED_CONTEXT_FIELD_BOOL:
3185b6ec284SJeremy L Thompson       *num_values = field_label->size / sizeof(bool);
3195b6ec284SJeremy L Thompson       break;
3202788fa27SJeremy L Thompson   }
3212788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3222788fa27SJeremy L Thompson }
3232788fa27SJeremy L Thompson 
3242788fa27SJeremy L Thompson /**
325*ca94c3ddSJeremy L Thompson   @brief Restore `CeedQFunctionContext` field data, read-only
3262788fa27SJeremy L Thompson 
327*ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
3282788fa27SJeremy L Thompson   @param[in]  field_label Label of field to restore
3292788fa27SJeremy L Thompson   @param[in]  field_type  Type of field to restore
3302788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
3312788fa27SJeremy L Thompson 
3322788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
3332788fa27SJeremy L Thompson 
3342788fa27SJeremy L Thompson   @ref Backend
3352788fa27SJeremy L Thompson **/
3362788fa27SJeremy L Thompson int CeedQFunctionContextRestoreGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type,
3372788fa27SJeremy L Thompson                                            void *values) {
3382788fa27SJeremy L Thompson   // Check field type
3396574a04fSJeremy L Thompson   CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED,
3406574a04fSJeremy L Thompson             "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name,
3416574a04fSJeremy L Thompson             CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
3422788fa27SJeremy L Thompson 
3432788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreDataRead(ctx, values));
3442788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3452788fa27SJeremy L Thompson }
3462788fa27SJeremy L Thompson 
3472788fa27SJeremy L Thompson /**
348*ca94c3ddSJeremy L Thompson   @brief Set `CeedQFunctionContext` field holding double precision values
349bfacc300SJeremy L Thompson 
350*ca94c3ddSJeremy L Thompson   @param[in,out] ctx         `CeedQFunctionContext`
3512788fa27SJeremy L Thompson   @param[in]     field_label Label for field to set
352ea61e9acSJeremy L Thompson   @param[in]     values      Values to set
353bfacc300SJeremy L Thompson 
354bfacc300SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
355bfacc300SJeremy L Thompson 
3563e1e85abSJeremy L Thompson   @ref Backend
357bfacc300SJeremy L Thompson **/
3582b730f8bSJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, double *values) {
3596574a04fSJeremy L Thompson   CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
3602b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values));
361bfacc300SJeremy L Thompson   return CEED_ERROR_SUCCESS;
362bfacc300SJeremy L Thompson }
363bfacc300SJeremy L Thompson 
364bfacc300SJeremy L Thompson /**
365*ca94c3ddSJeremy L Thompson   @brief Get `CeedQFunctionContext` field holding double precision values, read-only
3662788fa27SJeremy L Thompson 
367*ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
3682788fa27SJeremy L Thompson   @param[in]  field_label Label for field to get
3692788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
3702788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
3712788fa27SJeremy L Thompson 
3722788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
3732788fa27SJeremy L Thompson 
3742788fa27SJeremy L Thompson   @ref Backend
3752788fa27SJeremy L Thompson **/
3762788fa27SJeremy L Thompson int CeedQFunctionContextGetDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const double **values) {
3776574a04fSJeremy L Thompson   CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
3782788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values));
3792788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3802788fa27SJeremy L Thompson }
3812788fa27SJeremy L Thompson 
3822788fa27SJeremy L Thompson /**
383*ca94c3ddSJeremy L Thompson   @brief Restore `CeedQFunctionContext` field holding double precision values, read-only
3842788fa27SJeremy L Thompson 
385*ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
3862788fa27SJeremy L Thompson   @param[in]  field_label Label for field to restore
3872788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
3882788fa27SJeremy L Thompson 
3892788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
3902788fa27SJeremy L Thompson 
3912788fa27SJeremy L Thompson   @ref Backend
3922788fa27SJeremy L Thompson **/
3932788fa27SJeremy L Thompson int CeedQFunctionContextRestoreDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const double **values) {
3946574a04fSJeremy L Thompson   CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
3952788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values));
3962788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3972788fa27SJeremy L Thompson }
3982788fa27SJeremy L Thompson 
3992788fa27SJeremy L Thompson /**
400*ca94c3ddSJeremy L Thompson   @brief Set CeedQFunctionContext field holding `int32` values
401bfacc300SJeremy L Thompson 
402ea61e9acSJeremy L Thompson   @param[in,out] ctx         CeedQFunctionContext
4032788fa27SJeremy L Thompson   @param[in]     field_label Label for field to set
404ea61e9acSJeremy L Thompson   @param[in]     values      Values to set
405bfacc300SJeremy L Thompson 
406bfacc300SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
407bfacc300SJeremy L Thompson 
4083e1e85abSJeremy L Thompson   @ref Backend
409bfacc300SJeremy L Thompson **/
41023dbfd29SJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, int32_t *values) {
4116574a04fSJeremy L Thompson   CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
4122b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values));
413bfacc300SJeremy L Thompson   return CEED_ERROR_SUCCESS;
414bfacc300SJeremy L Thompson }
415bfacc300SJeremy L Thompson 
416bfacc300SJeremy L Thompson /**
417*ca94c3ddSJeremy L Thompson   @brief Get `CeedQFunctionContext` field holding `int32` values, read-only
4182788fa27SJeremy L Thompson 
419*ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
4202788fa27SJeremy L Thompson   @param[in]  field_label Label for field to get
4212788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
4222788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
4232788fa27SJeremy L Thompson 
4242788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4252788fa27SJeremy L Thompson 
4262788fa27SJeremy L Thompson   @ref Backend
4272788fa27SJeremy L Thompson **/
42823dbfd29SJeremy L Thompson int CeedQFunctionContextGetInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const int32_t **values) {
4296574a04fSJeremy L Thompson   CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
4302788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values));
4312788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4322788fa27SJeremy L Thompson }
4332788fa27SJeremy L Thompson 
4342788fa27SJeremy L Thompson /**
435*ca94c3ddSJeremy L Thompson   @brief Restore `CeedQFunctionContext` field holding `int32` values, read-only
4362788fa27SJeremy L Thompson 
437*ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
4382788fa27SJeremy L Thompson   @param[in]  field_label Label for field to restore
4392788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
4402788fa27SJeremy L Thompson 
4412788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4422788fa27SJeremy L Thompson 
4432788fa27SJeremy L Thompson   @ref Backend
4442788fa27SJeremy L Thompson **/
44523dbfd29SJeremy L Thompson int CeedQFunctionContextRestoreInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const int32_t **values) {
4466574a04fSJeremy L Thompson   CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
4472788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values));
4482788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4492788fa27SJeremy L Thompson }
4502788fa27SJeremy L Thompson 
4512788fa27SJeremy L Thompson /**
452*ca94c3ddSJeremy L Thompson   @brief Set `CeedQFunctionContext` field holding boolean values
4535b6ec284SJeremy L Thompson 
454*ca94c3ddSJeremy L Thompson   @param[in,out] ctx         `CeedQFunctionContext`
4555b6ec284SJeremy L Thompson   @param[in]     field_label Label for field to set
4565b6ec284SJeremy L Thompson   @param[in]     values      Values to set
4575b6ec284SJeremy L Thompson 
4585b6ec284SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4595b6ec284SJeremy L Thompson 
4605b6ec284SJeremy L Thompson   @ref Backend
4615b6ec284SJeremy L Thompson **/
4625b6ec284SJeremy L Thompson int CeedQFunctionContextSetBoolean(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, bool *values) {
4635b6ec284SJeremy L Thompson   CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
4645b6ec284SJeremy L Thompson   CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, values));
4655b6ec284SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4665b6ec284SJeremy L Thompson }
4675b6ec284SJeremy L Thompson 
4685b6ec284SJeremy L Thompson /**
469*ca94c3ddSJeremy L Thompson   @brief Get `CeedQFunctionContext` field holding boolean values, read-only
4705b6ec284SJeremy L Thompson 
471*ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
4725b6ec284SJeremy L Thompson   @param[in]  field_label Label for field to get
4735b6ec284SJeremy L Thompson   @param[out] num_values  Number of values in the field label
4745b6ec284SJeremy L Thompson   @param[out] values      Pointer to context values
4755b6ec284SJeremy L Thompson 
4765b6ec284SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4775b6ec284SJeremy L Thompson 
4785b6ec284SJeremy L Thompson   @ref Backend
4795b6ec284SJeremy L Thompson **/
4805b6ec284SJeremy L Thompson int CeedQFunctionContextGetBooleanRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const bool **values) {
4815b6ec284SJeremy L Thompson   CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
4825b6ec284SJeremy L Thompson   CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, num_values, values));
4835b6ec284SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4845b6ec284SJeremy L Thompson }
4855b6ec284SJeremy L Thompson 
4865b6ec284SJeremy L Thompson /**
487*ca94c3ddSJeremy L Thompson   @brief Restore `CeedQFunctionContext` field holding boolean values, read-only
4885b6ec284SJeremy L Thompson 
489*ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
4905b6ec284SJeremy L Thompson   @param[in]  field_label Label for field to restore
4915b6ec284SJeremy L Thompson   @param[out] values      Pointer to context values
4925b6ec284SJeremy L Thompson 
4935b6ec284SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4945b6ec284SJeremy L Thompson 
4955b6ec284SJeremy L Thompson   @ref Backend
4965b6ec284SJeremy L Thompson **/
4975b6ec284SJeremy L Thompson int CeedQFunctionContextRestoreBooleanRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const bool **values) {
4985b6ec284SJeremy L Thompson   CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
4995b6ec284SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, values));
5005b6ec284SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5015b6ec284SJeremy L Thompson }
5025b6ec284SJeremy L Thompson 
5035b6ec284SJeremy L Thompson /**
504*ca94c3ddSJeremy L Thompson   @brief Get additional destroy routine for `CeedQFunctionContext` user data
5052e64a2b9SJeremy L Thompson 
506*ca94c3ddSJeremy L Thompson   @param[in] ctx         `CeedQFunctionContext` to get user destroy function
5072e64a2b9SJeremy L Thompson   @param[out] f_mem_type Memory type to use when passing data into `f`
5082e64a2b9SJeremy L Thompson   @param[out] f          Additional routine to use to destroy user data
5092e64a2b9SJeremy L Thompson 
5102e64a2b9SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
5112e64a2b9SJeremy L Thompson 
5122e64a2b9SJeremy L Thompson   @ref Backend
5132e64a2b9SJeremy L Thompson **/
5142b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx, CeedMemType *f_mem_type, CeedQFunctionContextDataDestroyUser *f) {
5152e64a2b9SJeremy L Thompson   if (f_mem_type) *f_mem_type = ctx->data_destroy_mem_type;
5162e64a2b9SJeremy L Thompson   if (f) *f = ctx->data_destroy_function;
5172e64a2b9SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5182e64a2b9SJeremy L Thompson }
5192e64a2b9SJeremy L Thompson 
5202e64a2b9SJeremy L Thompson /**
521*ca94c3ddSJeremy L Thompson   @brief Increment the reference counter for a `CeedQFunctionContext`
52234359f16Sjeremylt 
523*ca94c3ddSJeremy L Thompson   @param[in,out] ctx `CeedQFunctionContext` to increment the reference counter
52434359f16Sjeremylt 
52534359f16Sjeremylt   @return An error code: 0 - success, otherwise - failure
52634359f16Sjeremylt 
52734359f16Sjeremylt   @ref Backend
52834359f16Sjeremylt **/
5299560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) {
53034359f16Sjeremylt   ctx->ref_count++;
53134359f16Sjeremylt   return CEED_ERROR_SUCCESS;
53234359f16Sjeremylt }
53334359f16Sjeremylt 
534777ff853SJeremy L Thompson /// @}
535777ff853SJeremy L Thompson 
536777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
537777ff853SJeremy L Thompson /// CeedQFunctionContext Public API
538777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
539777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser
540777ff853SJeremy L Thompson /// @{
541777ff853SJeremy L Thompson 
542777ff853SJeremy L Thompson /**
543*ca94c3ddSJeremy L Thompson   @brief Create a `CeedQFunctionContext` for storing `CeedQFunctionContext` user context data
544777ff853SJeremy L Thompson 
545*ca94c3ddSJeremy L Thompson   @param[in]  ceed `Ceed` object used to create the `CeedQFunctionContext`
546*ca94c3ddSJeremy L Thompson   @param[out] ctx  Address of the variable where the newly created `CeedQFunctionContext` will be stored
547777ff853SJeremy L Thompson 
548777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
549777ff853SJeremy L Thompson 
550777ff853SJeremy L Thompson   @ref User
551777ff853SJeremy L Thompson **/
552777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) {
553777ff853SJeremy L Thompson   if (!ceed->QFunctionContextCreate) {
554777ff853SJeremy L Thompson     Ceed delegate;
5556574a04fSJeremy L Thompson 
5562b730f8bSJeremy L Thompson     CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Context"));
557*ca94c3ddSJeremy L Thompson     CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextCreate");
5582b730f8bSJeremy L Thompson     CeedCall(CeedQFunctionContextCreate(delegate, ctx));
559e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
560777ff853SJeremy L Thompson   }
561777ff853SJeremy L Thompson 
5622b730f8bSJeremy L Thompson   CeedCall(CeedCalloc(1, ctx));
563db002c03SJeremy L Thompson   CeedCall(CeedReferenceCopy(ceed, &(*ctx)->ceed));
564d1d35e2fSjeremylt   (*ctx)->ref_count = 1;
5652b730f8bSJeremy L Thompson   CeedCall(ceed->QFunctionContextCreate(*ctx));
566e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
567777ff853SJeremy L Thompson }
568777ff853SJeremy L Thompson 
569777ff853SJeremy L Thompson /**
570*ca94c3ddSJeremy L Thompson   @brief Copy the pointer to a `CeedQFunctionContext`.
5714385fb7fSSebastian Grimberg 
572*ca94c3ddSJeremy L Thompson   Both pointers should be destroyed with @ref CeedQFunctionContextDestroy().
573512bb800SJeremy L Thompson 
574*ca94c3ddSJeremy L Thompson   Note: If the value of `*ctx_copy` passed to this function is non-`NULL`, then it is assumed that `*ctx_copy` is a pointer to a `CeedQFunctionContext`.
575*ca94c3ddSJeremy L Thompson         This `CeedQFunctionContext` will be destroyed if `*ctx_copy` is the only reference to this `CeedQFunctionContext`.
5769560d06aSjeremylt 
577ea61e9acSJeremy L Thompson   @param[in]     ctx      CeedQFunctionContext to copy reference to
578ea61e9acSJeremy L Thompson   @param[in,out] ctx_copy Variable to store copied reference
5799560d06aSjeremylt 
5809560d06aSjeremylt   @return An error code: 0 - success, otherwise - failure
5819560d06aSjeremylt 
5829560d06aSjeremylt   @ref User
5839560d06aSjeremylt **/
5842b730f8bSJeremy L Thompson int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, CeedQFunctionContext *ctx_copy) {
5852b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextReference(ctx));
5862b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroy(ctx_copy));
5879560d06aSjeremylt   *ctx_copy = ctx;
5889560d06aSjeremylt   return CEED_ERROR_SUCCESS;
5899560d06aSjeremylt }
5909560d06aSjeremylt 
5919560d06aSjeremylt /**
592*ca94c3ddSJeremy L Thompson   @brief Set the data used by a `CeedQFunctionContext`, freeing any previously allocated data if applicable.
5934385fb7fSSebastian Grimberg 
594*ca94c3ddSJeremy L Thompson   The backend may copy values to a different @ref CeedMemType, such as during @ref CeedQFunctionApply().
595777ff853SJeremy L Thompson   See also @ref CeedQFunctionContextTakeData().
596777ff853SJeremy L Thompson 
597*ca94c3ddSJeremy L Thompson   @param[in,out] ctx       `CeedQFunctionContext`
598ea61e9acSJeremy L Thompson   @param[in]     mem_type  Memory type of the data being passed
599ea61e9acSJeremy L Thompson   @param[in]     copy_mode Copy mode for the data
600ea61e9acSJeremy L Thompson   @param[in]     size      Size of data, in bytes
601ea61e9acSJeremy L Thompson   @param[in]     data      Data to be used
602777ff853SJeremy L Thompson 
603777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
604777ff853SJeremy L Thompson 
605777ff853SJeremy L Thompson   @ref User
606777ff853SJeremy L Thompson **/
6072b730f8bSJeremy L Thompson int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, size_t size, void *data) {
608*ca94c3ddSJeremy L Thompson   CeedCheck(ctx->SetData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextSetData");
6096574a04fSJeremy L Thompson   CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
610777ff853SJeremy L Thompson 
6112b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroyData(ctx));
612d1d35e2fSjeremylt   ctx->ctx_size = size;
6132b730f8bSJeremy L Thompson   CeedCall(ctx->SetData(ctx, mem_type, copy_mode, data));
614777ff853SJeremy L Thompson   ctx->state += 2;
615e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
616777ff853SJeremy L Thompson }
617777ff853SJeremy L Thompson 
618777ff853SJeremy L Thompson /**
619*ca94c3ddSJeremy L Thompson   @brief Take ownership of the data in a `CeedQFunctionContext` via the specified memory type.
6204385fb7fSSebastian Grimberg 
621891038deSjeremylt   The caller is responsible for managing and freeing the memory.
622891038deSjeremylt 
623*ca94c3ddSJeremy L Thompson   @param[in]  ctx      `CeedQFunctionContext` to access
624ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
625ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
626891038deSjeremylt   @param[out] data     Data on memory type mem_type
627891038deSjeremylt 
628891038deSjeremylt   @return An error code: 0 - success, otherwise - failure
629891038deSjeremylt 
630891038deSjeremylt   @ref User
631891038deSjeremylt **/
6322b730f8bSJeremy L Thompson int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
6331c66c397SJeremy L Thompson   void *temp_data      = NULL;
6341c66c397SJeremy L Thompson   bool  has_valid_data = true, has_borrowed_data_of_type = true;
6351c66c397SJeremy L Thompson 
6362b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
6376574a04fSJeremy L Thompson   CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to take, must set data");
6389c774eddSJeremy L Thompson 
639*ca94c3ddSJeremy L Thompson   CeedCheck(ctx->TakeData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextTakeData");
6406574a04fSJeremy L Thompson   CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
641891038deSjeremylt 
6422b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, &has_borrowed_data_of_type));
6436574a04fSJeremy L Thompson   CeedCheck(has_borrowed_data_of_type, ctx->ceed, CEED_ERROR_BACKEND,
6446574a04fSJeremy L Thompson             "CeedQFunctionContext has no borrowed %s data, must set data with CeedQFunctionContextSetData", CeedMemTypes[mem_type]);
6459c774eddSJeremy L Thompson 
6462b730f8bSJeremy L Thompson   CeedCall(ctx->TakeData(ctx, mem_type, &temp_data));
647891038deSjeremylt   if (data) (*(void **)data) = temp_data;
648891038deSjeremylt   return CEED_ERROR_SUCCESS;
649891038deSjeremylt }
650891038deSjeremylt 
651891038deSjeremylt /**
652*ca94c3ddSJeremy L Thompson   @brief Get read/write access to a `CeedQFunctionContext` via the specified memory type.
6534385fb7fSSebastian Grimberg 
654777ff853SJeremy L Thompson   Restore access with @ref CeedQFunctionContextRestoreData().
655777ff853SJeremy L Thompson 
656*ca94c3ddSJeremy L Thompson   @param[in]  ctx      `CeedQFunctionContext` to access
657ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
658ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
659d1d35e2fSjeremylt   @param[out] data     Data on memory type mem_type
660777ff853SJeremy L Thompson 
661*ca94c3ddSJeremy L Thompson   @note The @ref CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions provide access to array pointers in the desired memory space.
662*ca94c3ddSJeremy L Thompson         Pairing get/restore allows the `CeedQFunctionContext` to track access.
663777ff853SJeremy L Thompson 
664777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
665777ff853SJeremy L Thompson 
666777ff853SJeremy L Thompson   @ref User
667777ff853SJeremy L Thompson **/
6682b730f8bSJeremy L Thompson int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
6691c66c397SJeremy L Thompson   bool has_valid_data = true;
6701c66c397SJeremy L Thompson 
671*ca94c3ddSJeremy L Thompson   CeedCheck(ctx->GetData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextGetData");
6726574a04fSJeremy L Thompson   CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
6736574a04fSJeremy L Thompson   CeedCheck(ctx->num_readers == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, a process has read access");
67428bfd0b7SJeremy L Thompson 
6752b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
6766574a04fSJeremy L Thompson   CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data");
6779c774eddSJeremy L Thompson 
6782b730f8bSJeremy L Thompson   CeedCall(ctx->GetData(ctx, mem_type, data));
67928bfd0b7SJeremy L Thompson   ctx->state++;
68028bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
68128bfd0b7SJeremy L Thompson }
68228bfd0b7SJeremy L Thompson 
68328bfd0b7SJeremy L Thompson /**
684*ca94c3ddSJeremy L Thompson   @brief Get read only access to a `CeedQFunctionContext` via the specified memory type.
6854385fb7fSSebastian Grimberg 
68628bfd0b7SJeremy L Thompson   Restore access with @ref CeedQFunctionContextRestoreData().
68728bfd0b7SJeremy L Thompson 
688*ca94c3ddSJeremy L Thompson   @param[in]  ctx      `CeedQFunctionContext` to access
689ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
690ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
69128bfd0b7SJeremy L Thompson   @param[out] data     Data on memory type mem_type
69228bfd0b7SJeremy L Thompson 
693*ca94c3ddSJeremy L Thompson   @note The @ref CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead() functions provide access to array pointers in the desired memory space.
694*ca94c3ddSJeremy L Thompson         Pairing get/restore allows the `CeedQFunctionContext` to track access.
69528bfd0b7SJeremy L Thompson 
69628bfd0b7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
69728bfd0b7SJeremy L Thompson 
69828bfd0b7SJeremy L Thompson   @ref User
69928bfd0b7SJeremy L Thompson **/
7002b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
7011c66c397SJeremy L Thompson   bool has_valid_data = true;
7021c66c397SJeremy L Thompson 
703*ca94c3ddSJeremy L Thompson   CeedCheck(ctx->GetDataRead, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextGetDataRead");
7046574a04fSJeremy L Thompson   CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
70528bfd0b7SJeremy L Thompson 
7062b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
7076574a04fSJeremy L Thompson   CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data");
70828bfd0b7SJeremy L Thompson 
7092b730f8bSJeremy L Thompson   CeedCall(ctx->GetDataRead(ctx, mem_type, data));
71028bfd0b7SJeremy L Thompson   ctx->num_readers++;
711e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
712777ff853SJeremy L Thompson }
713777ff853SJeremy L Thompson 
714777ff853SJeremy L Thompson /**
715777ff853SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetData()
716777ff853SJeremy L Thompson 
717*ca94c3ddSJeremy L Thompson   @param[in]     ctx  `CeedQFunctionContext` to restore
718ea61e9acSJeremy L Thompson   @param[in,out] data Data to restore
719777ff853SJeremy L Thompson 
720777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
721777ff853SJeremy L Thompson 
722777ff853SJeremy L Thompson   @ref User
723777ff853SJeremy L Thompson **/
724777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) {
7256574a04fSJeremy L Thompson   CeedCheck(ctx->state % 2 == 1, ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted");
726777ff853SJeremy L Thompson 
7276574a04fSJeremy L Thompson   if (ctx->RestoreData) CeedCall(ctx->RestoreData(ctx));
728777ff853SJeremy L Thompson   *(void **)data = NULL;
72928bfd0b7SJeremy L Thompson   ctx->state++;
73028bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
73128bfd0b7SJeremy L Thompson }
73228bfd0b7SJeremy L Thompson 
73328bfd0b7SJeremy L Thompson /**
73428bfd0b7SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead()
73528bfd0b7SJeremy L Thompson 
736*ca94c3ddSJeremy L Thompson   @param[in]     ctx  `CeedQFunctionContext` to restore
737ea61e9acSJeremy L Thompson   @param[in,out] data Data to restore
73828bfd0b7SJeremy L Thompson 
73928bfd0b7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
74028bfd0b7SJeremy L Thompson 
74128bfd0b7SJeremy L Thompson   @ref User
74228bfd0b7SJeremy L Thompson **/
74328bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) {
7446574a04fSJeremy L Thompson   CeedCheck(ctx->num_readers > 0, ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted");
74528bfd0b7SJeremy L Thompson 
74675a19770SJeremy L Thompson   ctx->num_readers--;
7476574a04fSJeremy L Thompson   if (ctx->num_readers == 0 && ctx->RestoreDataRead) CeedCall(ctx->RestoreDataRead(ctx));
74828bfd0b7SJeremy L Thompson   *(void **)data = NULL;
749e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
750777ff853SJeremy L Thompson }
751777ff853SJeremy L Thompson 
752777ff853SJeremy L Thompson /**
753*ca94c3ddSJeremy L Thompson   @brief Register a `CeedQFunctionContext` field holding double precision values
754cdf32b93SJeremy L Thompson 
755*ca94c3ddSJeremy L Thompson   @param[in,out] ctx               `CeedQFunctionContext`
756ea61e9acSJeremy L Thompson   @param[in]     field_name        Name of field to register
757ea61e9acSJeremy L Thompson   @param[in]     field_offset      Offset of field to register
758ea61e9acSJeremy L Thompson   @param[in]     num_values        Number of values to register, must be contiguous in memory
759*ca94c3ddSJeremy L Thompson   @param[in]     field_description Description of field, or `NULL` for none
760cdf32b93SJeremy L Thompson 
761cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
762cdf32b93SJeremy L Thompson 
763cdf32b93SJeremy L Thompson   @ref User
764cdf32b93SJeremy L Thompson **/
7652b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values,
766cdf32b93SJeremy L Thompson                                        const char *field_description) {
7675b6ec284SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_DOUBLE, num_values);
768cdf32b93SJeremy L Thompson }
769cdf32b93SJeremy L Thompson 
770cdf32b93SJeremy L Thompson /**
771*ca94c3ddSJeremy L Thompson   @brief Register a `CeedQFunctionContext` field holding `int32` values
772cdf32b93SJeremy L Thompson 
773ea61e9acSJeremy L Thompson   @param[in,out] ctx               CeedQFunctionContext
774ea61e9acSJeremy L Thompson   @param[in]     field_name        Name of field to register
775ea61e9acSJeremy L Thompson   @param[in]     field_offset      Offset of field to register
776ea61e9acSJeremy L Thompson   @param[in]     num_values        Number of values to register, must be contiguous in memory
777*ca94c3ddSJeremy L Thompson   @param[in]     field_description Description of field, or `NULL` for none
778cdf32b93SJeremy L Thompson 
779cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
780cdf32b93SJeremy L Thompson 
781cdf32b93SJeremy L Thompson   @ref User
782cdf32b93SJeremy L Thompson **/
7832b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values,
784cdf32b93SJeremy L Thompson                                       const char *field_description) {
7855b6ec284SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_INT32, num_values);
7865b6ec284SJeremy L Thompson }
7875b6ec284SJeremy L Thompson 
7885b6ec284SJeremy L Thompson /**
789*ca94c3ddSJeremy L Thompson   @brief Register a `CeedQFunctionContext` field holding boolean values
7905b6ec284SJeremy L Thompson 
791*ca94c3ddSJeremy L Thompson   @param[in,out] ctx               `CeedQFunctionContext`
7925b6ec284SJeremy L Thompson   @param[in]     field_name        Name of field to register
7935b6ec284SJeremy L Thompson   @param[in]     field_offset      Offset of field to register
7945b6ec284SJeremy L Thompson   @param[in]     num_values        Number of values to register, must be contiguous in memory
795*ca94c3ddSJeremy L Thompson   @param[in]     field_description Description of field, or `NULL` for none
7965b6ec284SJeremy L Thompson 
7975b6ec284SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
7985b6ec284SJeremy L Thompson 
7995b6ec284SJeremy L Thompson   @ref User
8005b6ec284SJeremy L Thompson **/
8015b6ec284SJeremy L Thompson int CeedQFunctionContextRegisterBoolean(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values,
8025b6ec284SJeremy L Thompson                                         const char *field_description) {
8035b6ec284SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_BOOL, num_values);
804cdf32b93SJeremy L Thompson }
805cdf32b93SJeremy L Thompson 
806cdf32b93SJeremy L Thompson /**
807*ca94c3ddSJeremy L Thompson   @brief Get labels for all registered `CeedQFunctionContext` fields
808cdf32b93SJeremy L Thompson 
809*ca94c3ddSJeremy L Thompson   @param[in]  ctx          `CeedQFunctionContext`
8103668ca4bSJeremy L Thompson   @param[out] field_labels Variable to hold array of field labels
811cdf32b93SJeremy L Thompson   @param[out] num_fields   Length of field descriptions array
812cdf32b93SJeremy L Thompson 
813cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
814cdf32b93SJeremy L Thompson 
815cdf32b93SJeremy L Thompson   @ref User
816cdf32b93SJeremy L Thompson **/
8172b730f8bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, const CeedContextFieldLabel **field_labels, CeedInt *num_fields) {
8183668ca4bSJeremy L Thompson   *field_labels = ctx->field_labels;
819cdf32b93SJeremy L Thompson   *num_fields   = ctx->num_fields;
820cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
821cdf32b93SJeremy L Thompson }
822cdf32b93SJeremy L Thompson 
823cdf32b93SJeremy L Thompson /**
824*ca94c3ddSJeremy L Thompson   @brief Get the descriptive information about a `CeedContextFieldLabel`
8250f86cbe7SJeremy L Thompson 
826*ca94c3ddSJeremy L Thompson   @param[in]  label             @ref CeedContextFieldLabel
8270f86cbe7SJeremy L Thompson   @param[out] field_name        Name of labeled field
8281ff07f3dSJeremy L Thompson   @param[out] field_offset      Offset of field registered
8297bfe0f0eSJeremy L Thompson   @param[out] num_values        Number of values registered
8301ff07f3dSJeremy L Thompson   @param[out] field_description Description of field, or NULL for none
831*ca94c3ddSJeremy L Thompson   @param[out] field_type        @ref CeedContextFieldType
8320f86cbe7SJeremy L Thompson 
8330f86cbe7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
8340f86cbe7SJeremy L Thompson 
8350f86cbe7SJeremy L Thompson   @ref User
8360f86cbe7SJeremy L Thompson **/
8371ff07f3dSJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, const char **field_name, size_t *field_offset, size_t *num_values,
8381ff07f3dSJeremy L Thompson                                         const char **field_description, CeedContextFieldType *field_type) {
8390f86cbe7SJeremy L Thompson   if (field_name) *field_name = label->name;
8401ff07f3dSJeremy L Thompson   if (field_offset) *field_offset = label->offset;
8417bfe0f0eSJeremy L Thompson   if (num_values) *num_values = label->num_values;
8421ff07f3dSJeremy L Thompson   if (field_description) *field_description = label->description;
8430f86cbe7SJeremy L Thompson   if (field_type) *field_type = label->type;
8440f86cbe7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
8450f86cbe7SJeremy L Thompson }
8460f86cbe7SJeremy L Thompson 
8470f86cbe7SJeremy L Thompson /**
84880a9ef05SNatalie Beams   @brief Get data size for a Context
84980a9ef05SNatalie Beams 
850*ca94c3ddSJeremy L Thompson   @param[in]  ctx      `CeedQFunctionContext`
85180a9ef05SNatalie Beams   @param[out] ctx_size Variable to store size of context data values
85280a9ef05SNatalie Beams 
85380a9ef05SNatalie Beams   @return An error code: 0 - success, otherwise - failure
85480a9ef05SNatalie Beams 
85580a9ef05SNatalie Beams   @ref User
85680a9ef05SNatalie Beams **/
8572b730f8bSJeremy L Thompson int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, size_t *ctx_size) {
85880a9ef05SNatalie Beams   *ctx_size = ctx->ctx_size;
85980a9ef05SNatalie Beams   return CEED_ERROR_SUCCESS;
86080a9ef05SNatalie Beams }
86180a9ef05SNatalie Beams 
86280a9ef05SNatalie Beams /**
863*ca94c3ddSJeremy L Thompson   @brief View a `CeedQFunctionContext`
864777ff853SJeremy L Thompson 
865*ca94c3ddSJeremy L Thompson   @param[in] ctx    `CeedQFunctionContext` to view
866777ff853SJeremy L Thompson   @param[in] stream Filestream to write to
867777ff853SJeremy L Thompson 
868777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
869777ff853SJeremy L Thompson 
870777ff853SJeremy L Thompson   @ref User
871777ff853SJeremy L Thompson **/
872777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) {
873777ff853SJeremy L Thompson   fprintf(stream, "CeedQFunctionContext\n");
874d1d35e2fSjeremylt   fprintf(stream, "  Context Data Size: %ld\n", ctx->ctx_size);
8753668ca4bSJeremy L Thompson   for (CeedInt i = 0; i < ctx->num_fields; i++) {
8763668ca4bSJeremy L Thompson     // LCOV_EXCL_START
8772b730f8bSJeremy L Thompson     fprintf(stream, "  Labeled %s field: %s\n", CeedContextFieldTypes[ctx->field_labels[i]->type], ctx->field_labels[i]->name);
8783668ca4bSJeremy L Thompson     // LCOV_EXCL_STOP
8793668ca4bSJeremy L Thompson   }
880e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
881777ff853SJeremy L Thompson }
882777ff853SJeremy L Thompson 
883777ff853SJeremy L Thompson /**
884*ca94c3ddSJeremy L Thompson   @brief Set additional destroy routine for `CeedQFunctionContext` user data
8852790b72bSJeremy L Thompson 
886*ca94c3ddSJeremy L Thompson   @param[in,out] ctx        `CeedQFunctionContext` to set user destroy function
8872e64a2b9SJeremy L Thompson   @param[in]     f_mem_type Memory type to use when passing data into `f`
8882e64a2b9SJeremy L Thompson   @param[in]     f          Additional routine to use to destroy user data
8892790b72bSJeremy L Thompson 
8902790b72bSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
8912790b72bSJeremy L Thompson 
8922790b72bSJeremy L Thompson   @ref User
8932790b72bSJeremy L Thompson **/
8942b730f8bSJeremy L Thompson int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) {
8956574a04fSJeremy L Thompson   CeedCheck(f, ctx->ceed, 1, "Must provide valid callback function for destroying user data");
8962790b72bSJeremy L Thompson   ctx->data_destroy_mem_type = f_mem_type;
8972790b72bSJeremy L Thompson   ctx->data_destroy_function = f;
8982790b72bSJeremy L Thompson   return CEED_ERROR_SUCCESS;
8992790b72bSJeremy L Thompson }
9002790b72bSJeremy L Thompson 
9012790b72bSJeremy L Thompson /**
902*ca94c3ddSJeremy L Thompson   @brief Destroy a `CeedQFunctionContext`
903777ff853SJeremy L Thompson 
904*ca94c3ddSJeremy L Thompson   @param[in,out] ctx `CeedQFunctionContext` to destroy
905777ff853SJeremy L Thompson 
906777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
907777ff853SJeremy L Thompson 
908777ff853SJeremy L Thompson   @ref User
909777ff853SJeremy L Thompson **/
910777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) {
911ad6481ceSJeremy L Thompson   if (!*ctx || --(*ctx)->ref_count > 0) {
912ad6481ceSJeremy L Thompson     *ctx = NULL;
913ad6481ceSJeremy L Thompson     return CEED_ERROR_SUCCESS;
914ad6481ceSJeremy L Thompson   }
9156574a04fSJeremy L Thompson   CeedCheck(((*ctx)->state % 2) == 0, (*ctx)->ceed, 1, "Cannot destroy CeedQFunctionContext, the access lock is in use");
916777ff853SJeremy L Thompson 
9172b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroyData(*ctx));
9182b730f8bSJeremy L Thompson   if ((*ctx)->Destroy) CeedCall((*ctx)->Destroy(*ctx));
919cdf32b93SJeremy L Thompson   for (CeedInt i = 0; i < (*ctx)->num_fields; i++) {
9202b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]->name));
9212b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]->description));
9222b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]));
923cdf32b93SJeremy L Thompson   }
9242b730f8bSJeremy L Thompson   CeedCall(CeedFree(&(*ctx)->field_labels));
9252b730f8bSJeremy L Thompson   CeedCall(CeedDestroy(&(*ctx)->ceed));
9262b730f8bSJeremy L Thompson   CeedCall(CeedFree(ctx));
927e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
928777ff853SJeremy L Thompson }
929777ff853SJeremy L Thompson 
930777ff853SJeremy L Thompson /// @}
931