xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-qfunctioncontext.c (revision 1203703b5dc87b4acbe66c9a27384ca8ad07798d)
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 /**
26ca94c3ddSJeremy L Thompson   @brief Get index for `CeedQFunctionContext` field
27cdf32b93SJeremy L Thompson 
28ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
29ea61e9acSJeremy L Thompson   @param[in]  field_name  Name of field
30ca94c3ddSJeremy 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 /**
45ca94c3ddSJeremy L Thompson   @brief Common function for registering `CeedQFunctionContext` fields
46cdf32b93SJeremy L Thompson 
47ca94c3ddSJeremy 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
50ca94c3ddSJeremy L Thompson   @param[in]     field_description Description of field, or `NULL` for none
51ca94c3ddSJeremy 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;
62*1203703bSJeremy L Thompson   Ceed    ceed;
631c66c397SJeremy L Thompson 
641c66c397SJeremy L Thompson   // Check for duplicate
65*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
662b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index));
67*1203703bSJeremy L Thompson   CeedCheck(field_index == -1, ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" already registered", field_name);
68cdf32b93SJeremy L Thompson 
69cdf32b93SJeremy L Thompson   // Allocate space for field data
70cdf32b93SJeremy L Thompson   if (ctx->num_fields == 0) {
712b730f8bSJeremy L Thompson     CeedCall(CeedCalloc(1, &ctx->field_labels));
72cdf32b93SJeremy L Thompson     ctx->max_fields = 1;
73cdf32b93SJeremy L Thompson   } else if (ctx->num_fields == ctx->max_fields) {
742b730f8bSJeremy L Thompson     CeedCall(CeedRealloc(2 * ctx->max_fields, &ctx->field_labels));
75cdf32b93SJeremy L Thompson     ctx->max_fields *= 2;
76cdf32b93SJeremy L Thompson   }
772b730f8bSJeremy L Thompson   CeedCall(CeedCalloc(1, &ctx->field_labels[ctx->num_fields]));
78cdf32b93SJeremy L Thompson 
795b6ec284SJeremy L Thompson   // Compute field size
805b6ec284SJeremy L Thompson   switch (field_type) {
815b6ec284SJeremy L Thompson     case CEED_CONTEXT_FIELD_DOUBLE:
825b6ec284SJeremy L Thompson       field_size = sizeof(double);
835b6ec284SJeremy L Thompson       break;
845b6ec284SJeremy L Thompson     case CEED_CONTEXT_FIELD_INT32:
855b6ec284SJeremy L Thompson       field_size = sizeof(int);
865b6ec284SJeremy L Thompson       break;
875b6ec284SJeremy L Thompson     case CEED_CONTEXT_FIELD_BOOL:
885b6ec284SJeremy L Thompson       field_size = sizeof(bool);
895b6ec284SJeremy L Thompson       break;
905b6ec284SJeremy L Thompson   }
915b6ec284SJeremy L Thompson 
92cdf32b93SJeremy L Thompson   // Copy field data
932b730f8bSJeremy L Thompson   CeedCall(CeedStringAllocCopy(field_name, (char **)&ctx->field_labels[ctx->num_fields]->name));
942b730f8bSJeremy L Thompson   CeedCall(CeedStringAllocCopy(field_description, (char **)&ctx->field_labels[ctx->num_fields]->description));
953668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->type       = field_type;
963668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->offset     = field_offset;
977bfe0f0eSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->size       = field_size * num_values;
987bfe0f0eSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->num_values = num_values;
99cdf32b93SJeremy L Thompson   ctx->num_fields++;
100cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
101cdf32b93SJeremy L Thompson }
102cdf32b93SJeremy L Thompson 
1033b190ab8SJeremy L Thompson /**
104ca94c3ddSJeremy L Thompson   @brief Destroy user data held by `CeedQFunctionContext`, using function set by @ref CeedQFunctionContextSetDataDestroy(), if applicable
1053b190ab8SJeremy L Thompson 
106ca94c3ddSJeremy L Thompson   @param[in,out] ctx `CeedQFunctionContext` to destroy user data
1073b190ab8SJeremy L Thompson 
1083b190ab8SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1093b190ab8SJeremy L Thompson 
1103b190ab8SJeremy L Thompson   @ref Developer
1113b190ab8SJeremy L Thompson **/
1123b190ab8SJeremy L Thompson static int CeedQFunctionContextDestroyData(CeedQFunctionContext ctx) {
1133b190ab8SJeremy L Thompson   if (ctx->DataDestroy) {
1142b730f8bSJeremy L Thompson     CeedCall(ctx->DataDestroy(ctx));
1153b190ab8SJeremy L Thompson   } else {
1163b190ab8SJeremy L Thompson     CeedMemType                         data_destroy_mem_type;
1171c66c397SJeremy L Thompson     CeedQFunctionContextDataDestroyUser data_destroy_function;
1183b190ab8SJeremy L Thompson 
1192b730f8bSJeremy L Thompson     CeedCall(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function));
1203b190ab8SJeremy L Thompson     if (data_destroy_function) {
1213b190ab8SJeremy L Thompson       void *data;
1223b190ab8SJeremy L Thompson 
1232b730f8bSJeremy L Thompson       CeedCall(CeedQFunctionContextGetData(ctx, data_destroy_mem_type, &data));
1242b730f8bSJeremy L Thompson       CeedCall(data_destroy_function(data));
1252b730f8bSJeremy L Thompson       CeedCall(CeedQFunctionContextRestoreData(ctx, &data));
1263b190ab8SJeremy L Thompson     }
1273b190ab8SJeremy L Thompson   }
1283b190ab8SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1293b190ab8SJeremy L Thompson }
1303b190ab8SJeremy L Thompson 
131cdf32b93SJeremy L Thompson /// @}
132cdf32b93SJeremy L Thompson 
133cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
134777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API
135777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
136777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend
137777ff853SJeremy L Thompson /// @{
138777ff853SJeremy L Thompson 
139777ff853SJeremy L Thompson /**
140ca94c3ddSJeremy L Thompson   @brief Get the `Ceed` associated with a `CeedQFunctionContext`
141777ff853SJeremy L Thompson 
142ca94c3ddSJeremy L Thompson   @param[in]  ctx  `CeedQFunctionContext`
143ca94c3ddSJeremy L Thompson   @param[out] ceed Variable to store `Ceed`
144777ff853SJeremy L Thompson 
145777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
146777ff853SJeremy L Thompson 
147777ff853SJeremy L Thompson   @ref Backend
148777ff853SJeremy L Thompson **/
149777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) {
150777ff853SJeremy L Thompson   *ceed = ctx->ceed;
151e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
152777ff853SJeremy L Thompson }
153777ff853SJeremy L Thompson 
154777ff853SJeremy L Thompson /**
155ca94c3ddSJeremy L Thompson   @brief Check for valid data in a `CeedQFunctionContext`
1569c774eddSJeremy L Thompson 
157ca94c3ddSJeremy L Thompson   @param[in]  ctx            `CeedQFunctionContext` to check validity
1589c774eddSJeremy L Thompson   @param[out] has_valid_data Variable to store validity
1599c774eddSJeremy L Thompson 
1609c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1619c774eddSJeremy L Thompson 
1629c774eddSJeremy L Thompson   @ref Backend
1639c774eddSJeremy L Thompson **/
1642b730f8bSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx, bool *has_valid_data) {
165ca94c3ddSJeremy L Thompson   CeedCheck(ctx->HasValidData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextHasValidData");
1662b730f8bSJeremy L Thompson   CeedCall(ctx->HasValidData(ctx, has_valid_data));
1679c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1689c774eddSJeremy L Thompson }
1699c774eddSJeremy L Thompson 
1709c774eddSJeremy L Thompson /**
171ca94c3ddSJeremy L Thompson   @brief Check for borrowed data of a specific @ref CeedMemType in a `CeedQFunctionContext`
1729c774eddSJeremy L Thompson 
173ca94c3ddSJeremy L Thompson   @param[in]  ctx                       `CeedQFunctionContext` to check
174ea61e9acSJeremy L Thompson   @param[in]  mem_type                  Memory type to check
1759c774eddSJeremy L Thompson   @param[out] has_borrowed_data_of_type Variable to store result
1769c774eddSJeremy L Thompson 
1779c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1789c774eddSJeremy L Thompson 
1799c774eddSJeremy L Thompson   @ref Backend
1809c774eddSJeremy L Thompson **/
1812b730f8bSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx, CeedMemType mem_type, bool *has_borrowed_data_of_type) {
182ca94c3ddSJeremy L Thompson   CeedCheck(ctx->HasBorrowedDataOfType, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextHasBorrowedDataOfType");
1832b730f8bSJeremy L Thompson   CeedCall(ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type));
1849c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1859c774eddSJeremy L Thompson }
1869c774eddSJeremy L Thompson 
1879c774eddSJeremy L Thompson /**
188ca94c3ddSJeremy L Thompson   @brief Get the state of a `CeedQFunctionContext`
189777ff853SJeremy L Thompson 
190ca94c3ddSJeremy L Thompson   @param[in]  ctx   `CeedQFunctionContext` to retrieve state
191777ff853SJeremy L Thompson   @param[out] state Variable to store state
192777ff853SJeremy L Thompson 
193777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
194777ff853SJeremy L Thompson 
195777ff853SJeremy L Thompson   @ref Backend
196777ff853SJeremy L Thompson **/
197777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) {
198777ff853SJeremy L Thompson   *state = ctx->state;
199e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
200777ff853SJeremy L Thompson }
201777ff853SJeremy L Thompson 
202777ff853SJeremy L Thompson /**
203ca94c3ddSJeremy L Thompson   @brief Get backend data of a `CeedQFunctionContext`
204777ff853SJeremy L Thompson 
205ca94c3ddSJeremy L Thompson   @param[in]  ctx  `CeedQFunctionContext`
206777ff853SJeremy L Thompson   @param[out] data Variable to store data
207777ff853SJeremy L Thompson 
208777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
209777ff853SJeremy L Thompson 
210777ff853SJeremy L Thompson   @ref Backend
211777ff853SJeremy L Thompson **/
212777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) {
213777ff853SJeremy L Thompson   *(void **)data = ctx->data;
214e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
215777ff853SJeremy L Thompson }
216777ff853SJeremy L Thompson 
217777ff853SJeremy L Thompson /**
218ca94c3ddSJeremy L Thompson   @brief Set backend data of a `CeedQFunctionContext`
219777ff853SJeremy L Thompson 
220ca94c3ddSJeremy L Thompson   @param[in,out] ctx  `CeedQFunctionContext`
221ea61e9acSJeremy L Thompson   @param[in]     data Data to set
222777ff853SJeremy L Thompson 
223777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
224777ff853SJeremy L Thompson 
225777ff853SJeremy L Thompson   @ref Backend
226777ff853SJeremy L Thompson **/
227777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) {
228777ff853SJeremy L Thompson   ctx->data = data;
229e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
230777ff853SJeremy L Thompson }
231777ff853SJeremy L Thompson 
23234359f16Sjeremylt /**
233ca94c3ddSJeremy L Thompson   @brief Get label for a registered `CeedQFunctionContext` field, or `NULL` if no field has been registered with this `field_name`
234e6a0ab89SJeremy L Thompson 
235ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
236e6a0ab89SJeremy L Thompson   @param[in]  field_name  Name of field to retrieve label
237e6a0ab89SJeremy L Thompson   @param[out] field_label Variable to field label
238e6a0ab89SJeremy L Thompson 
239e6a0ab89SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
240e6a0ab89SJeremy L Thompson 
2413e1e85abSJeremy L Thompson   @ref Backend
242e6a0ab89SJeremy L Thompson **/
2432b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx, const char *field_name, CeedContextFieldLabel *field_label) {
244e6a0ab89SJeremy L Thompson   CeedInt field_index;
2451c66c397SJeremy L Thompson 
2462b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index));
247e6a0ab89SJeremy L Thompson 
248e6a0ab89SJeremy L Thompson   if (field_index != -1) {
249e6a0ab89SJeremy L Thompson     *field_label = ctx->field_labels[field_index];
250e6a0ab89SJeremy L Thompson   } else {
251e6a0ab89SJeremy L Thompson     *field_label = NULL;
252e6a0ab89SJeremy L Thompson   }
253e6a0ab89SJeremy L Thompson   return CEED_ERROR_SUCCESS;
254e6a0ab89SJeremy L Thompson }
255e6a0ab89SJeremy L Thompson 
256e6a0ab89SJeremy L Thompson /**
257ca94c3ddSJeremy L Thompson   @brief Set `CeedQFunctionContext` field
258d8dd9a91SJeremy L Thompson 
259ca94c3ddSJeremy L Thompson   @param[in,out] ctx         `CeedQFunctionContext`
260ea61e9acSJeremy L Thompson   @param[in]     field_label Label of field to set
261ea61e9acSJeremy L Thompson   @param[in]     field_type  Type of field to set
2622788fa27SJeremy L Thompson   @param[in]     values      Value to set
263d8dd9a91SJeremy L Thompson 
264d8dd9a91SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
265d8dd9a91SJeremy L Thompson 
2663e1e85abSJeremy L Thompson   @ref Backend
267d8dd9a91SJeremy L Thompson **/
2682788fa27SJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *values) {
2691a34d7dcSJeremy L Thompson   bool  is_different;
2701c66c397SJeremy L Thompson   char *data;
271*1203703bSJeremy L Thompson   Ceed  ceed;
2721c66c397SJeremy L Thompson 
2733668ca4bSJeremy L Thompson   // Check field type
274*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
275*1203703bSJeremy L Thompson   CeedCheck(field_label->type == field_type, ceed, CEED_ERROR_UNSUPPORTED,
2766574a04fSJeremy L Thompson             "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name,
2776574a04fSJeremy L Thompson             CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
278d8dd9a91SJeremy L Thompson 
2791a34d7dcSJeremy L Thompson   CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data));
2801a34d7dcSJeremy L Thompson   is_different = memcmp(&data[field_label->offset], values, field_label->size);
2811a34d7dcSJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreDataRead(ctx, &data));
2821a34d7dcSJeremy L Thompson   if (is_different) {
2832b730f8bSJeremy L Thompson     CeedCall(CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data));
2842788fa27SJeremy L Thompson     memcpy(&data[field_label->offset], values, field_label->size);
2852b730f8bSJeremy L Thompson     CeedCall(CeedQFunctionContextRestoreData(ctx, &data));
2861a34d7dcSJeremy L Thompson   }
287d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
288d8dd9a91SJeremy L Thompson }
289d8dd9a91SJeremy L Thompson 
290d8dd9a91SJeremy L Thompson /**
291ca94c3ddSJeremy L Thompson   @brief Get `CeedQFunctionContext` field data, read-only
2922788fa27SJeremy L Thompson 
293ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
2942788fa27SJeremy L Thompson   @param[in]  field_label Label of field to read
2952788fa27SJeremy L Thompson   @param[in]  field_type  Type of field to read
2962788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
2972788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
2982788fa27SJeremy L Thompson 
2992788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
3002788fa27SJeremy L Thompson 
3012788fa27SJeremy L Thompson   @ref Backend
3022788fa27SJeremy L Thompson **/
3032788fa27SJeremy L Thompson int CeedQFunctionContextGetGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type,
3042788fa27SJeremy L Thompson                                        size_t *num_values, void *values) {
3051c66c397SJeremy L Thompson   char *data;
306*1203703bSJeremy L Thompson   Ceed  ceed;
3071c66c397SJeremy L Thompson 
3082788fa27SJeremy L Thompson   // Check field type
309*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
310*1203703bSJeremy L Thompson   CeedCheck(field_label->type == field_type, ceed, CEED_ERROR_UNSUPPORTED,
3116574a04fSJeremy L Thompson             "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name,
3126574a04fSJeremy L Thompson             CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
3132788fa27SJeremy L Thompson 
3142788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data));
3152788fa27SJeremy L Thompson   *(void **)values = &data[field_label->offset];
3162788fa27SJeremy L Thompson   switch (field_type) {
3172788fa27SJeremy L Thompson     case CEED_CONTEXT_FIELD_INT32:
3182788fa27SJeremy L Thompson       *num_values = field_label->size / sizeof(int);
3192788fa27SJeremy L Thompson       break;
3202788fa27SJeremy L Thompson     case CEED_CONTEXT_FIELD_DOUBLE:
3212788fa27SJeremy L Thompson       *num_values = field_label->size / sizeof(double);
3222788fa27SJeremy L Thompson       break;
3235b6ec284SJeremy L Thompson     case CEED_CONTEXT_FIELD_BOOL:
3245b6ec284SJeremy L Thompson       *num_values = field_label->size / sizeof(bool);
3255b6ec284SJeremy L Thompson       break;
3262788fa27SJeremy L Thompson   }
3272788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3282788fa27SJeremy L Thompson }
3292788fa27SJeremy L Thompson 
3302788fa27SJeremy L Thompson /**
331ca94c3ddSJeremy L Thompson   @brief Restore `CeedQFunctionContext` field data, read-only
3322788fa27SJeremy L Thompson 
333ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
3342788fa27SJeremy L Thompson   @param[in]  field_label Label of field to restore
3352788fa27SJeremy L Thompson   @param[in]  field_type  Type of field to restore
3362788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
3372788fa27SJeremy L Thompson 
3382788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
3392788fa27SJeremy L Thompson 
3402788fa27SJeremy L Thompson   @ref Backend
3412788fa27SJeremy L Thompson **/
3422788fa27SJeremy L Thompson int CeedQFunctionContextRestoreGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type,
3432788fa27SJeremy L Thompson                                            void *values) {
344*1203703bSJeremy L Thompson   Ceed ceed;
345*1203703bSJeremy L Thompson 
3462788fa27SJeremy L Thompson   // Check field type
347*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
348*1203703bSJeremy L Thompson   CeedCheck(field_label->type == field_type, ceed, CEED_ERROR_UNSUPPORTED,
3496574a04fSJeremy L Thompson             "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name,
3506574a04fSJeremy L Thompson             CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
3512788fa27SJeremy L Thompson 
3522788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreDataRead(ctx, values));
3532788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3542788fa27SJeremy L Thompson }
3552788fa27SJeremy L Thompson 
3562788fa27SJeremy L Thompson /**
357ca94c3ddSJeremy L Thompson   @brief Set `CeedQFunctionContext` field holding double precision values
358bfacc300SJeremy L Thompson 
359ca94c3ddSJeremy L Thompson   @param[in,out] ctx         `CeedQFunctionContext`
3602788fa27SJeremy L Thompson   @param[in]     field_label Label for field to set
361ea61e9acSJeremy L Thompson   @param[in]     values      Values to set
362bfacc300SJeremy L Thompson 
363bfacc300SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
364bfacc300SJeremy L Thompson 
3653e1e85abSJeremy L Thompson   @ref Backend
366bfacc300SJeremy L Thompson **/
3672b730f8bSJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, double *values) {
368*1203703bSJeremy L Thompson   Ceed ceed;
369*1203703bSJeremy L Thompson 
370*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
371*1203703bSJeremy L Thompson   CeedCheck(field_label, ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
3722b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values));
373bfacc300SJeremy L Thompson   return CEED_ERROR_SUCCESS;
374bfacc300SJeremy L Thompson }
375bfacc300SJeremy L Thompson 
376bfacc300SJeremy L Thompson /**
377ca94c3ddSJeremy L Thompson   @brief Get `CeedQFunctionContext` field holding double precision values, read-only
3782788fa27SJeremy L Thompson 
379ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
3802788fa27SJeremy L Thompson   @param[in]  field_label Label for field to get
3812788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
3822788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
3832788fa27SJeremy L Thompson 
3842788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
3852788fa27SJeremy L Thompson 
3862788fa27SJeremy L Thompson   @ref Backend
3872788fa27SJeremy L Thompson **/
3882788fa27SJeremy L Thompson int CeedQFunctionContextGetDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const double **values) {
389*1203703bSJeremy L Thompson   Ceed ceed;
390*1203703bSJeremy L Thompson 
391*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
392*1203703bSJeremy L Thompson   CeedCheck(field_label, ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
3932788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values));
3942788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3952788fa27SJeremy L Thompson }
3962788fa27SJeremy L Thompson 
3972788fa27SJeremy L Thompson /**
398ca94c3ddSJeremy L Thompson   @brief Restore `CeedQFunctionContext` field holding double precision values, read-only
3992788fa27SJeremy L Thompson 
400ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
4012788fa27SJeremy L Thompson   @param[in]  field_label Label for field to restore
4022788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
4032788fa27SJeremy L Thompson 
4042788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4052788fa27SJeremy L Thompson 
4062788fa27SJeremy L Thompson   @ref Backend
4072788fa27SJeremy L Thompson **/
4082788fa27SJeremy L Thompson int CeedQFunctionContextRestoreDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const double **values) {
409*1203703bSJeremy L Thompson   Ceed ceed;
410*1203703bSJeremy L Thompson 
411*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
412*1203703bSJeremy L Thompson   CeedCheck(field_label, ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
4132788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values));
4142788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4152788fa27SJeremy L Thompson }
4162788fa27SJeremy L Thompson 
4172788fa27SJeremy L Thompson /**
418ca94c3ddSJeremy L Thompson   @brief Set CeedQFunctionContext field holding `int32` values
419bfacc300SJeremy L Thompson 
420ea61e9acSJeremy L Thompson   @param[in,out] ctx         CeedQFunctionContext
4212788fa27SJeremy L Thompson   @param[in]     field_label Label for field to set
422ea61e9acSJeremy L Thompson   @param[in]     values      Values to set
423bfacc300SJeremy L Thompson 
424bfacc300SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
425bfacc300SJeremy L Thompson 
4263e1e85abSJeremy L Thompson   @ref Backend
427bfacc300SJeremy L Thompson **/
42823dbfd29SJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, int32_t *values) {
429*1203703bSJeremy L Thompson   Ceed ceed;
430*1203703bSJeremy L Thompson 
431*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
432*1203703bSJeremy L Thompson   CeedCheck(field_label, ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
4332b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values));
434bfacc300SJeremy L Thompson   return CEED_ERROR_SUCCESS;
435bfacc300SJeremy L Thompson }
436bfacc300SJeremy L Thompson 
437bfacc300SJeremy L Thompson /**
438ca94c3ddSJeremy L Thompson   @brief Get `CeedQFunctionContext` field holding `int32` values, read-only
4392788fa27SJeremy L Thompson 
440ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
4412788fa27SJeremy L Thompson   @param[in]  field_label Label for field to get
4422788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
4432788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
4442788fa27SJeremy L Thompson 
4452788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4462788fa27SJeremy L Thompson 
4472788fa27SJeremy L Thompson   @ref Backend
4482788fa27SJeremy L Thompson **/
44923dbfd29SJeremy L Thompson int CeedQFunctionContextGetInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const int32_t **values) {
450*1203703bSJeremy L Thompson   Ceed ceed;
451*1203703bSJeremy L Thompson 
452*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
453*1203703bSJeremy L Thompson   CeedCheck(field_label, ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
4542788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values));
4552788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4562788fa27SJeremy L Thompson }
4572788fa27SJeremy L Thompson 
4582788fa27SJeremy L Thompson /**
459ca94c3ddSJeremy L Thompson   @brief Restore `CeedQFunctionContext` field holding `int32` values, read-only
4602788fa27SJeremy L Thompson 
461ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
4622788fa27SJeremy L Thompson   @param[in]  field_label Label for field to restore
4632788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
4642788fa27SJeremy L Thompson 
4652788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4662788fa27SJeremy L Thompson 
4672788fa27SJeremy L Thompson   @ref Backend
4682788fa27SJeremy L Thompson **/
46923dbfd29SJeremy L Thompson int CeedQFunctionContextRestoreInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const int32_t **values) {
470*1203703bSJeremy L Thompson   Ceed ceed;
471*1203703bSJeremy L Thompson 
472*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
473*1203703bSJeremy L Thompson   CeedCheck(field_label, ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
4742788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values));
4752788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4762788fa27SJeremy L Thompson }
4772788fa27SJeremy L Thompson 
4782788fa27SJeremy L Thompson /**
479ca94c3ddSJeremy L Thompson   @brief Set `CeedQFunctionContext` field holding boolean values
4805b6ec284SJeremy L Thompson 
481ca94c3ddSJeremy L Thompson   @param[in,out] ctx         `CeedQFunctionContext`
4825b6ec284SJeremy L Thompson   @param[in]     field_label Label for field to set
4835b6ec284SJeremy L Thompson   @param[in]     values      Values to set
4845b6ec284SJeremy L Thompson 
4855b6ec284SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4865b6ec284SJeremy L Thompson 
4875b6ec284SJeremy L Thompson   @ref Backend
4885b6ec284SJeremy L Thompson **/
4895b6ec284SJeremy L Thompson int CeedQFunctionContextSetBoolean(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, bool *values) {
490*1203703bSJeremy L Thompson   Ceed ceed;
491*1203703bSJeremy L Thompson 
492*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
493*1203703bSJeremy L Thompson   CeedCheck(field_label, ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
4945b6ec284SJeremy L Thompson   CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, values));
4955b6ec284SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4965b6ec284SJeremy L Thompson }
4975b6ec284SJeremy L Thompson 
4985b6ec284SJeremy L Thompson /**
499ca94c3ddSJeremy L Thompson   @brief Get `CeedQFunctionContext` field holding boolean values, read-only
5005b6ec284SJeremy L Thompson 
501ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
5025b6ec284SJeremy L Thompson   @param[in]  field_label Label for field to get
5035b6ec284SJeremy L Thompson   @param[out] num_values  Number of values in the field label
5045b6ec284SJeremy L Thompson   @param[out] values      Pointer to context values
5055b6ec284SJeremy L Thompson 
5065b6ec284SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
5075b6ec284SJeremy L Thompson 
5085b6ec284SJeremy L Thompson   @ref Backend
5095b6ec284SJeremy L Thompson **/
5105b6ec284SJeremy L Thompson int CeedQFunctionContextGetBooleanRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const bool **values) {
511*1203703bSJeremy L Thompson   Ceed ceed;
512*1203703bSJeremy L Thompson 
513*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
514*1203703bSJeremy L Thompson   CeedCheck(field_label, ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
5155b6ec284SJeremy L Thompson   CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, num_values, values));
5165b6ec284SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5175b6ec284SJeremy L Thompson }
5185b6ec284SJeremy L Thompson 
5195b6ec284SJeremy L Thompson /**
520ca94c3ddSJeremy L Thompson   @brief Restore `CeedQFunctionContext` field holding boolean values, read-only
5215b6ec284SJeremy L Thompson 
522ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
5235b6ec284SJeremy L Thompson   @param[in]  field_label Label for field to restore
5245b6ec284SJeremy L Thompson   @param[out] values      Pointer to context values
5255b6ec284SJeremy L Thompson 
5265b6ec284SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
5275b6ec284SJeremy L Thompson 
5285b6ec284SJeremy L Thompson   @ref Backend
5295b6ec284SJeremy L Thompson **/
5305b6ec284SJeremy L Thompson int CeedQFunctionContextRestoreBooleanRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const bool **values) {
531*1203703bSJeremy L Thompson   Ceed ceed;
532*1203703bSJeremy L Thompson 
533*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
534*1203703bSJeremy L Thompson   CeedCheck(field_label, ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
5355b6ec284SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, values));
5365b6ec284SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5375b6ec284SJeremy L Thompson }
5385b6ec284SJeremy L Thompson 
5395b6ec284SJeremy L Thompson /**
540ca94c3ddSJeremy L Thompson   @brief Get additional destroy routine for `CeedQFunctionContext` user data
5412e64a2b9SJeremy L Thompson 
542ca94c3ddSJeremy L Thompson   @param[in] ctx         `CeedQFunctionContext` to get user destroy function
5432e64a2b9SJeremy L Thompson   @param[out] f_mem_type Memory type to use when passing data into `f`
5442e64a2b9SJeremy L Thompson   @param[out] f          Additional routine to use to destroy user data
5452e64a2b9SJeremy L Thompson 
5462e64a2b9SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
5472e64a2b9SJeremy L Thompson 
5482e64a2b9SJeremy L Thompson   @ref Backend
5492e64a2b9SJeremy L Thompson **/
5502b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx, CeedMemType *f_mem_type, CeedQFunctionContextDataDestroyUser *f) {
5512e64a2b9SJeremy L Thompson   if (f_mem_type) *f_mem_type = ctx->data_destroy_mem_type;
5522e64a2b9SJeremy L Thompson   if (f) *f = ctx->data_destroy_function;
5532e64a2b9SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5542e64a2b9SJeremy L Thompson }
5552e64a2b9SJeremy L Thompson 
5562e64a2b9SJeremy L Thompson /**
557ca94c3ddSJeremy L Thompson   @brief Increment the reference counter for a `CeedQFunctionContext`
55834359f16Sjeremylt 
559ca94c3ddSJeremy L Thompson   @param[in,out] ctx `CeedQFunctionContext` to increment the reference counter
56034359f16Sjeremylt 
56134359f16Sjeremylt   @return An error code: 0 - success, otherwise - failure
56234359f16Sjeremylt 
56334359f16Sjeremylt   @ref Backend
56434359f16Sjeremylt **/
5659560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) {
56634359f16Sjeremylt   ctx->ref_count++;
56734359f16Sjeremylt   return CEED_ERROR_SUCCESS;
56834359f16Sjeremylt }
56934359f16Sjeremylt 
570777ff853SJeremy L Thompson /// @}
571777ff853SJeremy L Thompson 
572777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
573777ff853SJeremy L Thompson /// CeedQFunctionContext Public API
574777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
575777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser
576777ff853SJeremy L Thompson /// @{
577777ff853SJeremy L Thompson 
578777ff853SJeremy L Thompson /**
579ca94c3ddSJeremy L Thompson   @brief Create a `CeedQFunctionContext` for storing `CeedQFunctionContext` user context data
580777ff853SJeremy L Thompson 
581ca94c3ddSJeremy L Thompson   @param[in]  ceed `Ceed` object used to create the `CeedQFunctionContext`
582ca94c3ddSJeremy L Thompson   @param[out] ctx  Address of the variable where the newly created `CeedQFunctionContext` will be stored
583777ff853SJeremy L Thompson 
584777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
585777ff853SJeremy L Thompson 
586777ff853SJeremy L Thompson   @ref User
587777ff853SJeremy L Thompson **/
588777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) {
589777ff853SJeremy L Thompson   if (!ceed->QFunctionContextCreate) {
590777ff853SJeremy L Thompson     Ceed delegate;
5916574a04fSJeremy L Thompson 
5922b730f8bSJeremy L Thompson     CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Context"));
593ca94c3ddSJeremy L Thompson     CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextCreate");
5942b730f8bSJeremy L Thompson     CeedCall(CeedQFunctionContextCreate(delegate, ctx));
595e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
596777ff853SJeremy L Thompson   }
597777ff853SJeremy L Thompson 
5982b730f8bSJeremy L Thompson   CeedCall(CeedCalloc(1, ctx));
599db002c03SJeremy L Thompson   CeedCall(CeedReferenceCopy(ceed, &(*ctx)->ceed));
600d1d35e2fSjeremylt   (*ctx)->ref_count = 1;
6012b730f8bSJeremy L Thompson   CeedCall(ceed->QFunctionContextCreate(*ctx));
602e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
603777ff853SJeremy L Thompson }
604777ff853SJeremy L Thompson 
605777ff853SJeremy L Thompson /**
606ca94c3ddSJeremy L Thompson   @brief Copy the pointer to a `CeedQFunctionContext`.
6074385fb7fSSebastian Grimberg 
608ca94c3ddSJeremy L Thompson   Both pointers should be destroyed with @ref CeedQFunctionContextDestroy().
609512bb800SJeremy L Thompson 
610ca94c3ddSJeremy 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`.
611ca94c3ddSJeremy L Thompson         This `CeedQFunctionContext` will be destroyed if `*ctx_copy` is the only reference to this `CeedQFunctionContext`.
6129560d06aSjeremylt 
613ea61e9acSJeremy L Thompson   @param[in]     ctx      CeedQFunctionContext to copy reference to
614ea61e9acSJeremy L Thompson   @param[in,out] ctx_copy Variable to store copied reference
6159560d06aSjeremylt 
6169560d06aSjeremylt   @return An error code: 0 - success, otherwise - failure
6179560d06aSjeremylt 
6189560d06aSjeremylt   @ref User
6199560d06aSjeremylt **/
6202b730f8bSJeremy L Thompson int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, CeedQFunctionContext *ctx_copy) {
6212b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextReference(ctx));
6222b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroy(ctx_copy));
6239560d06aSjeremylt   *ctx_copy = ctx;
6249560d06aSjeremylt   return CEED_ERROR_SUCCESS;
6259560d06aSjeremylt }
6269560d06aSjeremylt 
6279560d06aSjeremylt /**
628ca94c3ddSJeremy L Thompson   @brief Set the data used by a `CeedQFunctionContext`, freeing any previously allocated data if applicable.
6294385fb7fSSebastian Grimberg 
630ca94c3ddSJeremy L Thompson   The backend may copy values to a different @ref CeedMemType, such as during @ref CeedQFunctionApply().
631777ff853SJeremy L Thompson   See also @ref CeedQFunctionContextTakeData().
632777ff853SJeremy L Thompson 
633ca94c3ddSJeremy L Thompson   @param[in,out] ctx       `CeedQFunctionContext`
634ea61e9acSJeremy L Thompson   @param[in]     mem_type  Memory type of the data being passed
635ea61e9acSJeremy L Thompson   @param[in]     copy_mode Copy mode for the data
636ea61e9acSJeremy L Thompson   @param[in]     size      Size of data, in bytes
637ea61e9acSJeremy L Thompson   @param[in]     data      Data to be used
638777ff853SJeremy L Thompson 
639777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
640777ff853SJeremy L Thompson 
641777ff853SJeremy L Thompson   @ref User
642777ff853SJeremy L Thompson **/
6432b730f8bSJeremy L Thompson int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, size_t size, void *data) {
644*1203703bSJeremy L Thompson   Ceed ceed;
645*1203703bSJeremy L Thompson 
646*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
647*1203703bSJeremy L Thompson   CeedCheck(ctx->SetData, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextSetData");
648*1203703bSJeremy L Thompson   CeedCheck(ctx->state % 2 == 0, ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
649777ff853SJeremy L Thompson 
6502b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroyData(ctx));
651d1d35e2fSjeremylt   ctx->ctx_size = size;
6522b730f8bSJeremy L Thompson   CeedCall(ctx->SetData(ctx, mem_type, copy_mode, data));
653777ff853SJeremy L Thompson   ctx->state += 2;
654e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
655777ff853SJeremy L Thompson }
656777ff853SJeremy L Thompson 
657777ff853SJeremy L Thompson /**
658ca94c3ddSJeremy L Thompson   @brief Take ownership of the data in a `CeedQFunctionContext` via the specified memory type.
6594385fb7fSSebastian Grimberg 
660891038deSjeremylt   The caller is responsible for managing and freeing the memory.
661891038deSjeremylt 
662ca94c3ddSJeremy L Thompson   @param[in]  ctx      `CeedQFunctionContext` to access
663ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
664ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
665891038deSjeremylt   @param[out] data     Data on memory type mem_type
666891038deSjeremylt 
667891038deSjeremylt   @return An error code: 0 - success, otherwise - failure
668891038deSjeremylt 
669891038deSjeremylt   @ref User
670891038deSjeremylt **/
6712b730f8bSJeremy L Thompson int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
6721c66c397SJeremy L Thompson   void *temp_data      = NULL;
6731c66c397SJeremy L Thompson   bool  has_valid_data = true, has_borrowed_data_of_type = true;
674*1203703bSJeremy L Thompson   Ceed  ceed;
6751c66c397SJeremy L Thompson 
676*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
6772b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
678*1203703bSJeremy L Thompson   CeedCheck(has_valid_data, ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to take, must set data");
6799c774eddSJeremy L Thompson 
680*1203703bSJeremy L Thompson   CeedCheck(ctx->TakeData, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextTakeData");
681*1203703bSJeremy L Thompson   CeedCheck(ctx->state % 2 == 0, ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
682891038deSjeremylt 
6832b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, &has_borrowed_data_of_type));
684*1203703bSJeremy L Thompson   CeedCheck(has_borrowed_data_of_type, ceed, CEED_ERROR_BACKEND,
6856574a04fSJeremy L Thompson             "CeedQFunctionContext has no borrowed %s data, must set data with CeedQFunctionContextSetData", CeedMemTypes[mem_type]);
6869c774eddSJeremy L Thompson 
6872b730f8bSJeremy L Thompson   CeedCall(ctx->TakeData(ctx, mem_type, &temp_data));
688891038deSjeremylt   if (data) (*(void **)data) = temp_data;
689891038deSjeremylt   return CEED_ERROR_SUCCESS;
690891038deSjeremylt }
691891038deSjeremylt 
692891038deSjeremylt /**
693ca94c3ddSJeremy L Thompson   @brief Get read/write access to a `CeedQFunctionContext` via the specified memory type.
6944385fb7fSSebastian Grimberg 
695777ff853SJeremy L Thompson   Restore access with @ref CeedQFunctionContextRestoreData().
696777ff853SJeremy L Thompson 
697ca94c3ddSJeremy L Thompson   @param[in]  ctx      `CeedQFunctionContext` to access
698ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
699ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
700d1d35e2fSjeremylt   @param[out] data     Data on memory type mem_type
701777ff853SJeremy L Thompson 
702ca94c3ddSJeremy L Thompson   @note The @ref CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions provide access to array pointers in the desired memory space.
703ca94c3ddSJeremy L Thompson         Pairing get/restore allows the `CeedQFunctionContext` to track access.
704777ff853SJeremy L Thompson 
705777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
706777ff853SJeremy L Thompson 
707777ff853SJeremy L Thompson   @ref User
708777ff853SJeremy L Thompson **/
7092b730f8bSJeremy L Thompson int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
7101c66c397SJeremy L Thompson   bool has_valid_data = true;
711*1203703bSJeremy L Thompson   Ceed ceed;
7121c66c397SJeremy L Thompson 
713*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
714*1203703bSJeremy L Thompson   CeedCheck(ctx->GetData, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextGetData");
715*1203703bSJeremy L Thompson   CeedCheck(ctx->state % 2 == 0, ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
716*1203703bSJeremy L Thompson   CeedCheck(ctx->num_readers == 0, ceed, 1, "Cannot grant CeedQFunctionContext data access, a process has read access");
71728bfd0b7SJeremy L Thompson 
7182b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
719*1203703bSJeremy L Thompson   CeedCheck(has_valid_data, ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data");
7209c774eddSJeremy L Thompson 
7212b730f8bSJeremy L Thompson   CeedCall(ctx->GetData(ctx, mem_type, data));
72228bfd0b7SJeremy L Thompson   ctx->state++;
72328bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
72428bfd0b7SJeremy L Thompson }
72528bfd0b7SJeremy L Thompson 
72628bfd0b7SJeremy L Thompson /**
727ca94c3ddSJeremy L Thompson   @brief Get read only access to a `CeedQFunctionContext` via the specified memory type.
7284385fb7fSSebastian Grimberg 
72928bfd0b7SJeremy L Thompson   Restore access with @ref CeedQFunctionContextRestoreData().
73028bfd0b7SJeremy L Thompson 
731ca94c3ddSJeremy L Thompson   @param[in]  ctx      `CeedQFunctionContext` to access
732ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
733ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
73428bfd0b7SJeremy L Thompson   @param[out] data     Data on memory type mem_type
73528bfd0b7SJeremy L Thompson 
736ca94c3ddSJeremy L Thompson   @note The @ref CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead() functions provide access to array pointers in the desired memory space.
737ca94c3ddSJeremy L Thompson         Pairing get/restore allows the `CeedQFunctionContext` to track access.
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 **/
7432b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
7441c66c397SJeremy L Thompson   bool has_valid_data = true;
745*1203703bSJeremy L Thompson   Ceed ceed;
7461c66c397SJeremy L Thompson 
747*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
748*1203703bSJeremy L Thompson   CeedCheck(ctx->GetDataRead, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextGetDataRead");
749*1203703bSJeremy L Thompson   CeedCheck(ctx->state % 2 == 0, ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
75028bfd0b7SJeremy L Thompson 
7512b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
752*1203703bSJeremy L Thompson   CeedCheck(has_valid_data, ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data");
75328bfd0b7SJeremy L Thompson 
7542b730f8bSJeremy L Thompson   CeedCall(ctx->GetDataRead(ctx, mem_type, data));
75528bfd0b7SJeremy L Thompson   ctx->num_readers++;
756e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
757777ff853SJeremy L Thompson }
758777ff853SJeremy L Thompson 
759777ff853SJeremy L Thompson /**
760777ff853SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetData()
761777ff853SJeremy L Thompson 
762ca94c3ddSJeremy L Thompson   @param[in]     ctx  `CeedQFunctionContext` to restore
763ea61e9acSJeremy L Thompson   @param[in,out] data Data to restore
764777ff853SJeremy L Thompson 
765777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
766777ff853SJeremy L Thompson 
767777ff853SJeremy L Thompson   @ref User
768777ff853SJeremy L Thompson **/
769777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) {
770*1203703bSJeremy L Thompson   Ceed ceed;
771*1203703bSJeremy L Thompson 
772*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
773*1203703bSJeremy L Thompson   CeedCheck(ctx->state % 2 == 1, ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted");
774777ff853SJeremy L Thompson 
7756574a04fSJeremy L Thompson   if (ctx->RestoreData) CeedCall(ctx->RestoreData(ctx));
776777ff853SJeremy L Thompson   *(void **)data = NULL;
77728bfd0b7SJeremy L Thompson   ctx->state++;
77828bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
77928bfd0b7SJeremy L Thompson }
78028bfd0b7SJeremy L Thompson 
78128bfd0b7SJeremy L Thompson /**
78228bfd0b7SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead()
78328bfd0b7SJeremy L Thompson 
784ca94c3ddSJeremy L Thompson   @param[in]     ctx  `CeedQFunctionContext` to restore
785ea61e9acSJeremy L Thompson   @param[in,out] data Data to restore
78628bfd0b7SJeremy L Thompson 
78728bfd0b7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
78828bfd0b7SJeremy L Thompson 
78928bfd0b7SJeremy L Thompson   @ref User
79028bfd0b7SJeremy L Thompson **/
79128bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) {
792*1203703bSJeremy L Thompson   Ceed ceed;
793*1203703bSJeremy L Thompson 
794*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
795*1203703bSJeremy L Thompson   CeedCheck(ctx->num_readers > 0, ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted");
79628bfd0b7SJeremy L Thompson 
79775a19770SJeremy L Thompson   ctx->num_readers--;
7986574a04fSJeremy L Thompson   if (ctx->num_readers == 0 && ctx->RestoreDataRead) CeedCall(ctx->RestoreDataRead(ctx));
79928bfd0b7SJeremy L Thompson   *(void **)data = NULL;
800e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
801777ff853SJeremy L Thompson }
802777ff853SJeremy L Thompson 
803777ff853SJeremy L Thompson /**
804ca94c3ddSJeremy L Thompson   @brief Register a `CeedQFunctionContext` field holding double precision values
805cdf32b93SJeremy L Thompson 
806ca94c3ddSJeremy L Thompson   @param[in,out] ctx               `CeedQFunctionContext`
807ea61e9acSJeremy L Thompson   @param[in]     field_name        Name of field to register
808ea61e9acSJeremy L Thompson   @param[in]     field_offset      Offset of field to register
809ea61e9acSJeremy L Thompson   @param[in]     num_values        Number of values to register, must be contiguous in memory
810ca94c3ddSJeremy L Thompson   @param[in]     field_description Description of field, or `NULL` for none
811cdf32b93SJeremy L Thompson 
812cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
813cdf32b93SJeremy L Thompson 
814cdf32b93SJeremy L Thompson   @ref User
815cdf32b93SJeremy L Thompson **/
8162b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values,
817cdf32b93SJeremy L Thompson                                        const char *field_description) {
8185b6ec284SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_DOUBLE, num_values);
819cdf32b93SJeremy L Thompson }
820cdf32b93SJeremy L Thompson 
821cdf32b93SJeremy L Thompson /**
822ca94c3ddSJeremy L Thompson   @brief Register a `CeedQFunctionContext` field holding `int32` values
823cdf32b93SJeremy L Thompson 
824ea61e9acSJeremy L Thompson   @param[in,out] ctx               CeedQFunctionContext
825ea61e9acSJeremy L Thompson   @param[in]     field_name        Name of field to register
826ea61e9acSJeremy L Thompson   @param[in]     field_offset      Offset of field to register
827ea61e9acSJeremy L Thompson   @param[in]     num_values        Number of values to register, must be contiguous in memory
828ca94c3ddSJeremy L Thompson   @param[in]     field_description Description of field, or `NULL` for none
829cdf32b93SJeremy L Thompson 
830cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
831cdf32b93SJeremy L Thompson 
832cdf32b93SJeremy L Thompson   @ref User
833cdf32b93SJeremy L Thompson **/
8342b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values,
835cdf32b93SJeremy L Thompson                                       const char *field_description) {
8365b6ec284SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_INT32, num_values);
8375b6ec284SJeremy L Thompson }
8385b6ec284SJeremy L Thompson 
8395b6ec284SJeremy L Thompson /**
840ca94c3ddSJeremy L Thompson   @brief Register a `CeedQFunctionContext` field holding boolean values
8415b6ec284SJeremy L Thompson 
842ca94c3ddSJeremy L Thompson   @param[in,out] ctx               `CeedQFunctionContext`
8435b6ec284SJeremy L Thompson   @param[in]     field_name        Name of field to register
8445b6ec284SJeremy L Thompson   @param[in]     field_offset      Offset of field to register
8455b6ec284SJeremy L Thompson   @param[in]     num_values        Number of values to register, must be contiguous in memory
846ca94c3ddSJeremy L Thompson   @param[in]     field_description Description of field, or `NULL` for none
8475b6ec284SJeremy L Thompson 
8485b6ec284SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
8495b6ec284SJeremy L Thompson 
8505b6ec284SJeremy L Thompson   @ref User
8515b6ec284SJeremy L Thompson **/
8525b6ec284SJeremy L Thompson int CeedQFunctionContextRegisterBoolean(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values,
8535b6ec284SJeremy L Thompson                                         const char *field_description) {
8545b6ec284SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_BOOL, num_values);
855cdf32b93SJeremy L Thompson }
856cdf32b93SJeremy L Thompson 
857cdf32b93SJeremy L Thompson /**
858ca94c3ddSJeremy L Thompson   @brief Get labels for all registered `CeedQFunctionContext` fields
859cdf32b93SJeremy L Thompson 
860ca94c3ddSJeremy L Thompson   @param[in]  ctx          `CeedQFunctionContext`
8613668ca4bSJeremy L Thompson   @param[out] field_labels Variable to hold array of field labels
862cdf32b93SJeremy L Thompson   @param[out] num_fields   Length of field descriptions array
863cdf32b93SJeremy L Thompson 
864cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
865cdf32b93SJeremy L Thompson 
866cdf32b93SJeremy L Thompson   @ref User
867cdf32b93SJeremy L Thompson **/
8682b730f8bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, const CeedContextFieldLabel **field_labels, CeedInt *num_fields) {
8693668ca4bSJeremy L Thompson   *field_labels = ctx->field_labels;
870cdf32b93SJeremy L Thompson   *num_fields   = ctx->num_fields;
871cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
872cdf32b93SJeremy L Thompson }
873cdf32b93SJeremy L Thompson 
874cdf32b93SJeremy L Thompson /**
875ca94c3ddSJeremy L Thompson   @brief Get the descriptive information about a `CeedContextFieldLabel`
8760f86cbe7SJeremy L Thompson 
877ca94c3ddSJeremy L Thompson   @param[in]  label             @ref CeedContextFieldLabel
8780f86cbe7SJeremy L Thompson   @param[out] field_name        Name of labeled field
8791ff07f3dSJeremy L Thompson   @param[out] field_offset      Offset of field registered
8807bfe0f0eSJeremy L Thompson   @param[out] num_values        Number of values registered
8811ff07f3dSJeremy L Thompson   @param[out] field_description Description of field, or NULL for none
882ca94c3ddSJeremy L Thompson   @param[out] field_type        @ref CeedContextFieldType
8830f86cbe7SJeremy L Thompson 
8840f86cbe7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
8850f86cbe7SJeremy L Thompson 
8860f86cbe7SJeremy L Thompson   @ref User
8870f86cbe7SJeremy L Thompson **/
8881ff07f3dSJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, const char **field_name, size_t *field_offset, size_t *num_values,
8891ff07f3dSJeremy L Thompson                                         const char **field_description, CeedContextFieldType *field_type) {
8900f86cbe7SJeremy L Thompson   if (field_name) *field_name = label->name;
8911ff07f3dSJeremy L Thompson   if (field_offset) *field_offset = label->offset;
8927bfe0f0eSJeremy L Thompson   if (num_values) *num_values = label->num_values;
8931ff07f3dSJeremy L Thompson   if (field_description) *field_description = label->description;
8940f86cbe7SJeremy L Thompson   if (field_type) *field_type = label->type;
8950f86cbe7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
8960f86cbe7SJeremy L Thompson }
8970f86cbe7SJeremy L Thompson 
8980f86cbe7SJeremy L Thompson /**
89980a9ef05SNatalie Beams   @brief Get data size for a Context
90080a9ef05SNatalie Beams 
901ca94c3ddSJeremy L Thompson   @param[in]  ctx      `CeedQFunctionContext`
90280a9ef05SNatalie Beams   @param[out] ctx_size Variable to store size of context data values
90380a9ef05SNatalie Beams 
90480a9ef05SNatalie Beams   @return An error code: 0 - success, otherwise - failure
90580a9ef05SNatalie Beams 
90680a9ef05SNatalie Beams   @ref User
90780a9ef05SNatalie Beams **/
9082b730f8bSJeremy L Thompson int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, size_t *ctx_size) {
90980a9ef05SNatalie Beams   *ctx_size = ctx->ctx_size;
91080a9ef05SNatalie Beams   return CEED_ERROR_SUCCESS;
91180a9ef05SNatalie Beams }
91280a9ef05SNatalie Beams 
91380a9ef05SNatalie Beams /**
914ca94c3ddSJeremy L Thompson   @brief View a `CeedQFunctionContext`
915777ff853SJeremy L Thompson 
916ca94c3ddSJeremy L Thompson   @param[in] ctx    `CeedQFunctionContext` to view
917777ff853SJeremy L Thompson   @param[in] stream Filestream to write to
918777ff853SJeremy L Thompson 
919777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
920777ff853SJeremy L Thompson 
921777ff853SJeremy L Thompson   @ref User
922777ff853SJeremy L Thompson **/
923777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) {
924777ff853SJeremy L Thompson   fprintf(stream, "CeedQFunctionContext\n");
925249f8407SJeremy L Thompson   fprintf(stream, "  Context Data Size: %zu\n", ctx->ctx_size);
9263668ca4bSJeremy L Thompson   for (CeedInt i = 0; i < ctx->num_fields; i++) {
9272b730f8bSJeremy L Thompson     fprintf(stream, "  Labeled %s field: %s\n", CeedContextFieldTypes[ctx->field_labels[i]->type], ctx->field_labels[i]->name);
9283668ca4bSJeremy L Thompson   }
929e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
930777ff853SJeremy L Thompson }
931777ff853SJeremy L Thompson 
932777ff853SJeremy L Thompson /**
933ca94c3ddSJeremy L Thompson   @brief Set additional destroy routine for `CeedQFunctionContext` user data
9342790b72bSJeremy L Thompson 
935ca94c3ddSJeremy L Thompson   @param[in,out] ctx        `CeedQFunctionContext` to set user destroy function
9362e64a2b9SJeremy L Thompson   @param[in]     f_mem_type Memory type to use when passing data into `f`
9372e64a2b9SJeremy L Thompson   @param[in]     f          Additional routine to use to destroy user data
9382790b72bSJeremy L Thompson 
9392790b72bSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
9402790b72bSJeremy L Thompson 
9412790b72bSJeremy L Thompson   @ref User
9422790b72bSJeremy L Thompson **/
9432b730f8bSJeremy L Thompson int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) {
944*1203703bSJeremy L Thompson   Ceed ceed;
945*1203703bSJeremy L Thompson 
946*1203703bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetCeed(ctx, &ceed));
947*1203703bSJeremy L Thompson   CeedCheck(f, ceed, 1, "Must provide valid callback function for destroying user data");
9482790b72bSJeremy L Thompson   ctx->data_destroy_mem_type = f_mem_type;
9492790b72bSJeremy L Thompson   ctx->data_destroy_function = f;
9502790b72bSJeremy L Thompson   return CEED_ERROR_SUCCESS;
9512790b72bSJeremy L Thompson }
9522790b72bSJeremy L Thompson 
9532790b72bSJeremy L Thompson /**
954ca94c3ddSJeremy L Thompson   @brief Destroy a `CeedQFunctionContext`
955777ff853SJeremy L Thompson 
956ca94c3ddSJeremy L Thompson   @param[in,out] ctx `CeedQFunctionContext` to destroy
957777ff853SJeremy L Thompson 
958777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
959777ff853SJeremy L Thompson 
960777ff853SJeremy L Thompson   @ref User
961777ff853SJeremy L Thompson **/
962777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) {
963ad6481ceSJeremy L Thompson   if (!*ctx || --(*ctx)->ref_count > 0) {
964ad6481ceSJeremy L Thompson     *ctx = NULL;
965ad6481ceSJeremy L Thompson     return CEED_ERROR_SUCCESS;
966ad6481ceSJeremy L Thompson   }
9676574a04fSJeremy L Thompson   CeedCheck(((*ctx)->state % 2) == 0, (*ctx)->ceed, 1, "Cannot destroy CeedQFunctionContext, the access lock is in use");
968777ff853SJeremy L Thompson 
9692b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroyData(*ctx));
9702b730f8bSJeremy L Thompson   if ((*ctx)->Destroy) CeedCall((*ctx)->Destroy(*ctx));
971cdf32b93SJeremy L Thompson   for (CeedInt i = 0; i < (*ctx)->num_fields; i++) {
9722b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]->name));
9732b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]->description));
9742b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]));
975cdf32b93SJeremy L Thompson   }
9762b730f8bSJeremy L Thompson   CeedCall(CeedFree(&(*ctx)->field_labels));
9772b730f8bSJeremy L Thompson   CeedCall(CeedDestroy(&(*ctx)->ceed));
9782b730f8bSJeremy L Thompson   CeedCall(CeedFree(ctx));
979e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
980777ff853SJeremy L Thompson }
981777ff853SJeremy L Thompson 
982777ff853SJeremy L Thompson /// @}
983