xref: /libCEED/interface/ceed-qfunctioncontext.c (revision 2788fa279822b86b73c7d9989c768f3b4c4cdffb)
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
262*2788fa27SJeremy 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 **/
268*2788fa27SJeremy 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));
279*2788fa27SJeremy 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 /**
286*2788fa27SJeremy L Thompson   @brief Get QFunctionContext field data, read-only
287*2788fa27SJeremy L Thompson 
288*2788fa27SJeremy L Thompson   @param[in]  ctx         CeedQFunctionContext
289*2788fa27SJeremy L Thompson   @param[in]  field_label Label of field to read
290*2788fa27SJeremy L Thompson   @param[in]  field_type  Type of field to read
291*2788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
292*2788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
293*2788fa27SJeremy L Thompson 
294*2788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
295*2788fa27SJeremy L Thompson 
296*2788fa27SJeremy L Thompson   @ref Backend
297*2788fa27SJeremy L Thompson **/
298*2788fa27SJeremy L Thompson int CeedQFunctionContextGetGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type,
299*2788fa27SJeremy L Thompson                                        size_t *num_values, void *values) {
300*2788fa27SJeremy L Thompson   // Check field type
301*2788fa27SJeremy L Thompson   if (field_label->type != field_type) {
302*2788fa27SJeremy L Thompson     // LCOV_EXCL_START
303*2788fa27SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" registered as %s, not registered as %s",
304*2788fa27SJeremy L Thompson                      field_label->name, CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
305*2788fa27SJeremy L Thompson     // LCOV_EXCL_STOP
306*2788fa27SJeremy L Thompson   }
307*2788fa27SJeremy L Thompson 
308*2788fa27SJeremy L Thompson   char *data;
309*2788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data));
310*2788fa27SJeremy L Thompson   *(void **)values = &data[field_label->offset];
311*2788fa27SJeremy L Thompson   switch (field_type) {
312*2788fa27SJeremy L Thompson     case CEED_CONTEXT_FIELD_INT32:
313*2788fa27SJeremy L Thompson       *num_values = field_label->size / sizeof(int);
314*2788fa27SJeremy L Thompson       break;
315*2788fa27SJeremy L Thompson     case CEED_CONTEXT_FIELD_DOUBLE:
316*2788fa27SJeremy L Thompson       *num_values = field_label->size / sizeof(double);
317*2788fa27SJeremy L Thompson       break;
318*2788fa27SJeremy L Thompson   }
319*2788fa27SJeremy L Thompson 
320*2788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
321*2788fa27SJeremy L Thompson }
322*2788fa27SJeremy L Thompson 
323*2788fa27SJeremy L Thompson /**
324*2788fa27SJeremy L Thompson   @brief Restore QFunctionContext field data, read-only
325*2788fa27SJeremy L Thompson 
326*2788fa27SJeremy L Thompson   @param[in]  ctx         CeedQFunctionContext
327*2788fa27SJeremy L Thompson   @param[in]  field_label Label of field to restore
328*2788fa27SJeremy L Thompson   @param[in]  field_type  Type of field to restore
329*2788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
330*2788fa27SJeremy L Thompson 
331*2788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
332*2788fa27SJeremy L Thompson 
333*2788fa27SJeremy L Thompson   @ref Backend
334*2788fa27SJeremy L Thompson **/
335*2788fa27SJeremy L Thompson int CeedQFunctionContextRestoreGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type,
336*2788fa27SJeremy L Thompson                                            void *values) {
337*2788fa27SJeremy L Thompson   // Check field type
338*2788fa27SJeremy L Thompson   if (field_label->type != field_type) {
339*2788fa27SJeremy L Thompson     // LCOV_EXCL_START
340*2788fa27SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" registered as %s, not registered as %s",
341*2788fa27SJeremy L Thompson                      field_label->name, CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
342*2788fa27SJeremy L Thompson     // LCOV_EXCL_STOP
343*2788fa27SJeremy L Thompson   }
344*2788fa27SJeremy L Thompson 
345*2788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreDataRead(ctx, values));
346*2788fa27SJeremy L Thompson 
347*2788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
348*2788fa27SJeremy L Thompson }
349*2788fa27SJeremy L Thompson 
350*2788fa27SJeremy 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
354*2788fa27SJeremy 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 /**
374*2788fa27SJeremy L Thompson   @brief Get QFunctionContext field holding a double precision value, read-only
375*2788fa27SJeremy L Thompson 
376*2788fa27SJeremy L Thompson   @param[in]  ctx         CeedQFunctionContext
377*2788fa27SJeremy L Thompson   @param[in]  field_label Label for field to get
378*2788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
379*2788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
380*2788fa27SJeremy L Thompson 
381*2788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
382*2788fa27SJeremy L Thompson 
383*2788fa27SJeremy L Thompson   @ref Backend
384*2788fa27SJeremy L Thompson **/
385*2788fa27SJeremy L Thompson int CeedQFunctionContextGetDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const double **values) {
386*2788fa27SJeremy L Thompson   if (!field_label) {
387*2788fa27SJeremy L Thompson     // LCOV_EXCL_START
388*2788fa27SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
389*2788fa27SJeremy L Thompson     // LCOV_EXCL_STOP
390*2788fa27SJeremy L Thompson   }
391*2788fa27SJeremy L Thompson 
392*2788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values));
393*2788fa27SJeremy L Thompson 
394*2788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
395*2788fa27SJeremy L Thompson }
396*2788fa27SJeremy L Thompson 
397*2788fa27SJeremy L Thompson /**
398*2788fa27SJeremy L Thompson   @brief Restore QFunctionContext field holding a double precision value, read-only
399*2788fa27SJeremy L Thompson 
400*2788fa27SJeremy L Thompson   @param[in]  ctx         CeedQFunctionContext
401*2788fa27SJeremy L Thompson   @param[in]  field_label Label for field to restore
402*2788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
403*2788fa27SJeremy L Thompson 
404*2788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
405*2788fa27SJeremy L Thompson 
406*2788fa27SJeremy L Thompson   @ref Backend
407*2788fa27SJeremy L Thompson **/
408*2788fa27SJeremy L Thompson int CeedQFunctionContextRestoreDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const double **values) {
409*2788fa27SJeremy L Thompson   if (!field_label) {
410*2788fa27SJeremy L Thompson     // LCOV_EXCL_START
411*2788fa27SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
412*2788fa27SJeremy L Thompson     // LCOV_EXCL_STOP
413*2788fa27SJeremy L Thompson   }
414*2788fa27SJeremy L Thompson 
415*2788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values));
416*2788fa27SJeremy L Thompson 
417*2788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
418*2788fa27SJeremy L Thompson }
419*2788fa27SJeremy L Thompson 
420*2788fa27SJeremy L Thompson /**
421bfacc300SJeremy L Thompson   @brief Set QFunctionContext field holding an int32 value
422bfacc300SJeremy L Thompson 
423ea61e9acSJeremy L Thompson   @param[in,out] ctx         CeedQFunctionContext
424*2788fa27SJeremy 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 /**
444*2788fa27SJeremy L Thompson   @brief Get QFunctionContext field holding a int32 value, read-only
445*2788fa27SJeremy L Thompson 
446*2788fa27SJeremy L Thompson   @param[in]  ctx         CeedQFunctionContext
447*2788fa27SJeremy L Thompson   @param[in]  field_label Label for field to get
448*2788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
449*2788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
450*2788fa27SJeremy L Thompson 
451*2788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
452*2788fa27SJeremy L Thompson 
453*2788fa27SJeremy L Thompson   @ref Backend
454*2788fa27SJeremy L Thompson **/
455*2788fa27SJeremy L Thompson int CeedQFunctionContextGetInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const int **values) {
456*2788fa27SJeremy L Thompson   if (!field_label) {
457*2788fa27SJeremy L Thompson     // LCOV_EXCL_START
458*2788fa27SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
459*2788fa27SJeremy L Thompson     // LCOV_EXCL_STOP
460*2788fa27SJeremy L Thompson   }
461*2788fa27SJeremy L Thompson 
462*2788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values));
463*2788fa27SJeremy L Thompson 
464*2788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
465*2788fa27SJeremy L Thompson }
466*2788fa27SJeremy L Thompson 
467*2788fa27SJeremy L Thompson /**
468*2788fa27SJeremy L Thompson   @brief Restore QFunctionContext field holding a int32 value, read-only
469*2788fa27SJeremy L Thompson 
470*2788fa27SJeremy L Thompson   @param[in]  ctx         CeedQFunctionContext
471*2788fa27SJeremy L Thompson   @param[in]  field_label Label for field to restore
472*2788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
473*2788fa27SJeremy L Thompson 
474*2788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
475*2788fa27SJeremy L Thompson 
476*2788fa27SJeremy L Thompson   @ref Backend
477*2788fa27SJeremy L Thompson **/
478*2788fa27SJeremy L Thompson int CeedQFunctionContextRestoreInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const int **values) {
479*2788fa27SJeremy L Thompson   if (!field_label) {
480*2788fa27SJeremy L Thompson     // LCOV_EXCL_START
481*2788fa27SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label");
482*2788fa27SJeremy L Thompson     // LCOV_EXCL_STOP
483*2788fa27SJeremy L Thompson   }
484*2788fa27SJeremy L Thompson 
485*2788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values));
486*2788fa27SJeremy L Thompson 
487*2788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
488*2788fa27SJeremy L Thompson }
489*2788fa27SJeremy L Thompson 
490*2788fa27SJeremy 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()`.
565ea61e9acSJeremy L Thompson            Note: If `*ctx_copy` is non-NULL, then it is assumed that `*ctx_copy` is a pointer to a CeedQFunctionContext.
566ea61e9acSJeremy L Thompson              This CeedQFunctionContext will be destroyed if `*ctx_copy` is the only reference to this CeedQFunctionContext.
5679560d06aSjeremylt 
568ea61e9acSJeremy L Thompson   @param[in]     ctx      CeedQFunctionContext to copy reference to
569ea61e9acSJeremy L Thompson   @param[in,out] ctx_copy Variable to store copied reference
5709560d06aSjeremylt 
5719560d06aSjeremylt   @return An error code: 0 - success, otherwise - failure
5729560d06aSjeremylt 
5739560d06aSjeremylt   @ref User
5749560d06aSjeremylt **/
5752b730f8bSJeremy L Thompson int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, CeedQFunctionContext *ctx_copy) {
5762b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextReference(ctx));
5772b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroy(ctx_copy));
5789560d06aSjeremylt   *ctx_copy = ctx;
5799560d06aSjeremylt   return CEED_ERROR_SUCCESS;
5809560d06aSjeremylt }
5819560d06aSjeremylt 
5829560d06aSjeremylt /**
583ea61e9acSJeremy L Thompson   @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated data if applicable.
584ea61e9acSJeremy L Thompson            The backend may copy values to a different memtype, such as during @ref CeedQFunctionApply().
585777ff853SJeremy L Thompson            See also @ref CeedQFunctionContextTakeData().
586777ff853SJeremy L Thompson 
587ea61e9acSJeremy L Thompson   @param[in,out] ctx       CeedQFunctionContext
588ea61e9acSJeremy L Thompson   @param[in]     mem_type  Memory type of the data being passed
589ea61e9acSJeremy L Thompson   @param[in]     copy_mode Copy mode for the data
590ea61e9acSJeremy L Thompson   @param[in]     size      Size of data, in bytes
591ea61e9acSJeremy L Thompson   @param[in]     data      Data to be used
592777ff853SJeremy L Thompson 
593777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
594777ff853SJeremy L Thompson 
595777ff853SJeremy L Thompson   @ref User
596777ff853SJeremy L Thompson **/
5972b730f8bSJeremy L Thompson int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, size_t size, void *data) {
5982b730f8bSJeremy L Thompson   if (!ctx->SetData) {
599777ff853SJeremy L Thompson     // LCOV_EXCL_START
6002b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextSetData");
601777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
6022b730f8bSJeremy L Thompson   }
6032b730f8bSJeremy L Thompson   if (ctx->state % 2 == 1) {
604777ff853SJeremy L Thompson     // LCOV_EXCL_START
6052b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
606777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
6072b730f8bSJeremy L Thompson   }
608777ff853SJeremy L Thompson 
6092b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroyData(ctx));
610d1d35e2fSjeremylt   ctx->ctx_size = size;
6112b730f8bSJeremy L Thompson   CeedCall(ctx->SetData(ctx, mem_type, copy_mode, data));
612777ff853SJeremy L Thompson   ctx->state += 2;
613e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
614777ff853SJeremy L Thompson }
615777ff853SJeremy L Thompson 
616777ff853SJeremy L Thompson /**
617891038deSjeremylt   @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type.
618891038deSjeremylt            The caller is responsible for managing and freeing the memory.
619891038deSjeremylt 
620ea61e9acSJeremy L Thompson   @param[in]  ctx      CeedQFunctionContext to access
621ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
622ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
623891038deSjeremylt   @param[out] data     Data on memory type mem_type
624891038deSjeremylt 
625891038deSjeremylt   @return An error code: 0 - success, otherwise - failure
626891038deSjeremylt 
627891038deSjeremylt   @ref User
628891038deSjeremylt **/
6292b730f8bSJeremy L Thompson int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
6309c774eddSJeremy L Thompson   bool has_valid_data = true;
6312b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
6322b730f8bSJeremy L Thompson   if (!has_valid_data) {
6339c774eddSJeremy L Thompson     // LCOV_EXCL_START
6342b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to take, must set data");
6359c774eddSJeremy L Thompson     // LCOV_EXCL_STOP
6362b730f8bSJeremy L Thompson   }
6379c774eddSJeremy L Thompson 
6382b730f8bSJeremy L Thompson   if (!ctx->TakeData) {
639891038deSjeremylt     // LCOV_EXCL_START
6402b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support TakeData");
641891038deSjeremylt     // LCOV_EXCL_STOP
6422b730f8bSJeremy L Thompson   }
6432b730f8bSJeremy L Thompson   if (ctx->state % 2 == 1) {
644891038deSjeremylt     // LCOV_EXCL_START
6452b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
646891038deSjeremylt     // LCOV_EXCL_STOP
6472b730f8bSJeremy L Thompson   }
648891038deSjeremylt 
6499c774eddSJeremy L Thompson   bool has_borrowed_data_of_type = true;
6502b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, &has_borrowed_data_of_type));
6512b730f8bSJeremy L Thompson   if (!has_borrowed_data_of_type) {
6529c774eddSJeremy L Thompson     // LCOV_EXCL_START
6532b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no borowed %s data, must set data with CeedQFunctionContextSetData",
6549c774eddSJeremy L Thompson                      CeedMemTypes[mem_type]);
6559c774eddSJeremy L Thompson     // LCOV_EXCL_STOP
6562b730f8bSJeremy L Thompson   }
6579c774eddSJeremy L Thompson 
658891038deSjeremylt   void *temp_data = NULL;
6592b730f8bSJeremy L Thompson   CeedCall(ctx->TakeData(ctx, mem_type, &temp_data));
660891038deSjeremylt   if (data) (*(void **)data) = temp_data;
661891038deSjeremylt   return CEED_ERROR_SUCCESS;
662891038deSjeremylt }
663891038deSjeremylt 
664891038deSjeremylt /**
665777ff853SJeremy L Thompson   @brief Get read/write access to a CeedQFunctionContext via the specified memory type.
666777ff853SJeremy L Thompson            Restore access with @ref CeedQFunctionContextRestoreData().
667777ff853SJeremy L Thompson 
668ea61e9acSJeremy L Thompson   @param[in]  ctx      CeedQFunctionContext to access
669ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
670ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
671d1d35e2fSjeremylt   @param[out] data     Data on memory type mem_type
672777ff853SJeremy L Thompson 
673ea61e9acSJeremy L Thompson   @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions provide access to array pointers in the desired memory
674ea61e9acSJeremy L Thompson space. Pairing get/restore allows the Context to track access.
675777ff853SJeremy L Thompson 
676777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
677777ff853SJeremy L Thompson 
678777ff853SJeremy L Thompson   @ref User
679777ff853SJeremy L Thompson **/
6802b730f8bSJeremy L Thompson int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
6812b730f8bSJeremy L Thompson   if (!ctx->GetData) {
682777ff853SJeremy L Thompson     // LCOV_EXCL_START
6832b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetData");
684777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
6852b730f8bSJeremy L Thompson   }
6862b730f8bSJeremy L Thompson   if (ctx->state % 2 == 1) {
687777ff853SJeremy L Thompson     // LCOV_EXCL_START
6882b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
689777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
6902b730f8bSJeremy L Thompson   }
6912b730f8bSJeremy L Thompson   if (ctx->num_readers > 0) {
69228bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
6932b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, a process has read access");
69428bfd0b7SJeremy L Thompson     // LCOV_EXCL_STOP
6952b730f8bSJeremy L Thompson   }
69628bfd0b7SJeremy L Thompson 
6979c774eddSJeremy L Thompson   bool has_valid_data = true;
6982b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
6992b730f8bSJeremy L Thompson   if (!has_valid_data) {
7009c774eddSJeremy L Thompson     // LCOV_EXCL_START
7012b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data");
7029c774eddSJeremy L Thompson     // LCOV_EXCL_STOP
7032b730f8bSJeremy L Thompson   }
7049c774eddSJeremy L Thompson 
7052b730f8bSJeremy L Thompson   CeedCall(ctx->GetData(ctx, mem_type, data));
70628bfd0b7SJeremy L Thompson   ctx->state++;
70728bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
70828bfd0b7SJeremy L Thompson }
70928bfd0b7SJeremy L Thompson 
71028bfd0b7SJeremy L Thompson /**
71128bfd0b7SJeremy L Thompson   @brief Get read only access to a CeedQFunctionContext via the specified memory type.
71228bfd0b7SJeremy L Thompson            Restore access with @ref CeedQFunctionContextRestoreData().
71328bfd0b7SJeremy L Thompson 
714ea61e9acSJeremy L Thompson   @param[in]  ctx      CeedQFunctionContext to access
715ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
716ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
71728bfd0b7SJeremy L Thompson   @param[out] data     Data on memory type mem_type
71828bfd0b7SJeremy L Thompson 
719ea61e9acSJeremy L Thompson   @note The CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead() functions provide access to array pointers in the desired
720ea61e9acSJeremy L Thompson memory space. Pairing get/restore allows the Context to track access.
72128bfd0b7SJeremy L Thompson 
72228bfd0b7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
72328bfd0b7SJeremy L Thompson 
72428bfd0b7SJeremy L Thompson   @ref User
72528bfd0b7SJeremy L Thompson **/
7262b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
7272b730f8bSJeremy L Thompson   if (!ctx->GetDataRead) {
72828bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
7292b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetDataRead");
73028bfd0b7SJeremy L Thompson     // LCOV_EXCL_STOP
7312b730f8bSJeremy L Thompson   }
7322b730f8bSJeremy L Thompson   if (ctx->state % 2 == 1) {
73328bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
7342b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
73528bfd0b7SJeremy L Thompson     // LCOV_EXCL_STOP
7362b730f8bSJeremy L Thompson   }
73728bfd0b7SJeremy L Thompson 
73828bfd0b7SJeremy L Thompson   bool has_valid_data = true;
7392b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
7402b730f8bSJeremy L Thompson   if (!has_valid_data) {
74128bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
7422b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data");
74328bfd0b7SJeremy L Thompson     // LCOV_EXCL_STOP
7442b730f8bSJeremy L Thompson   }
74528bfd0b7SJeremy L Thompson 
7462b730f8bSJeremy L Thompson   CeedCall(ctx->GetDataRead(ctx, mem_type, data));
74728bfd0b7SJeremy L Thompson   ctx->num_readers++;
748e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
749777ff853SJeremy L Thompson }
750777ff853SJeremy L Thompson 
751777ff853SJeremy L Thompson /**
752777ff853SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetData()
753777ff853SJeremy L Thompson 
754ea61e9acSJeremy L Thompson   @param[in]     ctx  CeedQFunctionContext to restore
755ea61e9acSJeremy L Thompson   @param[in,out] data Data to restore
756777ff853SJeremy L Thompson 
757777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
758777ff853SJeremy L Thompson 
759777ff853SJeremy L Thompson   @ref User
760777ff853SJeremy L Thompson **/
761777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) {
7622b730f8bSJeremy L Thompson   if (ctx->state % 2 != 1) {
763777ff853SJeremy L Thompson     // LCOV_EXCL_START
7642b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted");
765777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
7662b730f8bSJeremy L Thompson   }
767777ff853SJeremy L Thompson 
768706efda3SJeremy L Thompson   if (ctx->RestoreData) {
7692b730f8bSJeremy L Thompson     CeedCall(ctx->RestoreData(ctx));
770706efda3SJeremy L Thompson   }
771777ff853SJeremy L Thompson   *(void **)data = NULL;
77228bfd0b7SJeremy L Thompson   ctx->state++;
77328bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
77428bfd0b7SJeremy L Thompson }
77528bfd0b7SJeremy L Thompson 
77628bfd0b7SJeremy L Thompson /**
77728bfd0b7SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead()
77828bfd0b7SJeremy L Thompson 
779ea61e9acSJeremy L Thompson   @param[in]     ctx  CeedQFunctionContext to restore
780ea61e9acSJeremy L Thompson   @param[in,out] data Data to restore
78128bfd0b7SJeremy L Thompson 
78228bfd0b7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
78328bfd0b7SJeremy L Thompson 
78428bfd0b7SJeremy L Thompson   @ref User
78528bfd0b7SJeremy L Thompson **/
78628bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) {
7872b730f8bSJeremy L Thompson   if (ctx->num_readers == 0) {
78828bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
7892b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted");
79028bfd0b7SJeremy L Thompson     // LCOV_EXCL_STOP
7912b730f8bSJeremy L Thompson   }
79228bfd0b7SJeremy L Thompson 
79375a19770SJeremy L Thompson   ctx->num_readers--;
79475a19770SJeremy L Thompson   if (ctx->num_readers == 0 && ctx->RestoreDataRead) {
7952b730f8bSJeremy L Thompson     CeedCall(ctx->RestoreDataRead(ctx));
79628bfd0b7SJeremy L Thompson   }
79728bfd0b7SJeremy L Thompson   *(void **)data = NULL;
79875a19770SJeremy L Thompson 
799e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
800777ff853SJeremy L Thompson }
801777ff853SJeremy L Thompson 
802777ff853SJeremy L Thompson /**
803cdf32b93SJeremy L Thompson   @brief Register QFunctionContext a field holding a double precision value
804cdf32b93SJeremy L Thompson 
805ea61e9acSJeremy L Thompson   @param[in,out] ctx               CeedQFunctionContext
806ea61e9acSJeremy L Thompson   @param[in]     field_name        Name of field to register
807ea61e9acSJeremy L Thompson   @param[in]     field_offset      Offset of field to register
808ea61e9acSJeremy L Thompson   @param[in]     num_values        Number of values to register, must be contiguous in memory
809ea61e9acSJeremy L Thompson   @param[in]     field_description Description of field, or NULL for none
810cdf32b93SJeremy L Thompson 
811cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
812cdf32b93SJeremy L Thompson 
813cdf32b93SJeremy L Thompson   @ref User
814cdf32b93SJeremy L Thompson **/
8152b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values,
816cdf32b93SJeremy L Thompson                                        const char *field_description) {
8172b730f8bSJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double), num_values);
818cdf32b93SJeremy L Thompson }
819cdf32b93SJeremy L Thompson 
820cdf32b93SJeremy L Thompson /**
821cdf32b93SJeremy L Thompson   @brief Register QFunctionContext a field holding a int32 value
822cdf32b93SJeremy L Thompson 
823ea61e9acSJeremy L Thompson   @param[in,out] ctx               CeedQFunctionContext
824ea61e9acSJeremy L Thompson   @param[in]     field_name        Name of field to register
825ea61e9acSJeremy L Thompson   @param[in]     field_offset      Offset of field to register
826ea61e9acSJeremy L Thompson   @param[in]     num_values        Number of values to register, must be contiguous in memory
827ea61e9acSJeremy L Thompson   @param[in]     field_description Description of field, or NULL for none
828cdf32b93SJeremy L Thompson 
829cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
830cdf32b93SJeremy L Thompson 
831cdf32b93SJeremy L Thompson   @ref User
832cdf32b93SJeremy L Thompson **/
8332b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values,
834cdf32b93SJeremy L Thompson                                       const char *field_description) {
8352b730f8bSJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int), num_values);
836cdf32b93SJeremy L Thompson }
837cdf32b93SJeremy L Thompson 
838cdf32b93SJeremy L Thompson /**
8393668ca4bSJeremy L Thompson   @brief Get labels for all registered QFunctionContext fields
840cdf32b93SJeremy L Thompson 
841ea61e9acSJeremy L Thompson   @param[in]  ctx          CeedQFunctionContext
8423668ca4bSJeremy L Thompson   @param[out] field_labels Variable to hold array of field labels
843cdf32b93SJeremy L Thompson   @param[out] num_fields   Length of field descriptions array
844cdf32b93SJeremy L Thompson 
845cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
846cdf32b93SJeremy L Thompson 
847cdf32b93SJeremy L Thompson   @ref User
848cdf32b93SJeremy L Thompson **/
8492b730f8bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, const CeedContextFieldLabel **field_labels, CeedInt *num_fields) {
8503668ca4bSJeremy L Thompson   *field_labels = ctx->field_labels;
851cdf32b93SJeremy L Thompson   *num_fields   = ctx->num_fields;
852cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
853cdf32b93SJeremy L Thompson }
854cdf32b93SJeremy L Thompson 
855cdf32b93SJeremy L Thompson /**
8560f86cbe7SJeremy L Thompson   @brief Get the descriptive information about a CeedContextFieldLabel
8570f86cbe7SJeremy L Thompson 
8580f86cbe7SJeremy L Thompson   @param[in]  label             CeedContextFieldLabel
8590f86cbe7SJeremy L Thompson   @param[out] field_name        Name of labeled field
8600f86cbe7SJeremy L Thompson   @param[out] field_description Description of field, or NULL for none
8617bfe0f0eSJeremy L Thompson   @param[out] num_values        Number of values registered
8620f86cbe7SJeremy L Thompson   @param[out] field_type        CeedContextFieldType
8630f86cbe7SJeremy L Thompson 
8640f86cbe7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
8650f86cbe7SJeremy L Thompson 
8660f86cbe7SJeremy L Thompson   @ref User
8670f86cbe7SJeremy L Thompson **/
8682b730f8bSJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, const char **field_name, const char **field_description, size_t *num_values,
8690f86cbe7SJeremy L Thompson                                         CeedContextFieldType *field_type) {
8700f86cbe7SJeremy L Thompson   if (field_name) *field_name = label->name;
8710f86cbe7SJeremy L Thompson   if (field_description) *field_description = label->description;
8727bfe0f0eSJeremy L Thompson   if (num_values) *num_values = label->num_values;
8730f86cbe7SJeremy L Thompson   if (field_type) *field_type = label->type;
8740f86cbe7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
8750f86cbe7SJeremy L Thompson }
8760f86cbe7SJeremy L Thompson 
8770f86cbe7SJeremy L Thompson /**
87880a9ef05SNatalie Beams   @brief Get data size for a Context
87980a9ef05SNatalie Beams 
880ea61e9acSJeremy L Thompson   @param[in]  ctx      CeedQFunctionContext
88180a9ef05SNatalie Beams   @param[out] ctx_size Variable to store size of context data values
88280a9ef05SNatalie Beams 
88380a9ef05SNatalie Beams   @return An error code: 0 - success, otherwise - failure
88480a9ef05SNatalie Beams 
88580a9ef05SNatalie Beams   @ref User
88680a9ef05SNatalie Beams **/
8872b730f8bSJeremy L Thompson int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, size_t *ctx_size) {
88880a9ef05SNatalie Beams   *ctx_size = ctx->ctx_size;
88980a9ef05SNatalie Beams   return CEED_ERROR_SUCCESS;
89080a9ef05SNatalie Beams }
89180a9ef05SNatalie Beams 
89280a9ef05SNatalie Beams /**
893777ff853SJeremy L Thompson   @brief View a CeedQFunctionContext
894777ff853SJeremy L Thompson 
895777ff853SJeremy L Thompson   @param[in] ctx    CeedQFunctionContext to view
896777ff853SJeremy L Thompson   @param[in] stream Filestream to write to
897777ff853SJeremy L Thompson 
898777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
899777ff853SJeremy L Thompson 
900777ff853SJeremy L Thompson   @ref User
901777ff853SJeremy L Thompson **/
902777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) {
903777ff853SJeremy L Thompson   fprintf(stream, "CeedQFunctionContext\n");
904d1d35e2fSjeremylt   fprintf(stream, "  Context Data Size: %ld\n", ctx->ctx_size);
9053668ca4bSJeremy L Thompson   for (CeedInt i = 0; i < ctx->num_fields; i++) {
9063668ca4bSJeremy L Thompson     // LCOV_EXCL_START
9072b730f8bSJeremy L Thompson     fprintf(stream, "  Labeled %s field: %s\n", CeedContextFieldTypes[ctx->field_labels[i]->type], ctx->field_labels[i]->name);
9083668ca4bSJeremy L Thompson     // LCOV_EXCL_STOP
9093668ca4bSJeremy L Thompson   }
910e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
911777ff853SJeremy L Thompson }
912777ff853SJeremy L Thompson 
913777ff853SJeremy L Thompson /**
9142790b72bSJeremy L Thompson   @brief Set additional destroy routine for CeedQFunctionContext user data
9152790b72bSJeremy L Thompson 
916ea61e9acSJeremy L Thompson   @param[in,out] ctx        CeedQFunctionContext to set user destroy function
9172e64a2b9SJeremy L Thompson   @param[in]     f_mem_type Memory type to use when passing data into `f`
9182e64a2b9SJeremy L Thompson   @param[in]     f          Additional routine to use to destroy user data
9192790b72bSJeremy L Thompson 
9202790b72bSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
9212790b72bSJeremy L Thompson 
9222790b72bSJeremy L Thompson   @ref User
9232790b72bSJeremy L Thompson **/
9242b730f8bSJeremy L Thompson int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) {
9252b730f8bSJeremy L Thompson   if (!f) {
9262790b72bSJeremy L Thompson     // LCOV_EXCL_START
9272b730f8bSJeremy L Thompson     return CeedError(ctx->ceed, 1, "Must provide valid callback function for destroying user data");
9282790b72bSJeremy L Thompson     // LCOV_EXCL_STOP
9292b730f8bSJeremy L Thompson   }
9302790b72bSJeremy L Thompson   ctx->data_destroy_mem_type = f_mem_type;
9312790b72bSJeremy L Thompson   ctx->data_destroy_function = f;
9322790b72bSJeremy L Thompson   return CEED_ERROR_SUCCESS;
9332790b72bSJeremy L Thompson }
9342790b72bSJeremy L Thompson 
9352790b72bSJeremy L Thompson /**
936777ff853SJeremy L Thompson   @brief Destroy a CeedQFunctionContext
937777ff853SJeremy L Thompson 
938ea61e9acSJeremy L Thompson   @param[in,out] ctx CeedQFunctionContext to destroy
939777ff853SJeremy L Thompson 
940777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
941777ff853SJeremy L Thompson 
942777ff853SJeremy L Thompson   @ref User
943777ff853SJeremy L Thompson **/
944777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) {
9452b730f8bSJeremy L Thompson   if (!*ctx || --(*ctx)->ref_count > 0) return CEED_ERROR_SUCCESS;
946777ff853SJeremy L Thompson 
9472b730f8bSJeremy L Thompson   if ((*ctx) && ((*ctx)->state % 2) == 1) {
948777ff853SJeremy L Thompson     // LCOV_EXCL_START
9492b730f8bSJeremy L Thompson     return CeedError((*ctx)->ceed, 1, "Cannot destroy CeedQFunctionContext, the access lock is in use");
950777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
9512b730f8bSJeremy L Thompson   }
952777ff853SJeremy L Thompson 
9532b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroyData(*ctx));
9542b730f8bSJeremy L Thompson   if ((*ctx)->Destroy) CeedCall((*ctx)->Destroy(*ctx));
955cdf32b93SJeremy L Thompson   for (CeedInt i = 0; i < (*ctx)->num_fields; i++) {
9562b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]->name));
9572b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]->description));
9582b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]));
959cdf32b93SJeremy L Thompson   }
9602b730f8bSJeremy L Thompson   CeedCall(CeedFree(&(*ctx)->field_labels));
9612b730f8bSJeremy L Thompson   CeedCall(CeedDestroy(&(*ctx)->ceed));
9622b730f8bSJeremy L Thompson   CeedCall(CeedFree(ctx));
963cdf32b93SJeremy L Thompson 
964e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
965777ff853SJeremy L Thompson }
966777ff853SJeremy L Thompson 
967777ff853SJeremy L Thompson /// @}
968