xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-qfunctioncontext.c (revision 512bb800c3b780a95e9f25e68d5c95fed17fce79)
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>
92b730f8bSJeremy L Thompson #include <ceed/backend.h>
102b730f8bSJeremy L Thompson #include <ceed/ceed.h>
113d576824SJeremy L Thompson #include <stdint.h>
123d576824SJeremy L Thompson #include <stdio.h>
13cdf32b93SJeremy L Thompson #include <string.h>
14777ff853SJeremy L Thompson 
15777ff853SJeremy L Thompson /// @file
16777ff853SJeremy L Thompson /// Implementation of public CeedQFunctionContext interfaces
17777ff853SJeremy L Thompson 
18777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
19cdf32b93SJeremy L Thompson /// CeedQFunctionContext Library Internal Functions
20cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
21cdf32b93SJeremy L Thompson /// @addtogroup CeedQFunctionDeveloper
22cdf32b93SJeremy L Thompson /// @{
23cdf32b93SJeremy L Thompson 
24cdf32b93SJeremy L Thompson /**
25cdf32b93SJeremy L Thompson   @brief Get index for QFunctionContext field
26cdf32b93SJeremy L Thompson 
27ea61e9acSJeremy L Thompson   @param[in]  ctx         CeedQFunctionContext
28ea61e9acSJeremy L Thompson   @param[in]  field_name  Name of field
29ea61e9acSJeremy L Thompson   @param[out] field_index Index of field, or -1 if field is not registered
30cdf32b93SJeremy L Thompson 
31cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
32cdf32b93SJeremy L Thompson 
33cdf32b93SJeremy L Thompson   @ref Developer
34cdf32b93SJeremy L Thompson **/
352b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx, const char *field_name, CeedInt *field_index) {
36cdf32b93SJeremy L Thompson   *field_index = -1;
372b730f8bSJeremy L Thompson   for (CeedInt i = 0; i < ctx->num_fields; i++) {
382b730f8bSJeremy L Thompson     if (!strcmp(ctx->field_labels[i]->name, field_name)) *field_index = i;
392b730f8bSJeremy L Thompson   }
40cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
41cdf32b93SJeremy L Thompson }
42cdf32b93SJeremy L Thompson 
43cdf32b93SJeremy L Thompson /**
44cdf32b93SJeremy L Thompson   @brief Common function for registering QFunctionContext fields
45cdf32b93SJeremy L Thompson 
46ea61e9acSJeremy L Thompson   @param[in,out] ctx               CeedQFunctionContext
47ea61e9acSJeremy L Thompson   @param[in]     field_name        Name of field to register
48ea61e9acSJeremy L Thompson   @param[in]     field_offset      Offset of field to register
49ea61e9acSJeremy L Thompson   @param[in]     field_description Description of field, or NULL for none
50ea61e9acSJeremy L Thompson   @param[in]     field_type        Field data type, such as double or int32
51ea61e9acSJeremy L Thompson   @param[in]     field_size        Size of field, in bytes
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,
592b730f8bSJeremy L Thompson                                         CeedContextFieldType field_type, size_t field_size, size_t num_values) {
60cdf32b93SJeremy L Thompson   // Check for duplicate
61cdf32b93SJeremy L Thompson   CeedInt field_index = -1;
622b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index));
632b730f8bSJeremy L Thompson   if (field_index != -1) {
64cdf32b93SJeremy L Thompson     // LCOV_EXCL_START
652b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" already registered", field_name);
66cdf32b93SJeremy L Thompson     // LCOV_EXCL_STOP
672b730f8bSJeremy L Thompson   }
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 
79cdf32b93SJeremy L Thompson   // Copy field data
802b730f8bSJeremy L Thompson   CeedCall(CeedStringAllocCopy(field_name, (char **)&ctx->field_labels[ctx->num_fields]->name));
812b730f8bSJeremy L Thompson   CeedCall(CeedStringAllocCopy(field_description, (char **)&ctx->field_labels[ctx->num_fields]->description));
823668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->type       = field_type;
833668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->offset     = field_offset;
847bfe0f0eSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->size       = field_size * num_values;
857bfe0f0eSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->num_values = num_values;
86cdf32b93SJeremy L Thompson   ctx->num_fields++;
87cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
88cdf32b93SJeremy L Thompson }
89cdf32b93SJeremy L Thompson 
903b190ab8SJeremy L Thompson /**
91ea61e9acSJeremy L Thompson   @brief Destroy user data held by CeedQFunctionContext, using function set by CeedQFunctionContextSetDataDestroy, if applicable
923b190ab8SJeremy L Thompson 
933b190ab8SJeremy L Thompson   @param[in,out] ctx CeedQFunctionContext to destroy user data
943b190ab8SJeremy L Thompson 
953b190ab8SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
963b190ab8SJeremy L Thompson 
973b190ab8SJeremy L Thompson   @ref Developer
983b190ab8SJeremy L Thompson **/
993b190ab8SJeremy L Thompson static int CeedQFunctionContextDestroyData(CeedQFunctionContext ctx) {
1003b190ab8SJeremy L Thompson   if (ctx->DataDestroy) {
1012b730f8bSJeremy L Thompson     CeedCall(ctx->DataDestroy(ctx));
1023b190ab8SJeremy L Thompson   } else {
1033b190ab8SJeremy L Thompson     CeedQFunctionContextDataDestroyUser data_destroy_function;
1043b190ab8SJeremy L Thompson     CeedMemType                         data_destroy_mem_type;
1053b190ab8SJeremy L Thompson 
1062b730f8bSJeremy L Thompson     CeedCall(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function));
1073b190ab8SJeremy L Thompson     if (data_destroy_function) {
1083b190ab8SJeremy L Thompson       void *data;
1093b190ab8SJeremy L Thompson 
1102b730f8bSJeremy L Thompson       CeedCall(CeedQFunctionContextGetData(ctx, data_destroy_mem_type, &data));
1112b730f8bSJeremy L Thompson       CeedCall(data_destroy_function(data));
1122b730f8bSJeremy L Thompson       CeedCall(CeedQFunctionContextRestoreData(ctx, &data));
1133b190ab8SJeremy L Thompson     }
1143b190ab8SJeremy L Thompson   }
1153b190ab8SJeremy L Thompson 
1163b190ab8SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1173b190ab8SJeremy L Thompson }
1183b190ab8SJeremy L Thompson 
119cdf32b93SJeremy L Thompson /// @}
120cdf32b93SJeremy L Thompson 
121cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
122777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API
123777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
124777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend
125777ff853SJeremy L Thompson /// @{
126777ff853SJeremy L Thompson 
127777ff853SJeremy L Thompson /**
128777ff853SJeremy L Thompson   @brief Get the Ceed associated with a CeedQFunctionContext
129777ff853SJeremy L Thompson 
130ea61e9acSJeremy L Thompson   @param[in]  ctx  CeedQFunctionContext
131777ff853SJeremy L Thompson   @param[out] ceed Variable to store Ceed
132777ff853SJeremy L Thompson 
133777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
134777ff853SJeremy L Thompson 
135777ff853SJeremy L Thompson   @ref Backend
136777ff853SJeremy L Thompson **/
137777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) {
138777ff853SJeremy L Thompson   *ceed = ctx->ceed;
139e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
140777ff853SJeremy L Thompson }
141777ff853SJeremy L Thompson 
142777ff853SJeremy L Thompson /**
1439c774eddSJeremy L Thompson   @brief Check for valid data in a CeedQFunctionContext
1449c774eddSJeremy L Thompson 
145ea61e9acSJeremy L Thompson   @param[in]  ctx            CeedQFunctionContext to check validity
1469c774eddSJeremy L Thompson   @param[out] has_valid_data Variable to store validity
1479c774eddSJeremy L Thompson 
1489c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1499c774eddSJeremy L Thompson 
1509c774eddSJeremy L Thompson   @ref Backend
1519c774eddSJeremy L Thompson **/
1522b730f8bSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx, bool *has_valid_data) {
1532b730f8bSJeremy L Thompson   if (!ctx->HasValidData) {
1549c774eddSJeremy L Thompson     // LCOV_EXCL_START
1552b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support HasValidData");
1569c774eddSJeremy L Thompson     // LCOV_EXCL_STOP
1572b730f8bSJeremy L Thompson   }
1589c774eddSJeremy L Thompson 
1592b730f8bSJeremy L Thompson   CeedCall(ctx->HasValidData(ctx, has_valid_data));
1609c774eddSJeremy L Thompson 
1619c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1629c774eddSJeremy L Thompson }
1639c774eddSJeremy L Thompson 
1649c774eddSJeremy L Thompson /**
165ea61e9acSJeremy L Thompson   @brief Check for borrowed data of a specific CeedMemType in a CeedQFunctionContext
1669c774eddSJeremy L Thompson 
167ea61e9acSJeremy L Thompson   @param[in]  ctx                       CeedQFunctionContext to check
168ea61e9acSJeremy L Thompson   @param[in]  mem_type                  Memory type to check
1699c774eddSJeremy L Thompson   @param[out] has_borrowed_data_of_type Variable to store result
1709c774eddSJeremy L Thompson 
1719c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1729c774eddSJeremy L Thompson 
1739c774eddSJeremy L Thompson   @ref Backend
1749c774eddSJeremy L Thompson **/
1752b730f8bSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx, CeedMemType mem_type, bool *has_borrowed_data_of_type) {
1762b730f8bSJeremy L Thompson   if (!ctx->HasBorrowedDataOfType) {
1779c774eddSJeremy L Thompson     // LCOV_EXCL_START
1782b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support HasBorrowedDataOfType");
1799c774eddSJeremy L Thompson     // LCOV_EXCL_STOP
1802b730f8bSJeremy L Thompson   }
1819c774eddSJeremy L Thompson 
1822b730f8bSJeremy L Thompson   CeedCall(ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type));
1839c774eddSJeremy L Thompson 
1849c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1859c774eddSJeremy L Thompson }
1869c774eddSJeremy L Thompson 
1879c774eddSJeremy L Thompson /**
188777ff853SJeremy L Thompson   @brief Get the state of a CeedQFunctionContext
189777ff853SJeremy L Thompson 
190ea61e9acSJeremy 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 /**
203777ff853SJeremy L Thompson   @brief Get backend data of a CeedQFunctionContext
204777ff853SJeremy L Thompson 
205ea61e9acSJeremy 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 /**
218777ff853SJeremy L Thompson   @brief Set backend data of a CeedQFunctionContext
219777ff853SJeremy L Thompson 
220ea61e9acSJeremy 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 /**
233ea61e9acSJeremy L Thompson   @brief Get label for a registered QFunctionContext field, or `NULL` if no field has been registered with this `field_name`
234e6a0ab89SJeremy L Thompson 
235e6a0ab89SJeremy 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;
2452b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index));
246e6a0ab89SJeremy L Thompson 
247e6a0ab89SJeremy L Thompson   if (field_index != -1) {
248e6a0ab89SJeremy L Thompson     *field_label = ctx->field_labels[field_index];
249e6a0ab89SJeremy L Thompson   } else {
250e6a0ab89SJeremy L Thompson     *field_label = NULL;
251e6a0ab89SJeremy L Thompson   }
252e6a0ab89SJeremy L Thompson 
253e6a0ab89SJeremy L Thompson   return CEED_ERROR_SUCCESS;
254e6a0ab89SJeremy L Thompson }
255e6a0ab89SJeremy L Thompson 
256e6a0ab89SJeremy L Thompson /**
257d8dd9a91SJeremy L Thompson   @brief Set QFunctionContext field
258d8dd9a91SJeremy L Thompson 
259ea61e9acSJeremy 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) {
2693668ca4bSJeremy L Thompson   // Check field type
2702b730f8bSJeremy L Thompson   if (field_label->type != field_type) {
271d8dd9a91SJeremy L Thompson     // LCOV_EXCL_START
2722b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" registered as %s, not registered as %s",
2732b730f8bSJeremy L Thompson                      field_label->name, CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
274d8dd9a91SJeremy L Thompson     // LCOV_EXCL_STOP
2752b730f8bSJeremy L Thompson   }
276d8dd9a91SJeremy L Thompson 
277d8dd9a91SJeremy L Thompson   char *data;
2782b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data));
2792788fa27SJeremy L Thompson   memcpy(&data[field_label->offset], values, field_label->size);
2802b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreData(ctx, &data));
281d8dd9a91SJeremy L Thompson 
282d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
283d8dd9a91SJeremy L Thompson }
284d8dd9a91SJeremy L Thompson 
285d8dd9a91SJeremy L Thompson /**
2862788fa27SJeremy L Thompson   @brief Get QFunctionContext field data, read-only
2872788fa27SJeremy L Thompson 
2882788fa27SJeremy L Thompson   @param[in]  ctx         CeedQFunctionContext
2892788fa27SJeremy L Thompson   @param[in]  field_label Label of field to read
2902788fa27SJeremy L Thompson   @param[in]  field_type  Type of field to read
2912788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
2922788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
2932788fa27SJeremy L Thompson 
2942788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
2952788fa27SJeremy L Thompson 
2962788fa27SJeremy L Thompson   @ref Backend
2972788fa27SJeremy L Thompson **/
2982788fa27SJeremy L Thompson int CeedQFunctionContextGetGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type,
2992788fa27SJeremy L Thompson                                        size_t *num_values, void *values) {
3002788fa27SJeremy L Thompson   // Check field type
3012788fa27SJeremy L Thompson   if (field_label->type != field_type) {
3022788fa27SJeremy L Thompson     // LCOV_EXCL_START
3032788fa27SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" registered as %s, not registered as %s",
3042788fa27SJeremy L Thompson                      field_label->name, CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
3052788fa27SJeremy L Thompson     // LCOV_EXCL_STOP
3062788fa27SJeremy L Thompson   }
3072788fa27SJeremy L Thompson 
3082788fa27SJeremy L Thompson   char *data;
3092788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data));
3102788fa27SJeremy L Thompson   *(void **)values = &data[field_label->offset];
3112788fa27SJeremy L Thompson   switch (field_type) {
3122788fa27SJeremy L Thompson     case CEED_CONTEXT_FIELD_INT32:
3132788fa27SJeremy L Thompson       *num_values = field_label->size / sizeof(int);
3142788fa27SJeremy L Thompson       break;
3152788fa27SJeremy L Thompson     case CEED_CONTEXT_FIELD_DOUBLE:
3162788fa27SJeremy L Thompson       *num_values = field_label->size / sizeof(double);
3172788fa27SJeremy L Thompson       break;
3182788fa27SJeremy L Thompson   }
3192788fa27SJeremy L Thompson 
3202788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3212788fa27SJeremy L Thompson }
3222788fa27SJeremy L Thompson 
3232788fa27SJeremy L Thompson /**
3242788fa27SJeremy L Thompson   @brief Restore QFunctionContext field data, read-only
3252788fa27SJeremy L Thompson 
3262788fa27SJeremy L Thompson   @param[in]  ctx         CeedQFunctionContext
3272788fa27SJeremy L Thompson   @param[in]  field_label Label of field to restore
3282788fa27SJeremy L Thompson   @param[in]  field_type  Type of field to restore
3292788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
3302788fa27SJeremy L Thompson 
3312788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
3322788fa27SJeremy L Thompson 
3332788fa27SJeremy L Thompson   @ref Backend
3342788fa27SJeremy L Thompson **/
3352788fa27SJeremy L Thompson int CeedQFunctionContextRestoreGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type,
3362788fa27SJeremy L Thompson                                            void *values) {
3372788fa27SJeremy L Thompson   // Check field type
3382788fa27SJeremy L Thompson   if (field_label->type != field_type) {
3392788fa27SJeremy L Thompson     // LCOV_EXCL_START
3402788fa27SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" registered as %s, not registered as %s",
3412788fa27SJeremy L Thompson                      field_label->name, CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
3422788fa27SJeremy L Thompson     // LCOV_EXCL_STOP
3432788fa27SJeremy L Thompson   }
3442788fa27SJeremy L Thompson 
3452788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreDataRead(ctx, values));
3462788fa27SJeremy L Thompson 
3472788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3482788fa27SJeremy L Thompson }
3492788fa27SJeremy L Thompson 
3502788fa27SJeremy L Thompson /**
351bfacc300SJeremy L Thompson   @brief Set QFunctionContext field holding a double precision value
352bfacc300SJeremy L Thompson 
353ea61e9acSJeremy L Thompson   @param[in,out] ctx         CeedQFunctionContext
3542788fa27SJeremy L Thompson   @param[in]     field_label Label for field to set
355ea61e9acSJeremy L Thompson   @param[in]     values      Values to set
356bfacc300SJeremy L Thompson 
357bfacc300SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
358bfacc300SJeremy L Thompson 
3593e1e85abSJeremy L Thompson   @ref Backend
360bfacc300SJeremy L Thompson **/
3612b730f8bSJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, double *values) {
3622b730f8bSJeremy L Thompson   if (!field_label) {
363bfacc300SJeremy L Thompson     // LCOV_EXCL_START
3642b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
365bfacc300SJeremy L Thompson     // LCOV_EXCL_STOP
3662b730f8bSJeremy L Thompson   }
367bfacc300SJeremy L Thompson 
3682b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values));
369bfacc300SJeremy L Thompson 
370bfacc300SJeremy L Thompson   return CEED_ERROR_SUCCESS;
371bfacc300SJeremy L Thompson }
372bfacc300SJeremy L Thompson 
373bfacc300SJeremy L Thompson /**
3742788fa27SJeremy L Thompson   @brief Get QFunctionContext field holding a double precision value, read-only
3752788fa27SJeremy L Thompson 
3762788fa27SJeremy L Thompson   @param[in]  ctx         CeedQFunctionContext
3772788fa27SJeremy L Thompson   @param[in]  field_label Label for field to get
3782788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
3792788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
3802788fa27SJeremy L Thompson 
3812788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
3822788fa27SJeremy L Thompson 
3832788fa27SJeremy L Thompson   @ref Backend
3842788fa27SJeremy L Thompson **/
3852788fa27SJeremy L Thompson int CeedQFunctionContextGetDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const double **values) {
3862788fa27SJeremy L Thompson   if (!field_label) {
3872788fa27SJeremy L Thompson     // LCOV_EXCL_START
3882788fa27SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
3892788fa27SJeremy L Thompson     // LCOV_EXCL_STOP
3902788fa27SJeremy L Thompson   }
3912788fa27SJeremy L Thompson 
3922788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values));
3932788fa27SJeremy L Thompson 
3942788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3952788fa27SJeremy L Thompson }
3962788fa27SJeremy L Thompson 
3972788fa27SJeremy L Thompson /**
3982788fa27SJeremy L Thompson   @brief Restore QFunctionContext field holding a double precision value, read-only
3992788fa27SJeremy L Thompson 
4002788fa27SJeremy 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) {
4092788fa27SJeremy L Thompson   if (!field_label) {
4102788fa27SJeremy L Thompson     // LCOV_EXCL_START
4112788fa27SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
4122788fa27SJeremy L Thompson     // LCOV_EXCL_STOP
4132788fa27SJeremy L Thompson   }
4142788fa27SJeremy L Thompson 
4152788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values));
4162788fa27SJeremy L Thompson 
4172788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4182788fa27SJeremy L Thompson }
4192788fa27SJeremy L Thompson 
4202788fa27SJeremy L Thompson /**
421bfacc300SJeremy L Thompson   @brief Set QFunctionContext field holding an int32 value
422bfacc300SJeremy L Thompson 
423ea61e9acSJeremy L Thompson   @param[in,out] ctx         CeedQFunctionContext
4242788fa27SJeremy L Thompson   @param[in]     field_label Label for field to set
425ea61e9acSJeremy L Thompson   @param[in]     values      Values to set
426bfacc300SJeremy L Thompson 
427bfacc300SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
428bfacc300SJeremy L Thompson 
4293e1e85abSJeremy L Thompson   @ref Backend
430bfacc300SJeremy L Thompson **/
4312b730f8bSJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, int *values) {
4322b730f8bSJeremy L Thompson   if (!field_label) {
433bfacc300SJeremy L Thompson     // LCOV_EXCL_START
4342b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
435bfacc300SJeremy L Thompson     // LCOV_EXCL_STOP
4362b730f8bSJeremy L Thompson   }
437bfacc300SJeremy L Thompson 
4382b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values));
439bfacc300SJeremy L Thompson 
440bfacc300SJeremy L Thompson   return CEED_ERROR_SUCCESS;
441bfacc300SJeremy L Thompson }
442bfacc300SJeremy L Thompson 
443bfacc300SJeremy L Thompson /**
4442788fa27SJeremy L Thompson   @brief Get QFunctionContext field holding a int32 value, read-only
4452788fa27SJeremy L Thompson 
4462788fa27SJeremy L Thompson   @param[in]  ctx         CeedQFunctionContext
4472788fa27SJeremy L Thompson   @param[in]  field_label Label for field to get
4482788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
4492788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
4502788fa27SJeremy L Thompson 
4512788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4522788fa27SJeremy L Thompson 
4532788fa27SJeremy L Thompson   @ref Backend
4542788fa27SJeremy L Thompson **/
4552788fa27SJeremy L Thompson int CeedQFunctionContextGetInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const int **values) {
4562788fa27SJeremy L Thompson   if (!field_label) {
4572788fa27SJeremy L Thompson     // LCOV_EXCL_START
4582788fa27SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
4592788fa27SJeremy L Thompson     // LCOV_EXCL_STOP
4602788fa27SJeremy L Thompson   }
4612788fa27SJeremy L Thompson 
4622788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values));
4632788fa27SJeremy L Thompson 
4642788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4652788fa27SJeremy L Thompson }
4662788fa27SJeremy L Thompson 
4672788fa27SJeremy L Thompson /**
4682788fa27SJeremy L Thompson   @brief Restore QFunctionContext field holding a int32 value, read-only
4692788fa27SJeremy L Thompson 
4702788fa27SJeremy L Thompson   @param[in]  ctx         CeedQFunctionContext
4712788fa27SJeremy L Thompson   @param[in]  field_label Label for field to restore
4722788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
4732788fa27SJeremy L Thompson 
4742788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4752788fa27SJeremy L Thompson 
4762788fa27SJeremy L Thompson   @ref Backend
4772788fa27SJeremy L Thompson **/
4782788fa27SJeremy L Thompson int CeedQFunctionContextRestoreInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const int **values) {
4792788fa27SJeremy L Thompson   if (!field_label) {
4802788fa27SJeremy L Thompson     // LCOV_EXCL_START
4812788fa27SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
4822788fa27SJeremy L Thompson     // LCOV_EXCL_STOP
4832788fa27SJeremy L Thompson   }
4842788fa27SJeremy L Thompson 
4852788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values));
4862788fa27SJeremy L Thompson 
4872788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4882788fa27SJeremy L Thompson }
4892788fa27SJeremy L Thompson 
4902788fa27SJeremy L Thompson /**
4912e64a2b9SJeremy L Thompson   @brief Get additional destroy routine for CeedQFunctionContext user data
4922e64a2b9SJeremy L Thompson 
4932e64a2b9SJeremy L Thompson   @param[in] ctx         CeedQFunctionContext to get user destroy function
4942e64a2b9SJeremy L Thompson   @param[out] f_mem_type Memory type to use when passing data into `f`
4952e64a2b9SJeremy L Thompson   @param[out] f          Additional routine to use to destroy user data
4962e64a2b9SJeremy L Thompson 
4972e64a2b9SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4982e64a2b9SJeremy L Thompson 
4992e64a2b9SJeremy L Thompson   @ref Backend
5002e64a2b9SJeremy L Thompson **/
5012b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx, CeedMemType *f_mem_type, CeedQFunctionContextDataDestroyUser *f) {
5022e64a2b9SJeremy L Thompson   if (f_mem_type) *f_mem_type = ctx->data_destroy_mem_type;
5032e64a2b9SJeremy L Thompson   if (f) *f = ctx->data_destroy_function;
5042e64a2b9SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5052e64a2b9SJeremy L Thompson }
5062e64a2b9SJeremy L Thompson 
5072e64a2b9SJeremy L Thompson /**
50834359f16Sjeremylt   @brief Increment the reference counter for a CeedQFunctionContext
50934359f16Sjeremylt 
510ea61e9acSJeremy L Thompson   @param[in,out] ctx CeedQFunctionContext to increment the reference counter
51134359f16Sjeremylt 
51234359f16Sjeremylt   @return An error code: 0 - success, otherwise - failure
51334359f16Sjeremylt 
51434359f16Sjeremylt   @ref Backend
51534359f16Sjeremylt **/
5169560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) {
51734359f16Sjeremylt   ctx->ref_count++;
51834359f16Sjeremylt   return CEED_ERROR_SUCCESS;
51934359f16Sjeremylt }
52034359f16Sjeremylt 
521777ff853SJeremy L Thompson /// @}
522777ff853SJeremy L Thompson 
523777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
524777ff853SJeremy L Thompson /// CeedQFunctionContext Public API
525777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
526777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser
527777ff853SJeremy L Thompson /// @{
528777ff853SJeremy L Thompson 
529777ff853SJeremy L Thompson /**
530777ff853SJeremy L Thompson   @brief Create a CeedQFunctionContext for storing CeedQFunction user context data
531777ff853SJeremy L Thompson 
532ea61e9acSJeremy L Thompson   @param[in]  ceed Ceed object where the CeedQFunctionContext will be created
533ea61e9acSJeremy L Thompson   @param[out] ctx  Address of the variable where the newly created CeedQFunctionContext will be stored
534777ff853SJeremy L Thompson 
535777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
536777ff853SJeremy L Thompson 
537777ff853SJeremy L Thompson   @ref User
538777ff853SJeremy L Thompson **/
539777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) {
540777ff853SJeremy L Thompson   if (!ceed->QFunctionContextCreate) {
541777ff853SJeremy L Thompson     Ceed delegate;
5422b730f8bSJeremy L Thompson     CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Context"));
543777ff853SJeremy L Thompson 
5442b730f8bSJeremy L Thompson     if (!delegate) {
545777ff853SJeremy L Thompson       // LCOV_EXCL_START
5462b730f8bSJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextCreate");
547777ff853SJeremy L Thompson       // LCOV_EXCL_STOP
5482b730f8bSJeremy L Thompson     }
549777ff853SJeremy L Thompson 
5502b730f8bSJeremy L Thompson     CeedCall(CeedQFunctionContextCreate(delegate, ctx));
551e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
552777ff853SJeremy L Thompson   }
553777ff853SJeremy L Thompson 
5542b730f8bSJeremy L Thompson   CeedCall(CeedCalloc(1, ctx));
555777ff853SJeremy L Thompson   (*ctx)->ceed = ceed;
5562b730f8bSJeremy L Thompson   CeedCall(CeedReference(ceed));
557d1d35e2fSjeremylt   (*ctx)->ref_count = 1;
5582b730f8bSJeremy L Thompson   CeedCall(ceed->QFunctionContextCreate(*ctx));
559e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
560777ff853SJeremy L Thompson }
561777ff853SJeremy L Thompson 
562777ff853SJeremy L Thompson /**
563ea61e9acSJeremy L Thompson   @brief Copy the pointer to a CeedQFunctionContext.
564ea61e9acSJeremy L Thompson            Both pointers should be destroyed with `CeedQFunctionContextDestroy()`.
565*512bb800SJeremy L Thompson 
566*512bb800SJeremy 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
567*512bb800SJeremy L Thompson              CeedQFunctionContext. This CeedQFunctionContext will be destroyed if `ctx_copy` is the only reference to this CeedQFunctionContext.
5689560d06aSjeremylt 
569ea61e9acSJeremy L Thompson   @param[in]     ctx      CeedQFunctionContext to copy reference to
570ea61e9acSJeremy L Thompson   @param[in,out] ctx_copy Variable to store copied reference
5719560d06aSjeremylt 
5729560d06aSjeremylt   @return An error code: 0 - success, otherwise - failure
5739560d06aSjeremylt 
5749560d06aSjeremylt   @ref User
5759560d06aSjeremylt **/
5762b730f8bSJeremy L Thompson int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, CeedQFunctionContext *ctx_copy) {
5772b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextReference(ctx));
5782b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroy(ctx_copy));
5799560d06aSjeremylt   *ctx_copy = ctx;
5809560d06aSjeremylt   return CEED_ERROR_SUCCESS;
5819560d06aSjeremylt }
5829560d06aSjeremylt 
5839560d06aSjeremylt /**
584ea61e9acSJeremy L Thompson   @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated data if applicable.
585ea61e9acSJeremy L Thompson            The backend may copy values to a different memtype, such as during @ref CeedQFunctionApply().
586777ff853SJeremy L Thompson            See also @ref CeedQFunctionContextTakeData().
587777ff853SJeremy L Thompson 
588ea61e9acSJeremy L Thompson   @param[in,out] ctx       CeedQFunctionContext
589ea61e9acSJeremy L Thompson   @param[in]     mem_type  Memory type of the data being passed
590ea61e9acSJeremy L Thompson   @param[in]     copy_mode Copy mode for the data
591ea61e9acSJeremy L Thompson   @param[in]     size      Size of data, in bytes
592ea61e9acSJeremy L Thompson   @param[in]     data      Data to be used
593777ff853SJeremy L Thompson 
594777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
595777ff853SJeremy L Thompson 
596777ff853SJeremy L Thompson   @ref User
597777ff853SJeremy L Thompson **/
5982b730f8bSJeremy L Thompson int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, size_t size, void *data) {
5992b730f8bSJeremy L Thompson   if (!ctx->SetData) {
600777ff853SJeremy L Thompson     // LCOV_EXCL_START
6012b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextSetData");
602777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
6032b730f8bSJeremy L Thompson   }
6042b730f8bSJeremy L Thompson   if (ctx->state % 2 == 1) {
605777ff853SJeremy L Thompson     // LCOV_EXCL_START
6062b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
607777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
6082b730f8bSJeremy L Thompson   }
609777ff853SJeremy L Thompson 
6102b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroyData(ctx));
611d1d35e2fSjeremylt   ctx->ctx_size = size;
6122b730f8bSJeremy L Thompson   CeedCall(ctx->SetData(ctx, mem_type, copy_mode, data));
613777ff853SJeremy L Thompson   ctx->state += 2;
614e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
615777ff853SJeremy L Thompson }
616777ff853SJeremy L Thompson 
617777ff853SJeremy L Thompson /**
618891038deSjeremylt   @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type.
619891038deSjeremylt            The caller is responsible for managing and freeing the memory.
620891038deSjeremylt 
621ea61e9acSJeremy L Thompson   @param[in]  ctx      CeedQFunctionContext to access
622ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
623ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
624891038deSjeremylt   @param[out] data     Data on memory type mem_type
625891038deSjeremylt 
626891038deSjeremylt   @return An error code: 0 - success, otherwise - failure
627891038deSjeremylt 
628891038deSjeremylt   @ref User
629891038deSjeremylt **/
6302b730f8bSJeremy L Thompson int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
6319c774eddSJeremy L Thompson   bool has_valid_data = true;
6322b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
6332b730f8bSJeremy L Thompson   if (!has_valid_data) {
6349c774eddSJeremy L Thompson     // LCOV_EXCL_START
6352b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to take, must set data");
6369c774eddSJeremy L Thompson     // LCOV_EXCL_STOP
6372b730f8bSJeremy L Thompson   }
6389c774eddSJeremy L Thompson 
6392b730f8bSJeremy L Thompson   if (!ctx->TakeData) {
640891038deSjeremylt     // LCOV_EXCL_START
6412b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support TakeData");
642891038deSjeremylt     // LCOV_EXCL_STOP
6432b730f8bSJeremy L Thompson   }
6442b730f8bSJeremy L Thompson   if (ctx->state % 2 == 1) {
645891038deSjeremylt     // LCOV_EXCL_START
6462b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
647891038deSjeremylt     // LCOV_EXCL_STOP
6482b730f8bSJeremy L Thompson   }
649891038deSjeremylt 
6509c774eddSJeremy L Thompson   bool has_borrowed_data_of_type = true;
6512b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, &has_borrowed_data_of_type));
6522b730f8bSJeremy L Thompson   if (!has_borrowed_data_of_type) {
6539c774eddSJeremy L Thompson     // LCOV_EXCL_START
6542b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no borowed %s data, must set data with CeedQFunctionContextSetData",
6559c774eddSJeremy L Thompson                      CeedMemTypes[mem_type]);
6569c774eddSJeremy L Thompson     // LCOV_EXCL_STOP
6572b730f8bSJeremy L Thompson   }
6589c774eddSJeremy L Thompson 
659891038deSjeremylt   void *temp_data = NULL;
6602b730f8bSJeremy L Thompson   CeedCall(ctx->TakeData(ctx, mem_type, &temp_data));
661891038deSjeremylt   if (data) (*(void **)data) = temp_data;
662891038deSjeremylt   return CEED_ERROR_SUCCESS;
663891038deSjeremylt }
664891038deSjeremylt 
665891038deSjeremylt /**
666777ff853SJeremy L Thompson   @brief Get read/write access to a CeedQFunctionContext via the specified memory type.
667777ff853SJeremy L Thompson            Restore access with @ref CeedQFunctionContextRestoreData().
668777ff853SJeremy L Thompson 
669ea61e9acSJeremy L Thompson   @param[in]  ctx      CeedQFunctionContext to access
670ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
671ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
672d1d35e2fSjeremylt   @param[out] data     Data on memory type mem_type
673777ff853SJeremy L Thompson 
674ea61e9acSJeremy L Thompson   @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions provide access to array pointers in the desired memory
675ea61e9acSJeremy L Thompson space. Pairing get/restore allows the Context to track access.
676777ff853SJeremy L Thompson 
677777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
678777ff853SJeremy L Thompson 
679777ff853SJeremy L Thompson   @ref User
680777ff853SJeremy L Thompson **/
6812b730f8bSJeremy L Thompson int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
6822b730f8bSJeremy L Thompson   if (!ctx->GetData) {
683777ff853SJeremy L Thompson     // LCOV_EXCL_START
6842b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetData");
685777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
6862b730f8bSJeremy L Thompson   }
6872b730f8bSJeremy L Thompson   if (ctx->state % 2 == 1) {
688777ff853SJeremy L Thompson     // LCOV_EXCL_START
6892b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
690777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
6912b730f8bSJeremy L Thompson   }
6922b730f8bSJeremy L Thompson   if (ctx->num_readers > 0) {
69328bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
6942b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, a process has read access");
69528bfd0b7SJeremy L Thompson     // LCOV_EXCL_STOP
6962b730f8bSJeremy L Thompson   }
69728bfd0b7SJeremy L Thompson 
6989c774eddSJeremy L Thompson   bool has_valid_data = true;
6992b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
7002b730f8bSJeremy L Thompson   if (!has_valid_data) {
7019c774eddSJeremy L Thompson     // LCOV_EXCL_START
7022b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data");
7039c774eddSJeremy L Thompson     // LCOV_EXCL_STOP
7042b730f8bSJeremy L Thompson   }
7059c774eddSJeremy L Thompson 
7062b730f8bSJeremy L Thompson   CeedCall(ctx->GetData(ctx, mem_type, data));
70728bfd0b7SJeremy L Thompson   ctx->state++;
70828bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
70928bfd0b7SJeremy L Thompson }
71028bfd0b7SJeremy L Thompson 
71128bfd0b7SJeremy L Thompson /**
71228bfd0b7SJeremy L Thompson   @brief Get read only access to a CeedQFunctionContext via the specified memory type.
71328bfd0b7SJeremy L Thompson            Restore access with @ref CeedQFunctionContextRestoreData().
71428bfd0b7SJeremy L Thompson 
715ea61e9acSJeremy L Thompson   @param[in]  ctx      CeedQFunctionContext to access
716ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
717ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
71828bfd0b7SJeremy L Thompson   @param[out] data     Data on memory type mem_type
71928bfd0b7SJeremy L Thompson 
720ea61e9acSJeremy L Thompson   @note The CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead() functions provide access to array pointers in the desired
721ea61e9acSJeremy L Thompson memory space. Pairing get/restore allows the Context to track access.
72228bfd0b7SJeremy L Thompson 
72328bfd0b7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
72428bfd0b7SJeremy L Thompson 
72528bfd0b7SJeremy L Thompson   @ref User
72628bfd0b7SJeremy L Thompson **/
7272b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
7282b730f8bSJeremy L Thompson   if (!ctx->GetDataRead) {
72928bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
7302b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetDataRead");
73128bfd0b7SJeremy L Thompson     // LCOV_EXCL_STOP
7322b730f8bSJeremy L Thompson   }
7332b730f8bSJeremy L Thompson   if (ctx->state % 2 == 1) {
73428bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
7352b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
73628bfd0b7SJeremy L Thompson     // LCOV_EXCL_STOP
7372b730f8bSJeremy L Thompson   }
73828bfd0b7SJeremy L Thompson 
73928bfd0b7SJeremy L Thompson   bool has_valid_data = true;
7402b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
7412b730f8bSJeremy L Thompson   if (!has_valid_data) {
74228bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
7432b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data");
74428bfd0b7SJeremy L Thompson     // LCOV_EXCL_STOP
7452b730f8bSJeremy L Thompson   }
74628bfd0b7SJeremy L Thompson 
7472b730f8bSJeremy L Thompson   CeedCall(ctx->GetDataRead(ctx, mem_type, data));
74828bfd0b7SJeremy L Thompson   ctx->num_readers++;
749e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
750777ff853SJeremy L Thompson }
751777ff853SJeremy L Thompson 
752777ff853SJeremy L Thompson /**
753777ff853SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetData()
754777ff853SJeremy L Thompson 
755ea61e9acSJeremy L Thompson   @param[in]     ctx  CeedQFunctionContext to restore
756ea61e9acSJeremy L Thompson   @param[in,out] data Data to restore
757777ff853SJeremy L Thompson 
758777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
759777ff853SJeremy L Thompson 
760777ff853SJeremy L Thompson   @ref User
761777ff853SJeremy L Thompson **/
762777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) {
7632b730f8bSJeremy L Thompson   if (ctx->state % 2 != 1) {
764777ff853SJeremy L Thompson     // LCOV_EXCL_START
7652b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted");
766777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
7672b730f8bSJeremy L Thompson   }
768777ff853SJeremy L Thompson 
769706efda3SJeremy L Thompson   if (ctx->RestoreData) {
7702b730f8bSJeremy L Thompson     CeedCall(ctx->RestoreData(ctx));
771706efda3SJeremy L Thompson   }
772777ff853SJeremy L Thompson   *(void **)data = NULL;
77328bfd0b7SJeremy L Thompson   ctx->state++;
77428bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
77528bfd0b7SJeremy L Thompson }
77628bfd0b7SJeremy L Thompson 
77728bfd0b7SJeremy L Thompson /**
77828bfd0b7SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead()
77928bfd0b7SJeremy L Thompson 
780ea61e9acSJeremy L Thompson   @param[in]     ctx  CeedQFunctionContext to restore
781ea61e9acSJeremy L Thompson   @param[in,out] data Data to restore
78228bfd0b7SJeremy L Thompson 
78328bfd0b7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
78428bfd0b7SJeremy L Thompson 
78528bfd0b7SJeremy L Thompson   @ref User
78628bfd0b7SJeremy L Thompson **/
78728bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) {
7882b730f8bSJeremy L Thompson   if (ctx->num_readers == 0) {
78928bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
7902b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted");
79128bfd0b7SJeremy L Thompson     // LCOV_EXCL_STOP
7922b730f8bSJeremy L Thompson   }
79328bfd0b7SJeremy L Thompson 
79475a19770SJeremy L Thompson   ctx->num_readers--;
79575a19770SJeremy L Thompson   if (ctx->num_readers == 0 && ctx->RestoreDataRead) {
7962b730f8bSJeremy L Thompson     CeedCall(ctx->RestoreDataRead(ctx));
79728bfd0b7SJeremy L Thompson   }
79828bfd0b7SJeremy L Thompson   *(void **)data = NULL;
79975a19770SJeremy L Thompson 
800e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
801777ff853SJeremy L Thompson }
802777ff853SJeremy L Thompson 
803777ff853SJeremy L Thompson /**
804cdf32b93SJeremy L Thompson   @brief Register QFunctionContext a field holding a double precision value
805cdf32b93SJeremy L Thompson 
806ea61e9acSJeremy 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
810ea61e9acSJeremy 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) {
8182b730f8bSJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double), num_values);
819cdf32b93SJeremy L Thompson }
820cdf32b93SJeremy L Thompson 
821cdf32b93SJeremy L Thompson /**
822cdf32b93SJeremy L Thompson   @brief Register QFunctionContext a field holding a int32 value
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
828ea61e9acSJeremy 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) {
8362b730f8bSJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int), num_values);
837cdf32b93SJeremy L Thompson }
838cdf32b93SJeremy L Thompson 
839cdf32b93SJeremy L Thompson /**
8403668ca4bSJeremy L Thompson   @brief Get labels for all registered QFunctionContext fields
841cdf32b93SJeremy L Thompson 
842ea61e9acSJeremy L Thompson   @param[in]  ctx          CeedQFunctionContext
8433668ca4bSJeremy L Thompson   @param[out] field_labels Variable to hold array of field labels
844cdf32b93SJeremy L Thompson   @param[out] num_fields   Length of field descriptions array
845cdf32b93SJeremy L Thompson 
846cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
847cdf32b93SJeremy L Thompson 
848cdf32b93SJeremy L Thompson   @ref User
849cdf32b93SJeremy L Thompson **/
8502b730f8bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, const CeedContextFieldLabel **field_labels, CeedInt *num_fields) {
8513668ca4bSJeremy L Thompson   *field_labels = ctx->field_labels;
852cdf32b93SJeremy L Thompson   *num_fields   = ctx->num_fields;
853cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
854cdf32b93SJeremy L Thompson }
855cdf32b93SJeremy L Thompson 
856cdf32b93SJeremy L Thompson /**
8570f86cbe7SJeremy L Thompson   @brief Get the descriptive information about a CeedContextFieldLabel
8580f86cbe7SJeremy L Thompson 
8590f86cbe7SJeremy L Thompson   @param[in]  label             CeedContextFieldLabel
8600f86cbe7SJeremy L Thompson   @param[out] field_name        Name of labeled field
8610f86cbe7SJeremy L Thompson   @param[out] field_description Description of field, or NULL for none
8627bfe0f0eSJeremy L Thompson   @param[out] num_values        Number of values registered
8630f86cbe7SJeremy L Thompson   @param[out] field_type        CeedContextFieldType
8640f86cbe7SJeremy L Thompson 
8650f86cbe7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
8660f86cbe7SJeremy L Thompson 
8670f86cbe7SJeremy L Thompson   @ref User
8680f86cbe7SJeremy L Thompson **/
8692b730f8bSJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, const char **field_name, const char **field_description, size_t *num_values,
8700f86cbe7SJeremy L Thompson                                         CeedContextFieldType *field_type) {
8710f86cbe7SJeremy L Thompson   if (field_name) *field_name = label->name;
8720f86cbe7SJeremy L Thompson   if (field_description) *field_description = label->description;
8737bfe0f0eSJeremy L Thompson   if (num_values) *num_values = label->num_values;
8740f86cbe7SJeremy L Thompson   if (field_type) *field_type = label->type;
8750f86cbe7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
8760f86cbe7SJeremy L Thompson }
8770f86cbe7SJeremy L Thompson 
8780f86cbe7SJeremy L Thompson /**
87980a9ef05SNatalie Beams   @brief Get data size for a Context
88080a9ef05SNatalie Beams 
881ea61e9acSJeremy L Thompson   @param[in]  ctx      CeedQFunctionContext
88280a9ef05SNatalie Beams   @param[out] ctx_size Variable to store size of context data values
88380a9ef05SNatalie Beams 
88480a9ef05SNatalie Beams   @return An error code: 0 - success, otherwise - failure
88580a9ef05SNatalie Beams 
88680a9ef05SNatalie Beams   @ref User
88780a9ef05SNatalie Beams **/
8882b730f8bSJeremy L Thompson int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, size_t *ctx_size) {
88980a9ef05SNatalie Beams   *ctx_size = ctx->ctx_size;
89080a9ef05SNatalie Beams   return CEED_ERROR_SUCCESS;
89180a9ef05SNatalie Beams }
89280a9ef05SNatalie Beams 
89380a9ef05SNatalie Beams /**
894777ff853SJeremy L Thompson   @brief View a CeedQFunctionContext
895777ff853SJeremy L Thompson 
896777ff853SJeremy L Thompson   @param[in] ctx    CeedQFunctionContext to view
897777ff853SJeremy L Thompson   @param[in] stream Filestream to write to
898777ff853SJeremy L Thompson 
899777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
900777ff853SJeremy L Thompson 
901777ff853SJeremy L Thompson   @ref User
902777ff853SJeremy L Thompson **/
903777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) {
904777ff853SJeremy L Thompson   fprintf(stream, "CeedQFunctionContext\n");
905d1d35e2fSjeremylt   fprintf(stream, "  Context Data Size: %ld\n", ctx->ctx_size);
9063668ca4bSJeremy L Thompson   for (CeedInt i = 0; i < ctx->num_fields; i++) {
9073668ca4bSJeremy L Thompson     // LCOV_EXCL_START
9082b730f8bSJeremy L Thompson     fprintf(stream, "  Labeled %s field: %s\n", CeedContextFieldTypes[ctx->field_labels[i]->type], ctx->field_labels[i]->name);
9093668ca4bSJeremy L Thompson     // LCOV_EXCL_STOP
9103668ca4bSJeremy L Thompson   }
911e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
912777ff853SJeremy L Thompson }
913777ff853SJeremy L Thompson 
914777ff853SJeremy L Thompson /**
9152790b72bSJeremy L Thompson   @brief Set additional destroy routine for CeedQFunctionContext user data
9162790b72bSJeremy L Thompson 
917ea61e9acSJeremy L Thompson   @param[in,out] ctx        CeedQFunctionContext to set user destroy function
9182e64a2b9SJeremy L Thompson   @param[in]     f_mem_type Memory type to use when passing data into `f`
9192e64a2b9SJeremy L Thompson   @param[in]     f          Additional routine to use to destroy user data
9202790b72bSJeremy L Thompson 
9212790b72bSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
9222790b72bSJeremy L Thompson 
9232790b72bSJeremy L Thompson   @ref User
9242790b72bSJeremy L Thompson **/
9252b730f8bSJeremy L Thompson int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) {
9262b730f8bSJeremy L Thompson   if (!f) {
9272790b72bSJeremy L Thompson     // LCOV_EXCL_START
9282b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Must provide valid callback function for destroying user data");
9292790b72bSJeremy L Thompson     // LCOV_EXCL_STOP
9302b730f8bSJeremy L Thompson   }
9312790b72bSJeremy L Thompson   ctx->data_destroy_mem_type = f_mem_type;
9322790b72bSJeremy L Thompson   ctx->data_destroy_function = f;
9332790b72bSJeremy L Thompson   return CEED_ERROR_SUCCESS;
9342790b72bSJeremy L Thompson }
9352790b72bSJeremy L Thompson 
9362790b72bSJeremy L Thompson /**
937777ff853SJeremy L Thompson   @brief Destroy a CeedQFunctionContext
938777ff853SJeremy L Thompson 
939ea61e9acSJeremy L Thompson   @param[in,out] ctx CeedQFunctionContext to destroy
940777ff853SJeremy L Thompson 
941777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
942777ff853SJeremy L Thompson 
943777ff853SJeremy L Thompson   @ref User
944777ff853SJeremy L Thompson **/
945777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) {
9462b730f8bSJeremy L Thompson   if (!*ctx || --(*ctx)->ref_count > 0) return CEED_ERROR_SUCCESS;
947777ff853SJeremy L Thompson 
9482b730f8bSJeremy L Thompson   if ((*ctx) && ((*ctx)->state % 2) == 1) {
949777ff853SJeremy L Thompson     // LCOV_EXCL_START
9502b730f8bSJeremy L Thompson     return CeedError((*ctx)->ceed, 1, "Cannot destroy CeedQFunctionContext, the access lock is in use");
951777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
9522b730f8bSJeremy L Thompson   }
953777ff853SJeremy L Thompson 
9542b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroyData(*ctx));
9552b730f8bSJeremy L Thompson   if ((*ctx)->Destroy) CeedCall((*ctx)->Destroy(*ctx));
956cdf32b93SJeremy L Thompson   for (CeedInt i = 0; i < (*ctx)->num_fields; i++) {
9572b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]->name));
9582b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]->description));
9592b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]));
960cdf32b93SJeremy L Thompson   }
9612b730f8bSJeremy L Thompson   CeedCall(CeedFree(&(*ctx)->field_labels));
9622b730f8bSJeremy L Thompson   CeedCall(CeedDestroy(&(*ctx)->ceed));
9632b730f8bSJeremy L Thompson   CeedCall(CeedFree(ctx));
964cdf32b93SJeremy L Thompson 
965e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
966777ff853SJeremy L Thompson }
967777ff853SJeremy L Thompson 
968777ff853SJeremy L Thompson /// @}
969