xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-qfunctioncontext.c (revision a299a25b9879b9b54a5c96c9f88ed0cb403a2fde)
19ba83ac0SJeremy L Thompson // Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors.
23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3777ff853SJeremy L Thompson //
43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
5777ff853SJeremy L Thompson //
63d8e8822SJeremy L Thompson // This file is part of CEED:  http://github.com/ceed
7777ff853SJeremy L Thompson 
83d576824SJeremy L Thompson #include <ceed-impl.h>
949aac155SJeremy L Thompson #include <ceed.h>
102b730f8bSJeremy L Thompson #include <ceed/backend.h>
1149aac155SJeremy L Thompson #include <stdbool.h>
123d576824SJeremy L Thompson #include <stdint.h>
133d576824SJeremy L Thompson #include <stdio.h>
14cdf32b93SJeremy L Thompson #include <string.h>
15777ff853SJeremy L Thompson 
16777ff853SJeremy L Thompson /// @file
17777ff853SJeremy L Thompson /// Implementation of public CeedQFunctionContext interfaces
18777ff853SJeremy L Thompson 
19777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
20cdf32b93SJeremy L Thompson /// CeedQFunctionContext Library Internal Functions
21cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
22cdf32b93SJeremy L Thompson /// @addtogroup CeedQFunctionDeveloper
23cdf32b93SJeremy L Thompson /// @{
24cdf32b93SJeremy L Thompson 
25cdf32b93SJeremy L Thompson /**
26ca94c3ddSJeremy L Thompson   @brief Get index for `CeedQFunctionContext` field
27cdf32b93SJeremy L Thompson 
28ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
29ea61e9acSJeremy L Thompson   @param[in]  field_name  Name of field
30ca94c3ddSJeremy L Thompson   @param[out] field_index Index of field, or `-1` if field is not registered
31cdf32b93SJeremy L Thompson 
32cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
33cdf32b93SJeremy L Thompson 
34cdf32b93SJeremy L Thompson   @ref Developer
35cdf32b93SJeremy L Thompson **/
362b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx, const char *field_name, CeedInt *field_index) {
37cdf32b93SJeremy L Thompson   *field_index = -1;
382b730f8bSJeremy L Thompson   for (CeedInt i = 0; i < ctx->num_fields; i++) {
392b730f8bSJeremy L Thompson     if (!strcmp(ctx->field_labels[i]->name, field_name)) *field_index = i;
402b730f8bSJeremy L Thompson   }
41cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
42cdf32b93SJeremy L Thompson }
43cdf32b93SJeremy L Thompson 
44cdf32b93SJeremy L Thompson /**
45ca94c3ddSJeremy L Thompson   @brief Common function for registering `CeedQFunctionContext` fields
46cdf32b93SJeremy L Thompson 
47ca94c3ddSJeremy L Thompson   @param[in,out] ctx               `CeedQFunctionContext`
48ea61e9acSJeremy L Thompson   @param[in]     field_name        Name of field to register
49ea61e9acSJeremy L Thompson   @param[in]     field_offset      Offset of field to register
50ca94c3ddSJeremy L Thompson   @param[in]     field_description Description of field, or `NULL` for none
51ca94c3ddSJeremy L Thompson   @param[in]     field_type        @ref CeedContextFieldType
52ea61e9acSJeremy L Thompson   @param[in]     num_values        Number of values to register, must be contiguous in memory
53cdf32b93SJeremy L Thompson 
54cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
55cdf32b93SJeremy L Thompson 
56cdf32b93SJeremy L Thompson   @ref Developer
57cdf32b93SJeremy L Thompson **/
582b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, const char *field_description,
595b6ec284SJeremy L Thompson                                         CeedContextFieldType field_type, size_t num_values) {
605b6ec284SJeremy L Thompson   size_t  field_size  = 0;
61cdf32b93SJeremy L Thompson   CeedInt field_index = -1;
621c66c397SJeremy L Thompson 
631c66c397SJeremy L Thompson   // Check for duplicate
642b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index));
659bc66399SJeremy L Thompson   CeedCheck(field_index == -1, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED,
669bc66399SJeremy L Thompson             "QFunctionContext field with name \"%s\" already registered", field_name);
67cdf32b93SJeremy L Thompson 
68cdf32b93SJeremy L Thompson   // Allocate space for field data
69cdf32b93SJeremy L Thompson   if (ctx->num_fields == 0) {
702b730f8bSJeremy L Thompson     CeedCall(CeedCalloc(1, &ctx->field_labels));
71cdf32b93SJeremy L Thompson     ctx->max_fields = 1;
72cdf32b93SJeremy L Thompson   } else if (ctx->num_fields == ctx->max_fields) {
732b730f8bSJeremy L Thompson     CeedCall(CeedRealloc(2 * ctx->max_fields, &ctx->field_labels));
74cdf32b93SJeremy L Thompson     ctx->max_fields *= 2;
75cdf32b93SJeremy L Thompson   }
762b730f8bSJeremy L Thompson   CeedCall(CeedCalloc(1, &ctx->field_labels[ctx->num_fields]));
77cdf32b93SJeremy L Thompson 
785b6ec284SJeremy L Thompson   // Compute field size
795b6ec284SJeremy L Thompson   switch (field_type) {
805b6ec284SJeremy L Thompson     case CEED_CONTEXT_FIELD_DOUBLE:
815b6ec284SJeremy L Thompson       field_size = sizeof(double);
825b6ec284SJeremy L Thompson       break;
835b6ec284SJeremy L Thompson     case CEED_CONTEXT_FIELD_INT32:
845b6ec284SJeremy L Thompson       field_size = sizeof(int);
855b6ec284SJeremy L Thompson       break;
865b6ec284SJeremy L Thompson     case CEED_CONTEXT_FIELD_BOOL:
875b6ec284SJeremy L Thompson       field_size = sizeof(bool);
885b6ec284SJeremy L Thompson       break;
895b6ec284SJeremy L Thompson   }
905b6ec284SJeremy L Thompson 
91cdf32b93SJeremy L Thompson   // Copy field data
922b730f8bSJeremy L Thompson   CeedCall(CeedStringAllocCopy(field_name, (char **)&ctx->field_labels[ctx->num_fields]->name));
932b730f8bSJeremy L Thompson   CeedCall(CeedStringAllocCopy(field_description, (char **)&ctx->field_labels[ctx->num_fields]->description));
943668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->type       = field_type;
953668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->offset     = field_offset;
967bfe0f0eSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->size       = field_size * num_values;
977bfe0f0eSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->num_values = num_values;
98cdf32b93SJeremy L Thompson   ctx->num_fields++;
99cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
100cdf32b93SJeremy L Thompson }
101cdf32b93SJeremy L Thompson 
1023b190ab8SJeremy L Thompson /**
103ca94c3ddSJeremy L Thompson   @brief Destroy user data held by `CeedQFunctionContext`, using function set by @ref CeedQFunctionContextSetDataDestroy(), if applicable
1043b190ab8SJeremy L Thompson 
105ca94c3ddSJeremy L Thompson   @param[in,out] ctx `CeedQFunctionContext` to destroy user data
1063b190ab8SJeremy L Thompson 
1073b190ab8SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1083b190ab8SJeremy L Thompson 
1093b190ab8SJeremy L Thompson   @ref Developer
1103b190ab8SJeremy L Thompson **/
1113b190ab8SJeremy L Thompson static int CeedQFunctionContextDestroyData(CeedQFunctionContext ctx) {
1123b190ab8SJeremy L Thompson   if (ctx->DataDestroy) {
1132b730f8bSJeremy L Thompson     CeedCall(ctx->DataDestroy(ctx));
1143b190ab8SJeremy L Thompson   } else {
1153b190ab8SJeremy L Thompson     CeedMemType                         data_destroy_mem_type;
1161c66c397SJeremy L Thompson     CeedQFunctionContextDataDestroyUser data_destroy_function;
1173b190ab8SJeremy L Thompson 
1182b730f8bSJeremy L Thompson     CeedCall(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function));
1193b190ab8SJeremy L Thompson     if (data_destroy_function) {
1203b190ab8SJeremy L Thompson       void *data;
1213b190ab8SJeremy L Thompson 
1222b730f8bSJeremy L Thompson       CeedCall(CeedQFunctionContextGetData(ctx, data_destroy_mem_type, &data));
1232b730f8bSJeremy L Thompson       CeedCall(data_destroy_function(data));
1242b730f8bSJeremy L Thompson       CeedCall(CeedQFunctionContextRestoreData(ctx, &data));
1253b190ab8SJeremy L Thompson     }
1263b190ab8SJeremy L Thompson   }
1273b190ab8SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1283b190ab8SJeremy L Thompson }
1293b190ab8SJeremy L Thompson 
130b0f67a9cSJeremy L Thompson /**
131b0f67a9cSJeremy L Thompson   @brief View a `CeedQFunctionContext` passed as a `CeedObject`
132b0f67a9cSJeremy L Thompson 
133b0f67a9cSJeremy L Thompson   @param[in] ctx    `CeedQFunctionContext` to view
134b0f67a9cSJeremy L Thompson   @param[in] stream Filestream to write to
135b0f67a9cSJeremy L Thompson 
136b0f67a9cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
137b0f67a9cSJeremy L Thompson 
138b0f67a9cSJeremy L Thompson   @ref Developer
139b0f67a9cSJeremy L Thompson **/
140b0f67a9cSJeremy L Thompson static int CeedQFunctionContextView_Object(CeedObject ctx, FILE *stream) {
141b0f67a9cSJeremy L Thompson   CeedCall(CeedQFunctionContextView((CeedQFunctionContext)ctx, stream));
142b0f67a9cSJeremy L Thompson   return CEED_ERROR_SUCCESS;
143b0f67a9cSJeremy L Thompson }
144b0f67a9cSJeremy L Thompson 
145cdf32b93SJeremy L Thompson /// @}
146cdf32b93SJeremy L Thompson 
147cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
148777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API
149777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
150777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend
151777ff853SJeremy L Thompson /// @{
152777ff853SJeremy L Thompson 
153777ff853SJeremy L Thompson /**
154ca94c3ddSJeremy L Thompson   @brief Get the `Ceed` associated with a `CeedQFunctionContext`
155777ff853SJeremy L Thompson 
156ca94c3ddSJeremy L Thompson   @param[in]  ctx  `CeedQFunctionContext`
157ca94c3ddSJeremy L Thompson   @param[out] ceed Variable to store `Ceed`
158777ff853SJeremy L Thompson 
159777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
160777ff853SJeremy L Thompson 
161777ff853SJeremy L Thompson   @ref Backend
162777ff853SJeremy L Thompson **/
163777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) {
164b0f67a9cSJeremy L Thompson   CeedCall(CeedObjectGetCeed((CeedObject)ctx, ceed));
165e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
166777ff853SJeremy L Thompson }
167777ff853SJeremy L Thompson 
168777ff853SJeremy L Thompson /**
1696e536b99SJeremy L Thompson   @brief Return the `Ceed` associated with a `CeedQFunctionContext`
1706e536b99SJeremy L Thompson 
1716e536b99SJeremy L Thompson   @param[in]  ctx  `CeedQFunctionContext`
1726e536b99SJeremy L Thompson 
1736e536b99SJeremy L Thompson   @return `Ceed` associated with `ctx`
1746e536b99SJeremy L Thompson 
1756e536b99SJeremy L Thompson   @ref Backend
1766e536b99SJeremy L Thompson **/
177b0f67a9cSJeremy L Thompson Ceed CeedQFunctionContextReturnCeed(CeedQFunctionContext ctx) { return CeedObjectReturnCeed((CeedObject)ctx); }
1786e536b99SJeremy L Thompson 
1796e536b99SJeremy L Thompson /**
180ca94c3ddSJeremy L Thompson   @brief Check for valid data in a `CeedQFunctionContext`
1819c774eddSJeremy L Thompson 
182ca94c3ddSJeremy L Thompson   @param[in]  ctx            `CeedQFunctionContext` to check validity
1839c774eddSJeremy L Thompson   @param[out] has_valid_data Variable to store validity
1849c774eddSJeremy L Thompson 
1859c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1869c774eddSJeremy L Thompson 
1879c774eddSJeremy L Thompson   @ref Backend
1889c774eddSJeremy L Thompson **/
1892b730f8bSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx, bool *has_valid_data) {
1906e536b99SJeremy L Thompson   CeedCheck(ctx->HasValidData, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED,
1916e536b99SJeremy L Thompson             "Backend does not support CeedQFunctionContextHasValidData");
1922b730f8bSJeremy L Thompson   CeedCall(ctx->HasValidData(ctx, has_valid_data));
1939c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1949c774eddSJeremy L Thompson }
1959c774eddSJeremy L Thompson 
1969c774eddSJeremy L Thompson /**
197ca94c3ddSJeremy L Thompson   @brief Check for borrowed data of a specific @ref CeedMemType in a `CeedQFunctionContext`
1989c774eddSJeremy L Thompson 
199ca94c3ddSJeremy L Thompson   @param[in]  ctx                       `CeedQFunctionContext` to check
200ea61e9acSJeremy L Thompson   @param[in]  mem_type                  Memory type to check
2019c774eddSJeremy L Thompson   @param[out] has_borrowed_data_of_type Variable to store result
2029c774eddSJeremy L Thompson 
2039c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
2049c774eddSJeremy L Thompson 
2059c774eddSJeremy L Thompson   @ref Backend
2069c774eddSJeremy L Thompson **/
2072b730f8bSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx, CeedMemType mem_type, bool *has_borrowed_data_of_type) {
2086e536b99SJeremy L Thompson   CeedCheck(ctx->HasBorrowedDataOfType, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED,
2096e536b99SJeremy L Thompson             "Backend does not support CeedQFunctionContextHasBorrowedDataOfType");
2102b730f8bSJeremy L Thompson   CeedCall(ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type));
2119c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
2129c774eddSJeremy L Thompson }
2139c774eddSJeremy L Thompson 
2149c774eddSJeremy L Thompson /**
215ca94c3ddSJeremy L Thompson   @brief Get the state of a `CeedQFunctionContext`
216777ff853SJeremy L Thompson 
217ca94c3ddSJeremy L Thompson   @param[in]  ctx   `CeedQFunctionContext` to retrieve state
218777ff853SJeremy L Thompson   @param[out] state Variable to store state
219777ff853SJeremy L Thompson 
220777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
221777ff853SJeremy L Thompson 
222777ff853SJeremy L Thompson   @ref Backend
223777ff853SJeremy L Thompson **/
224777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) {
225777ff853SJeremy L Thompson   *state = ctx->state;
226e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
227777ff853SJeremy L Thompson }
228777ff853SJeremy L Thompson 
229777ff853SJeremy L Thompson /**
230ca94c3ddSJeremy L Thompson   @brief Get backend data of a `CeedQFunctionContext`
231777ff853SJeremy L Thompson 
232ca94c3ddSJeremy L Thompson   @param[in]  ctx  `CeedQFunctionContext`
233777ff853SJeremy L Thompson   @param[out] data Variable to store data
234777ff853SJeremy L Thompson 
235777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
236777ff853SJeremy L Thompson 
237777ff853SJeremy L Thompson   @ref Backend
238777ff853SJeremy L Thompson **/
239777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) {
240777ff853SJeremy L Thompson   *(void **)data = ctx->data;
241e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
242777ff853SJeremy L Thompson }
243777ff853SJeremy L Thompson 
244777ff853SJeremy L Thompson /**
245ca94c3ddSJeremy L Thompson   @brief Set backend data of a `CeedQFunctionContext`
246777ff853SJeremy L Thompson 
247ca94c3ddSJeremy L Thompson   @param[in,out] ctx  `CeedQFunctionContext`
248ea61e9acSJeremy L Thompson   @param[in]     data Data to set
249777ff853SJeremy L Thompson 
250777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
251777ff853SJeremy L Thompson 
252777ff853SJeremy L Thompson   @ref Backend
253777ff853SJeremy L Thompson **/
254777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) {
255777ff853SJeremy L Thompson   ctx->data = data;
256e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
257777ff853SJeremy L Thompson }
258777ff853SJeremy L Thompson 
25934359f16Sjeremylt /**
260ca94c3ddSJeremy L Thompson   @brief Get label for a registered `CeedQFunctionContext` field, or `NULL` if no field has been registered with this `field_name`
261e6a0ab89SJeremy L Thompson 
262ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
263e6a0ab89SJeremy L Thompson   @param[in]  field_name  Name of field to retrieve label
264e6a0ab89SJeremy L Thompson   @param[out] field_label Variable to field label
265e6a0ab89SJeremy L Thompson 
266e6a0ab89SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
267e6a0ab89SJeremy L Thompson 
2683e1e85abSJeremy L Thompson   @ref Backend
269e6a0ab89SJeremy L Thompson **/
2702b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx, const char *field_name, CeedContextFieldLabel *field_label) {
271e6a0ab89SJeremy L Thompson   CeedInt field_index;
2721c66c397SJeremy L Thompson 
2732b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index));
274e6a0ab89SJeremy L Thompson 
275e6a0ab89SJeremy L Thompson   if (field_index != -1) {
276e6a0ab89SJeremy L Thompson     *field_label = ctx->field_labels[field_index];
277e6a0ab89SJeremy L Thompson   } else {
278e6a0ab89SJeremy L Thompson     *field_label = NULL;
279e6a0ab89SJeremy L Thompson   }
280e6a0ab89SJeremy L Thompson   return CEED_ERROR_SUCCESS;
281e6a0ab89SJeremy L Thompson }
282e6a0ab89SJeremy L Thompson 
283e6a0ab89SJeremy L Thompson /**
284ca94c3ddSJeremy L Thompson   @brief Set `CeedQFunctionContext` field
285d8dd9a91SJeremy L Thompson 
286ca94c3ddSJeremy L Thompson   @param[in,out] ctx         `CeedQFunctionContext`
287ea61e9acSJeremy L Thompson   @param[in]     field_label Label of field to set
288ea61e9acSJeremy L Thompson   @param[in]     field_type  Type of field to set
2892788fa27SJeremy L Thompson   @param[in]     values      Value to set
290d8dd9a91SJeremy L Thompson 
291d8dd9a91SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
292d8dd9a91SJeremy L Thompson 
2933e1e85abSJeremy L Thompson   @ref Backend
294d8dd9a91SJeremy L Thompson **/
2952788fa27SJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *values) {
2961a34d7dcSJeremy L Thompson   bool  is_different;
2971c66c397SJeremy L Thompson   char *data;
2981c66c397SJeremy L Thompson 
2993668ca4bSJeremy L Thompson   // Check field type
3006e536b99SJeremy L Thompson   CeedCheck(field_label->type == field_type, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED,
3016574a04fSJeremy L Thompson             "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name,
3026574a04fSJeremy L Thompson             CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
303d8dd9a91SJeremy L Thompson 
3041a34d7dcSJeremy L Thompson   CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data));
3051a34d7dcSJeremy L Thompson   is_different = memcmp(&data[field_label->offset], values, field_label->size);
3061a34d7dcSJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreDataRead(ctx, &data));
3071a34d7dcSJeremy L Thompson   if (is_different) {
3082b730f8bSJeremy L Thompson     CeedCall(CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data));
3092788fa27SJeremy L Thompson     memcpy(&data[field_label->offset], values, field_label->size);
3102b730f8bSJeremy L Thompson     CeedCall(CeedQFunctionContextRestoreData(ctx, &data));
3111a34d7dcSJeremy L Thompson   }
312d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
313d8dd9a91SJeremy L Thompson }
314d8dd9a91SJeremy L Thompson 
315d8dd9a91SJeremy L Thompson /**
316ca94c3ddSJeremy L Thompson   @brief Get `CeedQFunctionContext` field data, read-only
3172788fa27SJeremy L Thompson 
318ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
3192788fa27SJeremy L Thompson   @param[in]  field_label Label of field to read
3202788fa27SJeremy L Thompson   @param[in]  field_type  Type of field to read
3212788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
3222788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
3232788fa27SJeremy L Thompson 
3242788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
3252788fa27SJeremy L Thompson 
3262788fa27SJeremy L Thompson   @ref Backend
3272788fa27SJeremy L Thompson **/
3282788fa27SJeremy L Thompson int CeedQFunctionContextGetGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type,
3292788fa27SJeremy L Thompson                                        size_t *num_values, void *values) {
3301c66c397SJeremy L Thompson   char *data;
3311c66c397SJeremy L Thompson 
3322788fa27SJeremy L Thompson   // Check field type
3336e536b99SJeremy L Thompson   CeedCheck(field_label->type == field_type, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED,
3346574a04fSJeremy L Thompson             "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name,
3356574a04fSJeremy L Thompson             CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
3362788fa27SJeremy L Thompson 
3372788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data));
3382788fa27SJeremy L Thompson   *(void **)values = &data[field_label->offset];
3392788fa27SJeremy L Thompson   switch (field_type) {
3402788fa27SJeremy L Thompson     case CEED_CONTEXT_FIELD_INT32:
3412788fa27SJeremy L Thompson       *num_values = field_label->size / sizeof(int);
3422788fa27SJeremy L Thompson       break;
3432788fa27SJeremy L Thompson     case CEED_CONTEXT_FIELD_DOUBLE:
3442788fa27SJeremy L Thompson       *num_values = field_label->size / sizeof(double);
3452788fa27SJeremy L Thompson       break;
3465b6ec284SJeremy L Thompson     case CEED_CONTEXT_FIELD_BOOL:
3475b6ec284SJeremy L Thompson       *num_values = field_label->size / sizeof(bool);
3485b6ec284SJeremy L Thompson       break;
3492788fa27SJeremy L Thompson   }
3502788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3512788fa27SJeremy L Thompson }
3522788fa27SJeremy L Thompson 
3532788fa27SJeremy L Thompson /**
354ca94c3ddSJeremy L Thompson   @brief Restore `CeedQFunctionContext` field data, read-only
3552788fa27SJeremy L Thompson 
356ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
3572788fa27SJeremy L Thompson   @param[in]  field_label Label of field to restore
3582788fa27SJeremy L Thompson   @param[in]  field_type  Type of field to restore
3592788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
3602788fa27SJeremy L Thompson 
3612788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
3622788fa27SJeremy L Thompson 
3632788fa27SJeremy L Thompson   @ref Backend
3642788fa27SJeremy L Thompson **/
3652788fa27SJeremy L Thompson int CeedQFunctionContextRestoreGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type,
3662788fa27SJeremy L Thompson                                            void *values) {
3672788fa27SJeremy L Thompson   // Check field type
3686e536b99SJeremy L Thompson   CeedCheck(field_label->type == field_type, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED,
3696574a04fSJeremy L Thompson             "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name,
3706574a04fSJeremy L Thompson             CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
3712788fa27SJeremy L Thompson 
3722788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreDataRead(ctx, values));
3732788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3742788fa27SJeremy L Thompson }
3752788fa27SJeremy L Thompson 
3762788fa27SJeremy L Thompson /**
377ca94c3ddSJeremy L Thompson   @brief Set `CeedQFunctionContext` field holding double precision values
378bfacc300SJeremy L Thompson 
379ca94c3ddSJeremy L Thompson   @param[in,out] ctx         `CeedQFunctionContext`
3802788fa27SJeremy L Thompson   @param[in]     field_label Label for field to set
381ea61e9acSJeremy L Thompson   @param[in]     values      Values to set
382bfacc300SJeremy L Thompson 
383bfacc300SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
384bfacc300SJeremy L Thompson 
3853e1e85abSJeremy L Thompson   @ref Backend
386bfacc300SJeremy L Thompson **/
3872b730f8bSJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, double *values) {
3886e536b99SJeremy L Thompson   CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
3892b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values));
390bfacc300SJeremy L Thompson   return CEED_ERROR_SUCCESS;
391bfacc300SJeremy L Thompson }
392bfacc300SJeremy L Thompson 
393bfacc300SJeremy L Thompson /**
394ca94c3ddSJeremy L Thompson   @brief Get `CeedQFunctionContext` field holding double precision values, read-only
3952788fa27SJeremy L Thompson 
396ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
3972788fa27SJeremy L Thompson   @param[in]  field_label Label for field to get
3982788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
3992788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
4002788fa27SJeremy L Thompson 
4012788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4022788fa27SJeremy L Thompson 
4032788fa27SJeremy L Thompson   @ref Backend
4042788fa27SJeremy L Thompson **/
4052788fa27SJeremy L Thompson int CeedQFunctionContextGetDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const double **values) {
4066e536b99SJeremy L Thompson   CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
4072788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values));
4082788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4092788fa27SJeremy L Thompson }
4102788fa27SJeremy L Thompson 
4112788fa27SJeremy L Thompson /**
412ca94c3ddSJeremy L Thompson   @brief Restore `CeedQFunctionContext` field holding double precision values, read-only
4132788fa27SJeremy L Thompson 
414ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
4152788fa27SJeremy L Thompson   @param[in]  field_label Label for field to restore
4162788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
4172788fa27SJeremy L Thompson 
4182788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4192788fa27SJeremy L Thompson 
4202788fa27SJeremy L Thompson   @ref Backend
4212788fa27SJeremy L Thompson **/
4222788fa27SJeremy L Thompson int CeedQFunctionContextRestoreDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const double **values) {
4236e536b99SJeremy L Thompson   CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
4242788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values));
4252788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4262788fa27SJeremy L Thompson }
4272788fa27SJeremy L Thompson 
4282788fa27SJeremy L Thompson /**
429ca94c3ddSJeremy L Thompson   @brief Set CeedQFunctionContext field holding `int32` values
430bfacc300SJeremy L Thompson 
431ea61e9acSJeremy L Thompson   @param[in,out] ctx         CeedQFunctionContext
4322788fa27SJeremy L Thompson   @param[in]     field_label Label for field to set
433ea61e9acSJeremy L Thompson   @param[in]     values      Values to set
434bfacc300SJeremy L Thompson 
435bfacc300SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
436bfacc300SJeremy L Thompson 
4373e1e85abSJeremy L Thompson   @ref Backend
438bfacc300SJeremy L Thompson **/
43923dbfd29SJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, int32_t *values) {
4406e536b99SJeremy L Thompson   CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
4412b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values));
442bfacc300SJeremy L Thompson   return CEED_ERROR_SUCCESS;
443bfacc300SJeremy L Thompson }
444bfacc300SJeremy L Thompson 
445bfacc300SJeremy L Thompson /**
446ca94c3ddSJeremy L Thompson   @brief Get `CeedQFunctionContext` field holding `int32` values, read-only
4472788fa27SJeremy L Thompson 
448ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
4492788fa27SJeremy L Thompson   @param[in]  field_label Label for field to get
4502788fa27SJeremy L Thompson   @param[out] num_values  Number of values in the field label
4512788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
4522788fa27SJeremy L Thompson 
4532788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4542788fa27SJeremy L Thompson 
4552788fa27SJeremy L Thompson   @ref Backend
4562788fa27SJeremy L Thompson **/
45723dbfd29SJeremy L Thompson int CeedQFunctionContextGetInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const int32_t **values) {
4586e536b99SJeremy L Thompson   CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
4592788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values));
4602788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4612788fa27SJeremy L Thompson }
4622788fa27SJeremy L Thompson 
4632788fa27SJeremy L Thompson /**
464ca94c3ddSJeremy L Thompson   @brief Restore `CeedQFunctionContext` field holding `int32` values, read-only
4652788fa27SJeremy L Thompson 
466ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
4672788fa27SJeremy L Thompson   @param[in]  field_label Label for field to restore
4682788fa27SJeremy L Thompson   @param[out] values      Pointer to context values
4692788fa27SJeremy L Thompson 
4702788fa27SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4712788fa27SJeremy L Thompson 
4722788fa27SJeremy L Thompson   @ref Backend
4732788fa27SJeremy L Thompson **/
47423dbfd29SJeremy L Thompson int CeedQFunctionContextRestoreInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const int32_t **values) {
4756e536b99SJeremy L Thompson   CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
4762788fa27SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values));
4772788fa27SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4782788fa27SJeremy L Thompson }
4792788fa27SJeremy L Thompson 
4802788fa27SJeremy L Thompson /**
481ca94c3ddSJeremy L Thompson   @brief Set `CeedQFunctionContext` field holding boolean values
4825b6ec284SJeremy L Thompson 
483ca94c3ddSJeremy L Thompson   @param[in,out] ctx         `CeedQFunctionContext`
4845b6ec284SJeremy L Thompson   @param[in]     field_label Label for field to set
4855b6ec284SJeremy L Thompson   @param[in]     values      Values to set
4865b6ec284SJeremy L Thompson 
4875b6ec284SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
4885b6ec284SJeremy L Thompson 
4895b6ec284SJeremy L Thompson   @ref Backend
4905b6ec284SJeremy L Thompson **/
4915b6ec284SJeremy L Thompson int CeedQFunctionContextSetBoolean(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, bool *values) {
4926e536b99SJeremy L Thompson   CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
4935b6ec284SJeremy L Thompson   CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, values));
4945b6ec284SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4955b6ec284SJeremy L Thompson }
4965b6ec284SJeremy L Thompson 
4975b6ec284SJeremy L Thompson /**
498ca94c3ddSJeremy L Thompson   @brief Get `CeedQFunctionContext` field holding boolean values, read-only
4995b6ec284SJeremy L Thompson 
500ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
5015b6ec284SJeremy L Thompson   @param[in]  field_label Label for field to get
5025b6ec284SJeremy L Thompson   @param[out] num_values  Number of values in the field label
5035b6ec284SJeremy L Thompson   @param[out] values      Pointer to context values
5045b6ec284SJeremy L Thompson 
5055b6ec284SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
5065b6ec284SJeremy L Thompson 
5075b6ec284SJeremy L Thompson   @ref Backend
5085b6ec284SJeremy L Thompson **/
5095b6ec284SJeremy L Thompson int CeedQFunctionContextGetBooleanRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const bool **values) {
5106e536b99SJeremy L Thompson   CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
5115b6ec284SJeremy L Thompson   CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, num_values, values));
5125b6ec284SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5135b6ec284SJeremy L Thompson }
5145b6ec284SJeremy L Thompson 
5155b6ec284SJeremy L Thompson /**
516ca94c3ddSJeremy L Thompson   @brief Restore `CeedQFunctionContext` field holding boolean values, read-only
5175b6ec284SJeremy L Thompson 
518ca94c3ddSJeremy L Thompson   @param[in]  ctx         `CeedQFunctionContext`
5195b6ec284SJeremy L Thompson   @param[in]  field_label Label for field to restore
5205b6ec284SJeremy L Thompson   @param[out] values      Pointer to context values
5215b6ec284SJeremy L Thompson 
5225b6ec284SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
5235b6ec284SJeremy L Thompson 
5245b6ec284SJeremy L Thompson   @ref Backend
5255b6ec284SJeremy L Thompson **/
5265b6ec284SJeremy L Thompson int CeedQFunctionContextRestoreBooleanRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const bool **values) {
5276e536b99SJeremy L Thompson   CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
5285b6ec284SJeremy L Thompson   CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, values));
5295b6ec284SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5305b6ec284SJeremy L Thompson }
5315b6ec284SJeremy L Thompson 
5325b6ec284SJeremy L Thompson /**
533ca94c3ddSJeremy L Thompson   @brief Get additional destroy routine for `CeedQFunctionContext` user data
5342e64a2b9SJeremy L Thompson 
535ca94c3ddSJeremy L Thompson   @param[in] ctx         `CeedQFunctionContext` to get user destroy function
5362e64a2b9SJeremy L Thompson   @param[out] f_mem_type Memory type to use when passing data into `f`
5372e64a2b9SJeremy L Thompson   @param[out] f          Additional routine to use to destroy user data
5382e64a2b9SJeremy L Thompson 
5392e64a2b9SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
5402e64a2b9SJeremy L Thompson 
5412e64a2b9SJeremy L Thompson   @ref Backend
5422e64a2b9SJeremy L Thompson **/
5432b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx, CeedMemType *f_mem_type, CeedQFunctionContextDataDestroyUser *f) {
5442e64a2b9SJeremy L Thompson   if (f_mem_type) *f_mem_type = ctx->data_destroy_mem_type;
5452e64a2b9SJeremy L Thompson   if (f) *f = ctx->data_destroy_function;
5462e64a2b9SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5472e64a2b9SJeremy L Thompson }
5482e64a2b9SJeremy L Thompson 
5492e64a2b9SJeremy L Thompson /**
550ca94c3ddSJeremy L Thompson   @brief Increment the reference counter for a `CeedQFunctionContext`
55134359f16Sjeremylt 
552ca94c3ddSJeremy L Thompson   @param[in,out] ctx `CeedQFunctionContext` to increment the reference counter
55334359f16Sjeremylt 
55434359f16Sjeremylt   @return An error code: 0 - success, otherwise - failure
55534359f16Sjeremylt 
55634359f16Sjeremylt   @ref Backend
55734359f16Sjeremylt **/
5589560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) {
559b0f67a9cSJeremy L Thompson   CeedCall(CeedObjectReference((CeedObject)ctx));
56034359f16Sjeremylt   return CEED_ERROR_SUCCESS;
56134359f16Sjeremylt }
56234359f16Sjeremylt 
563777ff853SJeremy L Thompson /// @}
564777ff853SJeremy L Thompson 
565777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
566777ff853SJeremy L Thompson /// CeedQFunctionContext Public API
567777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
568777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser
569777ff853SJeremy L Thompson /// @{
570777ff853SJeremy L Thompson 
571777ff853SJeremy L Thompson /**
572ca94c3ddSJeremy L Thompson   @brief Create a `CeedQFunctionContext` for storing `CeedQFunctionContext` user context data
573777ff853SJeremy L Thompson 
574ca94c3ddSJeremy L Thompson   @param[in]  ceed `Ceed` object used to create the `CeedQFunctionContext`
575ca94c3ddSJeremy L Thompson   @param[out] ctx  Address of the variable where the newly created `CeedQFunctionContext` will be stored
576777ff853SJeremy L Thompson 
577777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
578777ff853SJeremy L Thompson 
579777ff853SJeremy L Thompson   @ref User
580777ff853SJeremy L Thompson **/
581777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) {
582777ff853SJeremy L Thompson   if (!ceed->QFunctionContextCreate) {
583777ff853SJeremy L Thompson     Ceed delegate;
5846574a04fSJeremy L Thompson 
5852b730f8bSJeremy L Thompson     CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Context"));
5861ef3a2a9SJeremy L Thompson     CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedQFunctionContextCreate");
5872b730f8bSJeremy L Thompson     CeedCall(CeedQFunctionContextCreate(delegate, ctx));
5889bc66399SJeremy L Thompson     CeedCall(CeedDestroy(&delegate));
589e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
590777ff853SJeremy L Thompson   }
591777ff853SJeremy L Thompson 
5922b730f8bSJeremy L Thompson   CeedCall(CeedCalloc(1, ctx));
593b0f67a9cSJeremy L Thompson   CeedCall(CeedObjectCreate(ceed, CeedQFunctionContextView_Object, &(*ctx)->obj));
5942b730f8bSJeremy L Thompson   CeedCall(ceed->QFunctionContextCreate(*ctx));
595e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
596777ff853SJeremy L Thompson }
597777ff853SJeremy L Thompson 
598777ff853SJeremy L Thompson /**
599ca94c3ddSJeremy L Thompson   @brief Copy the pointer to a `CeedQFunctionContext`.
6004385fb7fSSebastian Grimberg 
601ca94c3ddSJeremy L Thompson   Both pointers should be destroyed with @ref CeedQFunctionContextDestroy().
602512bb800SJeremy L Thompson 
603ca94c3ddSJeremy L Thompson   Note: If the value of `*ctx_copy` passed to this function is non-`NULL`, then it is assumed that `*ctx_copy` is a pointer to a `CeedQFunctionContext`.
604ca94c3ddSJeremy L Thompson         This `CeedQFunctionContext` will be destroyed if `*ctx_copy` is the only reference to this `CeedQFunctionContext`.
6059560d06aSjeremylt 
606ea61e9acSJeremy L Thompson   @param[in]     ctx      CeedQFunctionContext to copy reference to
607ea61e9acSJeremy L Thompson   @param[in,out] ctx_copy Variable to store copied reference
6089560d06aSjeremylt 
6099560d06aSjeremylt   @return An error code: 0 - success, otherwise - failure
6109560d06aSjeremylt 
6119560d06aSjeremylt   @ref User
6129560d06aSjeremylt **/
6132b730f8bSJeremy L Thompson int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, CeedQFunctionContext *ctx_copy) {
6142b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextReference(ctx));
6152b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroy(ctx_copy));
6169560d06aSjeremylt   *ctx_copy = ctx;
6179560d06aSjeremylt   return CEED_ERROR_SUCCESS;
6189560d06aSjeremylt }
6199560d06aSjeremylt 
6209560d06aSjeremylt /**
621ca94c3ddSJeremy L Thompson   @brief Set the data used by a `CeedQFunctionContext`, freeing any previously allocated data if applicable.
6224385fb7fSSebastian Grimberg 
623ca94c3ddSJeremy L Thompson   The backend may copy values to a different @ref CeedMemType, such as during @ref CeedQFunctionApply().
624777ff853SJeremy L Thompson   See also @ref CeedQFunctionContextTakeData().
625777ff853SJeremy L Thompson 
626ca94c3ddSJeremy L Thompson   @param[in,out] ctx       `CeedQFunctionContext`
627ea61e9acSJeremy L Thompson   @param[in]     mem_type  Memory type of the data being passed
628ea61e9acSJeremy L Thompson   @param[in]     copy_mode Copy mode for the data
629ea61e9acSJeremy L Thompson   @param[in]     size      Size of data, in bytes
630ea61e9acSJeremy L Thompson   @param[in]     data      Data to be used
631777ff853SJeremy L Thompson 
632777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
633777ff853SJeremy L Thompson 
634777ff853SJeremy L Thompson   @ref User
635777ff853SJeremy L Thompson **/
6362b730f8bSJeremy L Thompson int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, size_t size, void *data) {
6379bc66399SJeremy L Thompson   CeedCheck(ctx->SetData, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextSetData");
6389bc66399SJeremy L Thompson   CeedCheck(ctx->state % 2 == 0, CeedQFunctionContextReturnCeed(ctx), 1,
6399bc66399SJeremy L Thompson             "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
640777ff853SJeremy L Thompson 
6412b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroyData(ctx));
642d1d35e2fSjeremylt   ctx->ctx_size = size;
6432b730f8bSJeremy L Thompson   CeedCall(ctx->SetData(ctx, mem_type, copy_mode, data));
644777ff853SJeremy L Thompson   ctx->state += 2;
645e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
646777ff853SJeremy L Thompson }
647777ff853SJeremy L Thompson 
648777ff853SJeremy L Thompson /**
649ca94c3ddSJeremy L Thompson   @brief Take ownership of the data in a `CeedQFunctionContext` via the specified memory type.
6504385fb7fSSebastian Grimberg 
651891038deSjeremylt   The caller is responsible for managing and freeing the memory.
652891038deSjeremylt 
653ca94c3ddSJeremy L Thompson   @param[in]  ctx      `CeedQFunctionContext` to access
654ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
655ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
656891038deSjeremylt   @param[out] data     Data on memory type mem_type
657891038deSjeremylt 
658891038deSjeremylt   @return An error code: 0 - success, otherwise - failure
659891038deSjeremylt 
660891038deSjeremylt   @ref User
661891038deSjeremylt **/
6622b730f8bSJeremy L Thompson int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
6631c66c397SJeremy L Thompson   void *temp_data      = NULL;
6641c66c397SJeremy L Thompson   bool  has_valid_data = true, has_borrowed_data_of_type = true;
6651c66c397SJeremy L Thompson 
6662b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
6679bc66399SJeremy L Thompson   CeedCheck(has_valid_data, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to take, must set data");
6689c774eddSJeremy L Thompson 
6699bc66399SJeremy L Thompson   CeedCheck(ctx->TakeData, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextTakeData");
6709bc66399SJeremy L Thompson   CeedCheck(ctx->state % 2 == 0, CeedQFunctionContextReturnCeed(ctx), 1,
6719bc66399SJeremy L Thompson             "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
672891038deSjeremylt 
6732b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, &has_borrowed_data_of_type));
6749bc66399SJeremy L Thompson   CeedCheck(has_borrowed_data_of_type, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND,
6756574a04fSJeremy L Thompson             "CeedQFunctionContext has no borrowed %s data, must set data with CeedQFunctionContextSetData", CeedMemTypes[mem_type]);
6769c774eddSJeremy L Thompson 
6772b730f8bSJeremy L Thompson   CeedCall(ctx->TakeData(ctx, mem_type, &temp_data));
678891038deSjeremylt   if (data) (*(void **)data) = temp_data;
679891038deSjeremylt   return CEED_ERROR_SUCCESS;
680891038deSjeremylt }
681891038deSjeremylt 
682891038deSjeremylt /**
683ca94c3ddSJeremy L Thompson   @brief Get read/write access to a `CeedQFunctionContext` via the specified memory type.
6844385fb7fSSebastian Grimberg 
685777ff853SJeremy L Thompson   Restore access with @ref CeedQFunctionContextRestoreData().
686777ff853SJeremy L Thompson 
687ca94c3ddSJeremy L Thompson   @param[in]  ctx      `CeedQFunctionContext` to access
688ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
689ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
690d1d35e2fSjeremylt   @param[out] data     Data on memory type mem_type
691777ff853SJeremy L Thompson 
692ca94c3ddSJeremy L Thompson   @note The @ref CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions provide access to array pointers in the desired memory space.
693ca94c3ddSJeremy L Thompson         Pairing get/restore allows the `CeedQFunctionContext` to track access.
694777ff853SJeremy L Thompson 
695777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
696777ff853SJeremy L Thompson 
697777ff853SJeremy L Thompson   @ref User
698777ff853SJeremy L Thompson **/
6992b730f8bSJeremy L Thompson int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
7001c66c397SJeremy L Thompson   bool has_valid_data = true;
7011c66c397SJeremy L Thompson 
7029bc66399SJeremy L Thompson   CeedCheck(ctx->GetData, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextGetData");
7039bc66399SJeremy L Thompson   CeedCheck(ctx->state % 2 == 0, CeedQFunctionContextReturnCeed(ctx), 1,
7049bc66399SJeremy L Thompson             "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
7059bc66399SJeremy L Thompson   CeedCheck(ctx->num_readers == 0, CeedQFunctionContextReturnCeed(ctx), 1,
7069bc66399SJeremy L Thompson             "Cannot grant CeedQFunctionContext data access, a process has read access");
70728bfd0b7SJeremy L Thompson 
7082b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
7099bc66399SJeremy L Thompson   CeedCheck(has_valid_data, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data");
7109c774eddSJeremy L Thompson 
7112b730f8bSJeremy L Thompson   CeedCall(ctx->GetData(ctx, mem_type, data));
71228bfd0b7SJeremy L Thompson   ctx->state++;
71328bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
71428bfd0b7SJeremy L Thompson }
71528bfd0b7SJeremy L Thompson 
71628bfd0b7SJeremy L Thompson /**
717ca94c3ddSJeremy L Thompson   @brief Get read only access to a `CeedQFunctionContext` via the specified memory type.
7184385fb7fSSebastian Grimberg 
71928bfd0b7SJeremy L Thompson   Restore access with @ref CeedQFunctionContextRestoreData().
72028bfd0b7SJeremy L Thompson 
721ca94c3ddSJeremy L Thompson   @param[in]  ctx      `CeedQFunctionContext` to access
722ea61e9acSJeremy L Thompson   @param[in]  mem_type Memory type on which to access the data.
723ea61e9acSJeremy L Thompson                          If the backend uses a different memory type, this will perform a copy.
72428bfd0b7SJeremy L Thompson   @param[out] data     Data on memory type mem_type
72528bfd0b7SJeremy L Thompson 
726ca94c3ddSJeremy L Thompson   @note The @ref CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead() functions provide access to array pointers in the desired memory space.
727ca94c3ddSJeremy L Thompson         Pairing get/restore allows the `CeedQFunctionContext` to track access.
72828bfd0b7SJeremy L Thompson 
72928bfd0b7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
73028bfd0b7SJeremy L Thompson 
73128bfd0b7SJeremy L Thompson   @ref User
73228bfd0b7SJeremy L Thompson **/
7332b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
7341c66c397SJeremy L Thompson   bool has_valid_data = true;
7351c66c397SJeremy L Thompson 
7369bc66399SJeremy L Thompson   CeedCheck(ctx->GetDataRead, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED,
7379bc66399SJeremy L Thompson             "Backend does not support CeedQFunctionContextGetDataRead");
7389bc66399SJeremy L Thompson   CeedCheck(ctx->state % 2 == 0, CeedQFunctionContextReturnCeed(ctx), 1,
7399bc66399SJeremy L Thompson             "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
74028bfd0b7SJeremy L Thompson 
7412b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
7429bc66399SJeremy L Thompson   CeedCheck(has_valid_data, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data");
74328bfd0b7SJeremy L Thompson 
7442b730f8bSJeremy L Thompson   CeedCall(ctx->GetDataRead(ctx, mem_type, data));
74528bfd0b7SJeremy L Thompson   ctx->num_readers++;
746e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
747777ff853SJeremy L Thompson }
748777ff853SJeremy L Thompson 
749777ff853SJeremy L Thompson /**
750777ff853SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetData()
751777ff853SJeremy L Thompson 
752ca94c3ddSJeremy L Thompson   @param[in]     ctx  `CeedQFunctionContext` to restore
753ea61e9acSJeremy L Thompson   @param[in,out] data Data to restore
754777ff853SJeremy L Thompson 
755777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
756777ff853SJeremy L Thompson 
757777ff853SJeremy L Thompson   @ref User
758777ff853SJeremy L Thompson **/
759777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) {
7606e536b99SJeremy L Thompson   CeedCheck(ctx->state % 2 == 1, CeedQFunctionContextReturnCeed(ctx), 1, "Cannot restore CeedQFunctionContext array access, access was not granted");
761777ff853SJeremy L Thompson 
7626574a04fSJeremy L Thompson   if (ctx->RestoreData) CeedCall(ctx->RestoreData(ctx));
763777ff853SJeremy L Thompson   *(void **)data = NULL;
76428bfd0b7SJeremy L Thompson   ctx->state++;
76528bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
76628bfd0b7SJeremy L Thompson }
76728bfd0b7SJeremy L Thompson 
76828bfd0b7SJeremy L Thompson /**
76928bfd0b7SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead()
77028bfd0b7SJeremy L Thompson 
771ca94c3ddSJeremy L Thompson   @param[in]     ctx  `CeedQFunctionContext` to restore
772ea61e9acSJeremy L Thompson   @param[in,out] data Data to restore
77328bfd0b7SJeremy L Thompson 
77428bfd0b7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
77528bfd0b7SJeremy L Thompson 
77628bfd0b7SJeremy L Thompson   @ref User
77728bfd0b7SJeremy L Thompson **/
77828bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) {
7796e536b99SJeremy L Thompson   CeedCheck(ctx->num_readers > 0, CeedQFunctionContextReturnCeed(ctx), 1, "Cannot restore CeedQFunctionContext array access, access was not granted");
78028bfd0b7SJeremy L Thompson 
78175a19770SJeremy L Thompson   ctx->num_readers--;
7826574a04fSJeremy L Thompson   if (ctx->num_readers == 0 && ctx->RestoreDataRead) CeedCall(ctx->RestoreDataRead(ctx));
78328bfd0b7SJeremy L Thompson   *(void **)data = NULL;
784e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
785777ff853SJeremy L Thompson }
786777ff853SJeremy L Thompson 
787777ff853SJeremy L Thompson /**
788ca94c3ddSJeremy L Thompson   @brief Register a `CeedQFunctionContext` field holding double precision values
789cdf32b93SJeremy L Thompson 
790ca94c3ddSJeremy L Thompson   @param[in,out] ctx               `CeedQFunctionContext`
791ea61e9acSJeremy L Thompson   @param[in]     field_name        Name of field to register
792ea61e9acSJeremy L Thompson   @param[in]     field_offset      Offset of field to register
793ea61e9acSJeremy L Thompson   @param[in]     num_values        Number of values to register, must be contiguous in memory
794ca94c3ddSJeremy L Thompson   @param[in]     field_description Description of field, or `NULL` for none
795cdf32b93SJeremy L Thompson 
796cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
797cdf32b93SJeremy L Thompson 
798cdf32b93SJeremy L Thompson   @ref User
799cdf32b93SJeremy L Thompson **/
8002b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values,
801cdf32b93SJeremy L Thompson                                        const char *field_description) {
8025b6ec284SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_DOUBLE, num_values);
803cdf32b93SJeremy L Thompson }
804cdf32b93SJeremy L Thompson 
805cdf32b93SJeremy L Thompson /**
806ca94c3ddSJeremy L Thompson   @brief Register a `CeedQFunctionContext` field holding `int32` values
807cdf32b93SJeremy L Thompson 
808ea61e9acSJeremy L Thompson   @param[in,out] ctx               CeedQFunctionContext
809ea61e9acSJeremy L Thompson   @param[in]     field_name        Name of field to register
810ea61e9acSJeremy L Thompson   @param[in]     field_offset      Offset of field to register
811ea61e9acSJeremy L Thompson   @param[in]     num_values        Number of values to register, must be contiguous in memory
812ca94c3ddSJeremy L Thompson   @param[in]     field_description Description of field, or `NULL` for none
813cdf32b93SJeremy L Thompson 
814cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
815cdf32b93SJeremy L Thompson 
816cdf32b93SJeremy L Thompson   @ref User
817cdf32b93SJeremy L Thompson **/
8182b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values,
819cdf32b93SJeremy L Thompson                                       const char *field_description) {
8205b6ec284SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_INT32, num_values);
8215b6ec284SJeremy L Thompson }
8225b6ec284SJeremy L Thompson 
8235b6ec284SJeremy L Thompson /**
824ca94c3ddSJeremy L Thompson   @brief Register a `CeedQFunctionContext` field holding boolean values
8255b6ec284SJeremy L Thompson 
826ca94c3ddSJeremy L Thompson   @param[in,out] ctx               `CeedQFunctionContext`
8275b6ec284SJeremy L Thompson   @param[in]     field_name        Name of field to register
8285b6ec284SJeremy L Thompson   @param[in]     field_offset      Offset of field to register
8295b6ec284SJeremy L Thompson   @param[in]     num_values        Number of values to register, must be contiguous in memory
830ca94c3ddSJeremy L Thompson   @param[in]     field_description Description of field, or `NULL` for none
8315b6ec284SJeremy L Thompson 
8325b6ec284SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
8335b6ec284SJeremy L Thompson 
8345b6ec284SJeremy L Thompson   @ref User
8355b6ec284SJeremy L Thompson **/
8365b6ec284SJeremy L Thompson int CeedQFunctionContextRegisterBoolean(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values,
8375b6ec284SJeremy L Thompson                                         const char *field_description) {
8385b6ec284SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_BOOL, num_values);
839cdf32b93SJeremy L Thompson }
840cdf32b93SJeremy L Thompson 
841cdf32b93SJeremy L Thompson /**
842ca94c3ddSJeremy L Thompson   @brief Get labels for all registered `CeedQFunctionContext` fields
843cdf32b93SJeremy L Thompson 
844ca94c3ddSJeremy L Thompson   @param[in]  ctx          `CeedQFunctionContext`
8453668ca4bSJeremy L Thompson   @param[out] field_labels Variable to hold array of field labels
846cdf32b93SJeremy L Thompson   @param[out] num_fields   Length of field descriptions array
847cdf32b93SJeremy L Thompson 
848cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
849cdf32b93SJeremy L Thompson 
850cdf32b93SJeremy L Thompson   @ref User
851cdf32b93SJeremy L Thompson **/
8522b730f8bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, const CeedContextFieldLabel **field_labels, CeedInt *num_fields) {
8533668ca4bSJeremy L Thompson   *field_labels = ctx->field_labels;
854cdf32b93SJeremy L Thompson   *num_fields   = ctx->num_fields;
855cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
856cdf32b93SJeremy L Thompson }
857cdf32b93SJeremy L Thompson 
858cdf32b93SJeremy L Thompson /**
859ca94c3ddSJeremy L Thompson   @brief Get the descriptive information about a `CeedContextFieldLabel`
8600f86cbe7SJeremy L Thompson 
861ca94c3ddSJeremy L Thompson   @param[in]  label             @ref CeedContextFieldLabel
8620f86cbe7SJeremy L Thompson   @param[out] field_name        Name of labeled field
8631ff07f3dSJeremy L Thompson   @param[out] field_offset      Offset of field registered
8647bfe0f0eSJeremy L Thompson   @param[out] num_values        Number of values registered
8651ff07f3dSJeremy L Thompson   @param[out] field_description Description of field, or NULL for none
866ca94c3ddSJeremy L Thompson   @param[out] field_type        @ref CeedContextFieldType
8670f86cbe7SJeremy L Thompson 
8680f86cbe7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
8690f86cbe7SJeremy L Thompson 
8700f86cbe7SJeremy L Thompson   @ref User
8710f86cbe7SJeremy L Thompson **/
8721ff07f3dSJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, const char **field_name, size_t *field_offset, size_t *num_values,
8731ff07f3dSJeremy L Thompson                                         const char **field_description, CeedContextFieldType *field_type) {
8740f86cbe7SJeremy L Thompson   if (field_name) *field_name = label->name;
8751ff07f3dSJeremy L Thompson   if (field_offset) *field_offset = label->offset;
8767bfe0f0eSJeremy L Thompson   if (num_values) *num_values = label->num_values;
8771ff07f3dSJeremy L Thompson   if (field_description) *field_description = label->description;
8780f86cbe7SJeremy L Thompson   if (field_type) *field_type = label->type;
8790f86cbe7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
8800f86cbe7SJeremy L Thompson }
8810f86cbe7SJeremy L Thompson 
8820f86cbe7SJeremy L Thompson /**
88380a9ef05SNatalie Beams   @brief Get data size for a Context
88480a9ef05SNatalie Beams 
885ca94c3ddSJeremy L Thompson   @param[in]  ctx      `CeedQFunctionContext`
88680a9ef05SNatalie Beams   @param[out] ctx_size Variable to store size of context data values
88780a9ef05SNatalie Beams 
88880a9ef05SNatalie Beams   @return An error code: 0 - success, otherwise - failure
88980a9ef05SNatalie Beams 
89080a9ef05SNatalie Beams   @ref User
89180a9ef05SNatalie Beams **/
8922b730f8bSJeremy L Thompson int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, size_t *ctx_size) {
89380a9ef05SNatalie Beams   *ctx_size = ctx->ctx_size;
89480a9ef05SNatalie Beams   return CEED_ERROR_SUCCESS;
89580a9ef05SNatalie Beams }
89680a9ef05SNatalie Beams 
89780a9ef05SNatalie Beams /**
8984c789ea2SJeremy L Thompson   @brief Set the number of tabs to indent for @ref CeedQFunctionContextView() output
8994c789ea2SJeremy L Thompson 
9004c789ea2SJeremy L Thompson   @param[in] ctx      `CeedQFunctionContext` to set the number of view tabs
9014c789ea2SJeremy L Thompson   @param[in] num_tabs Number of view tabs to set
9024c789ea2SJeremy L Thompson 
9034c789ea2SJeremy L Thompson   @return Error code: 0 - success, otherwise - failure
9044c789ea2SJeremy L Thompson 
9054c789ea2SJeremy L Thompson   @ref User
9064c789ea2SJeremy L Thompson **/
9074c789ea2SJeremy L Thompson int CeedQFunctionContextSetNumViewTabs(CeedQFunctionContext ctx, CeedInt num_tabs) {
908*a299a25bSJeremy L Thompson   CeedCall(CeedObjectSetNumViewTabs((CeedObject)ctx, num_tabs));
9094c789ea2SJeremy L Thompson   return CEED_ERROR_SUCCESS;
9104c789ea2SJeremy L Thompson }
9114c789ea2SJeremy L Thompson 
9124c789ea2SJeremy L Thompson /**
913690992b2SZach Atkins   @brief Get the number of tabs to indent for @ref CeedQFunctionContextView() output
914690992b2SZach Atkins 
915690992b2SZach Atkins   @param[in]  ctx      `CeedQFunctionContext` to get the number of view tabs
916690992b2SZach Atkins   @param[out] num_tabs Number of view tabs
917690992b2SZach Atkins 
918690992b2SZach Atkins   @return Error code: 0 - success, otherwise - failure
919690992b2SZach Atkins 
920690992b2SZach Atkins   @ref User
921690992b2SZach Atkins **/
922690992b2SZach Atkins int CeedQFunctionContextGetNumViewTabs(CeedQFunctionContext ctx, CeedInt *num_tabs) {
923*a299a25bSJeremy L Thompson   CeedCall(CeedObjectGetNumViewTabs((CeedObject)ctx, num_tabs));
924690992b2SZach Atkins   return CEED_ERROR_SUCCESS;
925690992b2SZach Atkins }
926690992b2SZach Atkins 
927690992b2SZach Atkins /**
928ca94c3ddSJeremy L Thompson   @brief View a `CeedQFunctionContext`
929777ff853SJeremy L Thompson 
930ca94c3ddSJeremy L Thompson   @param[in] ctx    `CeedQFunctionContext` to view
931777ff853SJeremy L Thompson   @param[in] stream Filestream to write to
932777ff853SJeremy L Thompson 
933777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
934777ff853SJeremy L Thompson 
935777ff853SJeremy L Thompson   @ref User
936777ff853SJeremy L Thompson **/
937777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) {
9384c789ea2SJeremy L Thompson   char *tabs = NULL;
9394c789ea2SJeremy L Thompson 
9404c789ea2SJeremy L Thompson   {
9414c789ea2SJeremy L Thompson     CeedInt num_tabs = 0;
9424c789ea2SJeremy L Thompson 
9434c789ea2SJeremy L Thompson     CeedCall(CeedQFunctionContextGetNumViewTabs(ctx, &num_tabs));
9444c789ea2SJeremy L Thompson     CeedCall(CeedCalloc(CEED_TAB_WIDTH * num_tabs + 1, &tabs));
9454c789ea2SJeremy L Thompson     for (CeedInt i = 0; i < CEED_TAB_WIDTH * num_tabs; i++) tabs[i] = ' ';
9463668ca4bSJeremy L Thompson   }
9474c789ea2SJeremy L Thompson 
9484c789ea2SJeremy L Thompson   fprintf(stream, "%sCeedQFunctionContext\n", tabs);
9494c789ea2SJeremy L Thompson   fprintf(stream, "%s  Context Data Size: %zu\n", tabs, ctx->ctx_size);
9504c789ea2SJeremy L Thompson   for (CeedInt i = 0; i < ctx->num_fields; i++) {
9514c789ea2SJeremy L Thompson     fprintf(stream, "%s  Labeled %s field: %s\n", tabs, CeedContextFieldTypes[ctx->field_labels[i]->type], ctx->field_labels[i]->name);
9524c789ea2SJeremy L Thompson   }
9534c789ea2SJeremy L Thompson   CeedCall(CeedFree(&tabs));
954e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
955777ff853SJeremy L Thompson }
956777ff853SJeremy L Thompson 
957777ff853SJeremy L Thompson /**
958ca94c3ddSJeremy L Thompson   @brief Set additional destroy routine for `CeedQFunctionContext` user data
9592790b72bSJeremy L Thompson 
960ca94c3ddSJeremy L Thompson   @param[in,out] ctx        `CeedQFunctionContext` to set user destroy function
9612e64a2b9SJeremy L Thompson   @param[in]     f_mem_type Memory type to use when passing data into `f`
9622e64a2b9SJeremy L Thompson   @param[in]     f          Additional routine to use to destroy user data
9632790b72bSJeremy L Thompson 
9642790b72bSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
9652790b72bSJeremy L Thompson 
9662790b72bSJeremy L Thompson   @ref User
9672790b72bSJeremy L Thompson **/
9682b730f8bSJeremy L Thompson int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) {
9696e536b99SJeremy L Thompson   CeedCheck(f, CeedQFunctionContextReturnCeed(ctx), 1, "Must provide valid callback function for destroying user data");
9702790b72bSJeremy L Thompson   ctx->data_destroy_mem_type = f_mem_type;
9712790b72bSJeremy L Thompson   ctx->data_destroy_function = f;
9722790b72bSJeremy L Thompson   return CEED_ERROR_SUCCESS;
9732790b72bSJeremy L Thompson }
9742790b72bSJeremy L Thompson 
9752790b72bSJeremy L Thompson /**
976ca94c3ddSJeremy L Thompson   @brief Destroy a `CeedQFunctionContext`
977777ff853SJeremy L Thompson 
978ca94c3ddSJeremy L Thompson   @param[in,out] ctx `CeedQFunctionContext` to destroy
979777ff853SJeremy L Thompson 
980777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
981777ff853SJeremy L Thompson 
982777ff853SJeremy L Thompson   @ref User
983777ff853SJeremy L Thompson **/
984777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) {
985b0f67a9cSJeremy L Thompson   if (!*ctx || CeedObjectDereference((CeedObject)*ctx) > 0) {
986ad6481ceSJeremy L Thompson     *ctx = NULL;
987ad6481ceSJeremy L Thompson     return CEED_ERROR_SUCCESS;
988ad6481ceSJeremy L Thompson   }
989b0f67a9cSJeremy L Thompson   CeedCheck(((*ctx)->state % 2) == 0, CeedQFunctionContextReturnCeed(*ctx), 1, "Cannot destroy CeedQFunctionContext, the access lock is in use");
990777ff853SJeremy L Thompson 
9912b730f8bSJeremy L Thompson   CeedCall(CeedQFunctionContextDestroyData(*ctx));
9922b730f8bSJeremy L Thompson   if ((*ctx)->Destroy) CeedCall((*ctx)->Destroy(*ctx));
993cdf32b93SJeremy L Thompson   for (CeedInt i = 0; i < (*ctx)->num_fields; i++) {
9942b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]->name));
9952b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]->description));
9962b730f8bSJeremy L Thompson     CeedCall(CeedFree(&(*ctx)->field_labels[i]));
997cdf32b93SJeremy L Thompson   }
9982b730f8bSJeremy L Thompson   CeedCall(CeedFree(&(*ctx)->field_labels));
999b0f67a9cSJeremy L Thompson   CeedCall(CeedObjectDestroy(&(*ctx)->obj));
10002b730f8bSJeremy L Thompson   CeedCall(CeedFree(ctx));
1001e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1002777ff853SJeremy L Thompson }
1003777ff853SJeremy L Thompson 
1004777ff853SJeremy L Thompson /// @}
1005