xref: /libCEED/interface/ceed-qfunctioncontext.c (revision 0f86cbe7e90c9366c73a141bde379916ec0231bc)
1777ff853SJeremy L Thompson // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2777ff853SJeremy L Thompson // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3777ff853SJeremy L Thompson // reserved. See files LICENSE and NOTICE for details.
4777ff853SJeremy L Thompson //
5777ff853SJeremy L Thompson // This file is part of CEED, a collection of benchmarks, miniapps, software
6777ff853SJeremy L Thompson // libraries and APIs for efficient high-order finite element and spectral
7777ff853SJeremy L Thompson // element discretizations for exascale applications. For more information and
8777ff853SJeremy L Thompson // source code availability see http://github.com/ceed.
9777ff853SJeremy L Thompson //
10777ff853SJeremy L Thompson // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11777ff853SJeremy L Thompson // a collaborative effort of two U.S. Department of Energy organizations (Office
12777ff853SJeremy L Thompson // of Science and the National Nuclear Security Administration) responsible for
13777ff853SJeremy L Thompson // the planning and preparation of a capable exascale ecosystem, including
14777ff853SJeremy L Thompson // software, applications, hardware, advanced system engineering and early
15777ff853SJeremy L Thompson // testbed platforms, in support of the nation's exascale computing imperative.
16777ff853SJeremy L Thompson 
17ec3da8bcSJed Brown #include <ceed/ceed.h>
18ec3da8bcSJed Brown #include <ceed/backend.h>
193d576824SJeremy L Thompson #include <ceed-impl.h>
203d576824SJeremy L Thompson #include <stdint.h>
213d576824SJeremy L Thompson #include <stdio.h>
22cdf32b93SJeremy L Thompson #include <string.h>
23777ff853SJeremy L Thompson 
24777ff853SJeremy L Thompson /// @file
25777ff853SJeremy L Thompson /// Implementation of public CeedQFunctionContext interfaces
26777ff853SJeremy L Thompson 
27777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
28cdf32b93SJeremy L Thompson /// CeedQFunctionContext Library Internal Functions
29cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
30cdf32b93SJeremy L Thompson /// @addtogroup CeedQFunctionDeveloper
31cdf32b93SJeremy L Thompson /// @{
32cdf32b93SJeremy L Thompson 
33cdf32b93SJeremy L Thompson /**
34cdf32b93SJeremy L Thompson   @brief Get index for QFunctionContext field
35cdf32b93SJeremy L Thompson 
36cdf32b93SJeremy L Thompson   @param ctx         CeedQFunctionContext
37cdf32b93SJeremy L Thompson   @param field_name  Name of field
38cdf32b93SJeremy L Thompson   @param field_index Index of field, or -1 if field is not registered
39cdf32b93SJeremy L Thompson 
40cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
41cdf32b93SJeremy L Thompson 
42cdf32b93SJeremy L Thompson   @ref Developer
43cdf32b93SJeremy L Thompson **/
44cdf32b93SJeremy L Thompson int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx,
45cdf32b93SJeremy L Thompson                                       const char *field_name, CeedInt *field_index) {
46cdf32b93SJeremy L Thompson   *field_index = -1;
47cdf32b93SJeremy L Thompson   for (CeedInt i=0; i<ctx->num_fields; i++)
483668ca4bSJeremy L Thompson     if (!strcmp(ctx->field_labels[i]->name, field_name))
49cdf32b93SJeremy L Thompson       *field_index = i;
50cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
51cdf32b93SJeremy L Thompson }
52cdf32b93SJeremy L Thompson 
53cdf32b93SJeremy L Thompson /**
54cdf32b93SJeremy L Thompson   @brief Common function for registering QFunctionContext fields
55cdf32b93SJeremy L Thompson 
56cdf32b93SJeremy L Thompson   @param ctx               CeedQFunctionContext
57cdf32b93SJeremy L Thompson   @param field_name        Name of field to register
58cdf32b93SJeremy L Thompson   @param field_offset      Offset of field to register
59cdf32b93SJeremy L Thompson   @param field_description Description of field, or NULL for none
60cdf32b93SJeremy L Thompson   @param field_type        Field data type, such as double or int32
61cdf32b93SJeremy L Thompson   @param field_size        Size of field, in bytes
62cdf32b93SJeremy L Thompson 
63cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
64cdf32b93SJeremy L Thompson 
65cdf32b93SJeremy L Thompson   @ref Developer
66cdf32b93SJeremy L Thompson **/
67cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx,
68cdf32b93SJeremy L Thompson                                         const char *field_name, size_t field_offset,
69cdf32b93SJeremy L Thompson                                         const char *field_description,
70cdf32b93SJeremy L Thompson                                         CeedContextFieldType field_type,
71cdf32b93SJeremy L Thompson                                         size_t field_size) {
72cdf32b93SJeremy L Thompson   int ierr;
73cdf32b93SJeremy L Thompson 
74cdf32b93SJeremy L Thompson   // Check for duplicate
75cdf32b93SJeremy L Thompson   CeedInt field_index = -1;
76cdf32b93SJeremy L Thompson   ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index);
77cdf32b93SJeremy L Thompson   CeedChk(ierr);
78cdf32b93SJeremy L Thompson   if (field_index != -1)
79cdf32b93SJeremy L Thompson     // LCOV_EXCL_START
80cdf32b93SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
81cdf32b93SJeremy L Thompson                      "QFunctionContext field with name \"%s\" already registered",
82cdf32b93SJeremy L Thompson                      field_name);
83cdf32b93SJeremy L Thompson   // LCOV_EXCL_STOP
84cdf32b93SJeremy L Thompson 
85cdf32b93SJeremy L Thompson   // Allocate space for field data
86cdf32b93SJeremy L Thompson   if (ctx->num_fields == 0) {
873668ca4bSJeremy L Thompson     ierr = CeedCalloc(1, &ctx->field_labels); CeedChk(ierr);
88cdf32b93SJeremy L Thompson     ctx->max_fields = 1;
89cdf32b93SJeremy L Thompson   } else if (ctx->num_fields == ctx->max_fields) {
903668ca4bSJeremy L Thompson     ierr = CeedRealloc(2*ctx->max_fields, &ctx->field_labels);
91cdf32b93SJeremy L Thompson     CeedChk(ierr);
92cdf32b93SJeremy L Thompson     ctx->max_fields *= 2;
93cdf32b93SJeremy L Thompson   }
943668ca4bSJeremy L Thompson   ierr = CeedCalloc(1, &ctx->field_labels[ctx->num_fields]); CeedChk(ierr);
95cdf32b93SJeremy L Thompson 
96cdf32b93SJeremy L Thompson   // Copy field data
97f7e22acaSJeremy L Thompson   ierr = CeedStringAllocCopy(field_name,
983668ca4bSJeremy L Thompson                              (char **)&ctx->field_labels[ctx->num_fields]->name);
99f7e22acaSJeremy L Thompson   CeedChk(ierr);
100f7e22acaSJeremy L Thompson   ierr = CeedStringAllocCopy(field_description,
1013668ca4bSJeremy L Thompson                              (char **)&ctx->field_labels[ctx->num_fields]->description);
102f7e22acaSJeremy L Thompson   CeedChk(ierr);
1033668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->type = field_type;
1043668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->offset = field_offset;
1053668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->size = field_size;
106cdf32b93SJeremy L Thompson   ctx->num_fields++;
107cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
108cdf32b93SJeremy L Thompson }
109cdf32b93SJeremy L Thompson 
110cdf32b93SJeremy L Thompson /// @}
111cdf32b93SJeremy L Thompson 
112cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
113777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API
114777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
115777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend
116777ff853SJeremy L Thompson /// @{
117777ff853SJeremy L Thompson 
118777ff853SJeremy L Thompson /**
119777ff853SJeremy L Thompson   @brief Get the Ceed associated with a CeedQFunctionContext
120777ff853SJeremy L Thompson 
121777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
122777ff853SJeremy L Thompson   @param[out] ceed  Variable to store Ceed
123777ff853SJeremy L Thompson 
124777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
125777ff853SJeremy L Thompson 
126777ff853SJeremy L Thompson   @ref Backend
127777ff853SJeremy L Thompson **/
128777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) {
129777ff853SJeremy L Thompson   *ceed = ctx->ceed;
130e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
131777ff853SJeremy L Thompson }
132777ff853SJeremy L Thompson 
133777ff853SJeremy L Thompson /**
1349c774eddSJeremy L Thompson   @brief Check for valid data in a CeedQFunctionContext
1359c774eddSJeremy L Thompson 
1369c774eddSJeremy L Thompson   @param ctx                  CeedQFunctionContext to check validity
1379c774eddSJeremy L Thompson   @param[out] has_valid_data  Variable to store validity
1389c774eddSJeremy L Thompson 
1399c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1409c774eddSJeremy L Thompson 
1419c774eddSJeremy L Thompson   @ref Backend
1429c774eddSJeremy L Thompson **/
1439c774eddSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx,
1449c774eddSJeremy L Thompson                                      bool *has_valid_data) {
1459c774eddSJeremy L Thompson   int ierr;
1469c774eddSJeremy L Thompson 
1479c774eddSJeremy L Thompson   if (!ctx->HasValidData)
1489c774eddSJeremy L Thompson     // LCOV_EXCL_START
1499c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
1509c774eddSJeremy L Thompson                      "Backend does not support HasValidData");
1519c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
1529c774eddSJeremy L Thompson 
1539c774eddSJeremy L Thompson   ierr = ctx->HasValidData(ctx, has_valid_data); CeedChk(ierr);
1549c774eddSJeremy L Thompson 
1559c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1569c774eddSJeremy L Thompson }
1579c774eddSJeremy L Thompson 
1589c774eddSJeremy L Thompson /**
1599c774eddSJeremy L Thompson   @brief Check for borrowed data of a specific CeedMemType in a
1609c774eddSJeremy L Thompson            CeedQFunctionContext
1619c774eddSJeremy L Thompson 
1629c774eddSJeremy L Thompson   @param ctx                             CeedQFunctionContext to check
1639c774eddSJeremy L Thompson   @param mem_type                        Memory type to check
1649c774eddSJeremy L Thompson   @param[out] has_borrowed_data_of_type  Variable to store result
1659c774eddSJeremy L Thompson 
1669c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1679c774eddSJeremy L Thompson 
1689c774eddSJeremy L Thompson   @ref Backend
1699c774eddSJeremy L Thompson **/
1709c774eddSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx,
1719c774eddSJeremy L Thompson     CeedMemType mem_type, bool *has_borrowed_data_of_type) {
1729c774eddSJeremy L Thompson   int ierr;
1739c774eddSJeremy L Thompson 
1749c774eddSJeremy L Thompson   if (!ctx->HasBorrowedDataOfType)
1759c774eddSJeremy L Thompson     // LCOV_EXCL_START
1769c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
1779c774eddSJeremy L Thompson                      "Backend does not support HasBorrowedDataOfType");
1789c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
1799c774eddSJeremy L Thompson 
1809c774eddSJeremy L Thompson   ierr = ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type);
1819c774eddSJeremy L Thompson   CeedChk(ierr);
1829c774eddSJeremy L Thompson 
1839c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1849c774eddSJeremy L Thompson }
1859c774eddSJeremy L Thompson 
1869c774eddSJeremy L Thompson /**
187777ff853SJeremy L Thompson   @brief Get the state of a CeedQFunctionContext
188777ff853SJeremy L Thompson 
189777ff853SJeremy L Thompson   @param ctx         CeedQFunctionContext to retrieve state
190777ff853SJeremy L Thompson   @param[out] state  Variable to store state
191777ff853SJeremy L Thompson 
192777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
193777ff853SJeremy L Thompson 
194777ff853SJeremy L Thompson   @ref Backend
195777ff853SJeremy L Thompson **/
196777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) {
197777ff853SJeremy L Thompson   *state = ctx->state;
198e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
199777ff853SJeremy L Thompson }
200777ff853SJeremy L Thompson 
201777ff853SJeremy L Thompson /**
202777ff853SJeremy L Thompson   @brief Get backend data of a CeedQFunctionContext
203777ff853SJeremy L Thompson 
204777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
205777ff853SJeremy L Thompson   @param[out] data  Variable to store data
206777ff853SJeremy L Thompson 
207777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
208777ff853SJeremy L Thompson 
209777ff853SJeremy L Thompson   @ref Backend
210777ff853SJeremy L Thompson **/
211777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) {
212777ff853SJeremy L Thompson   *(void **)data = ctx->data;
213e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
214777ff853SJeremy L Thompson }
215777ff853SJeremy L Thompson 
216777ff853SJeremy L Thompson /**
217777ff853SJeremy L Thompson   @brief Set backend data of a CeedQFunctionContext
218777ff853SJeremy L Thompson 
219777ff853SJeremy L Thompson   @param[out] ctx  CeedQFunctionContext
220777ff853SJeremy L Thompson   @param data      Data to set
221777ff853SJeremy L Thompson 
222777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
223777ff853SJeremy L Thompson 
224777ff853SJeremy L Thompson   @ref Backend
225777ff853SJeremy L Thompson **/
226777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) {
227777ff853SJeremy L Thompson   ctx->data = data;
228e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
229777ff853SJeremy L Thompson }
230777ff853SJeremy L Thompson 
23134359f16Sjeremylt /**
232d8dd9a91SJeremy L Thompson   @brief Set QFunctionContext field
233d8dd9a91SJeremy L Thompson 
234d8dd9a91SJeremy L Thompson   @param ctx         CeedQFunctionContext
2353668ca4bSJeremy L Thompson   @param field_label Label of field to set
236d8dd9a91SJeremy L Thompson   @param field_type  Type of field to set
237d8dd9a91SJeremy L Thompson   @param value       Value to set
238d8dd9a91SJeremy L Thompson 
239d8dd9a91SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
240d8dd9a91SJeremy L Thompson 
241d8dd9a91SJeremy L Thompson   @ref User
242d8dd9a91SJeremy L Thompson **/
243d8dd9a91SJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx,
2443668ca4bSJeremy L Thompson                                    CeedContextFieldLabel field_label,
245d8dd9a91SJeremy L Thompson                                    CeedContextFieldType field_type,
2463668ca4bSJeremy L Thompson                                    void *value) {
247d8dd9a91SJeremy L Thompson   int ierr;
248d8dd9a91SJeremy L Thompson 
2493668ca4bSJeremy L Thompson   // Check field type
2503668ca4bSJeremy L Thompson   if (field_label->type != field_type)
251d8dd9a91SJeremy L Thompson     // LCOV_EXCL_START
252d8dd9a91SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
253d8dd9a91SJeremy L Thompson                      "QFunctionContext field with name \"%s\" registered as %s, "
2543668ca4bSJeremy L Thompson                      "not registered as %s", field_label->name,
2553668ca4bSJeremy L Thompson                      CeedContextFieldTypes[field_label->type],
256d8dd9a91SJeremy L Thompson                      CeedContextFieldTypes[field_type]);
257d8dd9a91SJeremy L Thompson   // LCOV_EXCL_STOP
258d8dd9a91SJeremy L Thompson 
259d8dd9a91SJeremy L Thompson   char *data;
260d8dd9a91SJeremy L Thompson   ierr = CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data); CeedChk(ierr);
2613668ca4bSJeremy L Thompson   memcpy(&data[field_label->offset], value, field_label->size);
262d8dd9a91SJeremy L Thompson   ierr = CeedQFunctionContextRestoreData(ctx, &data); CeedChk(ierr);
263d8dd9a91SJeremy L Thompson 
264d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
265d8dd9a91SJeremy L Thompson }
266d8dd9a91SJeremy L Thompson 
267d8dd9a91SJeremy L Thompson /**
26834359f16Sjeremylt   @brief Increment the reference counter for a CeedQFunctionContext
26934359f16Sjeremylt 
27034359f16Sjeremylt   @param ctx  CeedQFunctionContext to increment the reference counter
27134359f16Sjeremylt 
27234359f16Sjeremylt   @return An error code: 0 - success, otherwise - failure
27334359f16Sjeremylt 
27434359f16Sjeremylt   @ref Backend
27534359f16Sjeremylt **/
2769560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) {
27734359f16Sjeremylt   ctx->ref_count++;
27834359f16Sjeremylt   return CEED_ERROR_SUCCESS;
27934359f16Sjeremylt }
28034359f16Sjeremylt 
281777ff853SJeremy L Thompson /// @}
282777ff853SJeremy L Thompson 
283777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
284777ff853SJeremy L Thompson /// CeedQFunctionContext Public API
285777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
286777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser
287777ff853SJeremy L Thompson /// @{
288777ff853SJeremy L Thompson 
289777ff853SJeremy L Thompson /**
290777ff853SJeremy L Thompson   @brief Create a CeedQFunctionContext for storing CeedQFunction user context data
291777ff853SJeremy L Thompson 
292777ff853SJeremy L Thompson   @param ceed      A Ceed object where the CeedQFunctionContext will be created
293777ff853SJeremy L Thompson   @param[out] ctx  Address of the variable where the newly created
294777ff853SJeremy L Thompson                      CeedQFunctionContext will be stored
295777ff853SJeremy L Thompson 
296777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
297777ff853SJeremy L Thompson 
298777ff853SJeremy L Thompson   @ref User
299777ff853SJeremy L Thompson **/
300777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) {
301777ff853SJeremy L Thompson   int ierr;
302777ff853SJeremy L Thompson 
303777ff853SJeremy L Thompson   if (!ceed->QFunctionContextCreate) {
304777ff853SJeremy L Thompson     Ceed delegate;
305777ff853SJeremy L Thompson     ierr = CeedGetObjectDelegate(ceed, &delegate, "Context"); CeedChk(ierr);
306777ff853SJeremy L Thompson 
307777ff853SJeremy L Thompson     if (!delegate)
308777ff853SJeremy L Thompson       // LCOV_EXCL_START
309e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
310e15f9bd0SJeremy L Thompson                        "Backend does not support ContextCreate");
311777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
312777ff853SJeremy L Thompson 
313777ff853SJeremy L Thompson     ierr = CeedQFunctionContextCreate(delegate, ctx); CeedChk(ierr);
314e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
315777ff853SJeremy L Thompson   }
316777ff853SJeremy L Thompson 
317777ff853SJeremy L Thompson   ierr = CeedCalloc(1, ctx); CeedChk(ierr);
318777ff853SJeremy L Thompson   (*ctx)->ceed = ceed;
3199560d06aSjeremylt   ierr = CeedReference(ceed); CeedChk(ierr);
320d1d35e2fSjeremylt   (*ctx)->ref_count = 1;
321777ff853SJeremy L Thompson   ierr = ceed->QFunctionContextCreate(*ctx); CeedChk(ierr);
322e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
323777ff853SJeremy L Thompson }
324777ff853SJeremy L Thompson 
325777ff853SJeremy L Thompson /**
3269560d06aSjeremylt   @brief Copy the pointer to a CeedQFunctionContext. Both pointers should
3279560d06aSjeremylt            be destroyed with `CeedQFunctionContextDestroy()`;
3289560d06aSjeremylt            Note: If `*ctx_copy` is non-NULL, then it is assumed that
3299560d06aSjeremylt            `*ctx_copy` is a pointer to a CeedQFunctionContext. This
3309560d06aSjeremylt            CeedQFunctionContext will be destroyed if `*ctx_copy` is the
3319560d06aSjeremylt            only reference to this CeedQFunctionContext.
3329560d06aSjeremylt 
3339560d06aSjeremylt   @param ctx            CeedQFunctionContext to copy reference to
3349560d06aSjeremylt   @param[out] ctx_copy  Variable to store copied reference
3359560d06aSjeremylt 
3369560d06aSjeremylt   @return An error code: 0 - success, otherwise - failure
3379560d06aSjeremylt 
3389560d06aSjeremylt   @ref User
3399560d06aSjeremylt **/
3409560d06aSjeremylt int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx,
3419560d06aSjeremylt                                       CeedQFunctionContext *ctx_copy) {
3429560d06aSjeremylt   int ierr;
3439560d06aSjeremylt 
3449560d06aSjeremylt   ierr = CeedQFunctionContextReference(ctx); CeedChk(ierr);
3459560d06aSjeremylt   ierr = CeedQFunctionContextDestroy(ctx_copy); CeedChk(ierr);
3469560d06aSjeremylt   *ctx_copy = ctx;
3479560d06aSjeremylt   return CEED_ERROR_SUCCESS;
3489560d06aSjeremylt }
3499560d06aSjeremylt 
3509560d06aSjeremylt /**
351777ff853SJeremy L Thompson   @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated
352777ff853SJeremy L Thompson            data if applicable. The backend may copy values to a different
353777ff853SJeremy L Thompson            memtype, such as during @ref CeedQFunctionApply().
354777ff853SJeremy L Thompson            See also @ref CeedQFunctionContextTakeData().
355777ff853SJeremy L Thompson 
356777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
357d1d35e2fSjeremylt   @param mem_type   Memory type of the data being passed
358d1d35e2fSjeremylt   @param copy_mode  Copy mode for the data
359891038deSjeremylt   @param size       Size of data, in bytes
360777ff853SJeremy L Thompson   @param data       Data to be used
361777ff853SJeremy L Thompson 
362777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
363777ff853SJeremy L Thompson 
364777ff853SJeremy L Thompson   @ref User
365777ff853SJeremy L Thompson **/
366d1d35e2fSjeremylt int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type,
367d1d35e2fSjeremylt                                 CeedCopyMode copy_mode,
368777ff853SJeremy L Thompson                                 size_t size, void *data) {
369777ff853SJeremy L Thompson   int ierr;
370777ff853SJeremy L Thompson 
371777ff853SJeremy L Thompson   if (!ctx->SetData)
372777ff853SJeremy L Thompson     // LCOV_EXCL_START
373e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
374e15f9bd0SJeremy L Thompson                      "Backend does not support ContextSetData");
375777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
376777ff853SJeremy L Thompson 
377777ff853SJeremy L Thompson   if (ctx->state % 2 == 1)
378777ff853SJeremy L Thompson     // LCOV_EXCL_START
379777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
380777ff853SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
381777ff853SJeremy L Thompson                      "access lock is already in use");
382777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
383777ff853SJeremy L Thompson 
384d1d35e2fSjeremylt   ctx->ctx_size = size;
385d1d35e2fSjeremylt   ierr = ctx->SetData(ctx, mem_type, copy_mode, data); CeedChk(ierr);
386777ff853SJeremy L Thompson   ctx->state += 2;
387e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
388777ff853SJeremy L Thompson }
389777ff853SJeremy L Thompson 
390777ff853SJeremy L Thompson /**
391891038deSjeremylt   @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type.
392891038deSjeremylt            The caller is responsible for managing and freeing the memory.
393891038deSjeremylt 
394891038deSjeremylt   @param ctx        CeedQFunctionContext to access
395891038deSjeremylt   @param mem_type   Memory type on which to access the data. If the backend
396891038deSjeremylt                       uses a different memory type, this will perform a copy.
397891038deSjeremylt   @param[out] data  Data on memory type mem_type
398891038deSjeremylt 
399891038deSjeremylt   @return An error code: 0 - success, otherwise - failure
400891038deSjeremylt 
401891038deSjeremylt   @ref User
402891038deSjeremylt **/
403891038deSjeremylt int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type,
404891038deSjeremylt                                  void *data) {
405891038deSjeremylt   int ierr;
406891038deSjeremylt 
4079c774eddSJeremy L Thompson   bool has_valid_data = true;
4089c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr);
4099c774eddSJeremy L Thompson   if (!has_valid_data)
4109c774eddSJeremy L Thompson     // LCOV_EXCL_START
4119c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
4129c774eddSJeremy L Thompson                      "CeedQFunctionContext has no valid data to take, must set data");
4139c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
4149c774eddSJeremy L Thompson 
415891038deSjeremylt   if (!ctx->TakeData)
416891038deSjeremylt     // LCOV_EXCL_START
417891038deSjeremylt     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
418891038deSjeremylt                      "Backend does not support TakeData");
419891038deSjeremylt   // LCOV_EXCL_STOP
420891038deSjeremylt 
421891038deSjeremylt   if (ctx->state % 2 == 1)
422891038deSjeremylt     // LCOV_EXCL_START
423891038deSjeremylt     return CeedError(ctx->ceed, 1,
424891038deSjeremylt                      "Cannot grant CeedQFunctionContext data access, the "
425891038deSjeremylt                      "access lock is already in use");
426891038deSjeremylt   // LCOV_EXCL_STOP
427891038deSjeremylt 
4289c774eddSJeremy L Thompson   bool has_borrowed_data_of_type = true;
4299c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type,
4309c774eddSJeremy L Thompson          &has_borrowed_data_of_type); CeedChk(ierr);
4319c774eddSJeremy L Thompson   if (!has_borrowed_data_of_type)
4329c774eddSJeremy L Thompson     // LCOV_EXCL_START
4339c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
4349c774eddSJeremy L Thompson                      "CeedQFunctionContext has no borowed %s data, "
4359c774eddSJeremy L Thompson                      "must set data with CeedQFunctionContextSetData",
4369c774eddSJeremy L Thompson                      CeedMemTypes[mem_type]);
4379c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
4389c774eddSJeremy L Thompson 
439891038deSjeremylt   void *temp_data = NULL;
440891038deSjeremylt   ierr = ctx->TakeData(ctx, mem_type, &temp_data); CeedChk(ierr);
441891038deSjeremylt   if (data) (*(void **)data) = temp_data;
442891038deSjeremylt   return CEED_ERROR_SUCCESS;
443891038deSjeremylt }
444891038deSjeremylt 
445891038deSjeremylt /**
446777ff853SJeremy L Thompson   @brief Get read/write access to a CeedQFunctionContext via the specified memory type.
447777ff853SJeremy L Thompson            Restore access with @ref CeedQFunctionContextRestoreData().
448777ff853SJeremy L Thompson 
449777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext to access
450d1d35e2fSjeremylt   @param mem_type   Memory type on which to access the data. If the backend
451777ff853SJeremy L Thompson                       uses a different memory type, this will perform a copy.
452d1d35e2fSjeremylt   @param[out] data  Data on memory type mem_type
453777ff853SJeremy L Thompson 
454777ff853SJeremy L Thompson   @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions
455777ff853SJeremy L Thompson     provide access to array pointers in the desired memory space. Pairing
456777ff853SJeremy L Thompson     get/restore allows the Context to track access.
457777ff853SJeremy L Thompson 
458777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
459777ff853SJeremy L Thompson 
460777ff853SJeremy L Thompson   @ref User
461777ff853SJeremy L Thompson **/
462d1d35e2fSjeremylt int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type,
463777ff853SJeremy L Thompson                                 void *data) {
464777ff853SJeremy L Thompson   int ierr;
465777ff853SJeremy L Thompson 
466777ff853SJeremy L Thompson   if (!ctx->GetData)
467777ff853SJeremy L Thompson     // LCOV_EXCL_START
468e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
469e15f9bd0SJeremy L Thompson                      "Backend does not support GetData");
470777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
471777ff853SJeremy L Thompson 
472777ff853SJeremy L Thompson   if (ctx->state % 2 == 1)
473777ff853SJeremy L Thompson     // LCOV_EXCL_START
474777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
475777ff853SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
476777ff853SJeremy L Thompson                      "access lock is already in use");
477777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
478777ff853SJeremy L Thompson 
4799c774eddSJeremy L Thompson   bool has_valid_data = true;
4809c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr);
4819c774eddSJeremy L Thompson   if (!has_valid_data)
4829c774eddSJeremy L Thompson     // LCOV_EXCL_START
4839c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
4849c774eddSJeremy L Thompson                      "CeedQFunctionContext has no valid data to get, must set data");
4859c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
4869c774eddSJeremy L Thompson 
487d1d35e2fSjeremylt   ierr = ctx->GetData(ctx, mem_type, data); CeedChk(ierr);
488777ff853SJeremy L Thompson   ctx->state += 1;
489e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
490777ff853SJeremy L Thompson }
491777ff853SJeremy L Thompson 
492777ff853SJeremy L Thompson /**
493777ff853SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetData()
494777ff853SJeremy L Thompson 
495777ff853SJeremy L Thompson   @param ctx   CeedQFunctionContext to restore
496777ff853SJeremy L Thompson   @param data  Data to restore
497777ff853SJeremy L Thompson 
498777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
499777ff853SJeremy L Thompson 
500777ff853SJeremy L Thompson   @ref User
501777ff853SJeremy L Thompson **/
502777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) {
503777ff853SJeremy L Thompson   int ierr;
504777ff853SJeremy L Thompson 
505777ff853SJeremy L Thompson   if (ctx->state % 2 != 1)
506777ff853SJeremy L Thompson     // LCOV_EXCL_START
507777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
508777ff853SJeremy L Thompson                      "Cannot restore CeedQFunctionContext array access, "
509777ff853SJeremy L Thompson                      "access was not granted");
510777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
511777ff853SJeremy L Thompson 
512706efda3SJeremy L Thompson   if (ctx->RestoreData) {
513777ff853SJeremy L Thompson     ierr = ctx->RestoreData(ctx); CeedChk(ierr);
514706efda3SJeremy L Thompson   }
515777ff853SJeremy L Thompson   *(void **)data = NULL;
516777ff853SJeremy L Thompson   ctx->state += 1;
517e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
518777ff853SJeremy L Thompson }
519777ff853SJeremy L Thompson 
520777ff853SJeremy L Thompson /**
521cdf32b93SJeremy L Thompson   @brief Register QFunctionContext a field holding a double precision value
522cdf32b93SJeremy L Thompson 
523cdf32b93SJeremy L Thompson   @param ctx               CeedQFunctionContext
524cdf32b93SJeremy L Thompson   @param field_name        Name of field to register
525cdf32b93SJeremy L Thompson   @param field_offset      Offset of field to register
526cdf32b93SJeremy L Thompson   @param field_description Description of field, or NULL for none
527cdf32b93SJeremy L Thompson 
528cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
529cdf32b93SJeremy L Thompson 
530cdf32b93SJeremy L Thompson   @ref User
531cdf32b93SJeremy L Thompson **/
532cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx,
533cdf32b93SJeremy L Thompson                                        const char *field_name, size_t field_offset,
534cdf32b93SJeremy L Thompson                                        const char *field_description) {
535cdf32b93SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset,
536cdf32b93SJeremy L Thompson          field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double));
537cdf32b93SJeremy L Thompson }
538cdf32b93SJeremy L Thompson 
539cdf32b93SJeremy L Thompson /**
540cdf32b93SJeremy L Thompson   @brief Register QFunctionContext a field holding a int32 value
541cdf32b93SJeremy L Thompson 
542cdf32b93SJeremy L Thompson   @param ctx               CeedQFunctionContext
543cdf32b93SJeremy L Thompson   @param field_name        Name of field to register
544cdf32b93SJeremy L Thompson   @param field_offset      Offset of field to register
545cdf32b93SJeremy L Thompson   @param field_description Description of field, or NULL for none
546cdf32b93SJeremy L Thompson 
547cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
548cdf32b93SJeremy L Thompson 
549cdf32b93SJeremy L Thompson   @ref User
550cdf32b93SJeremy L Thompson **/
551cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx,
552cdf32b93SJeremy L Thompson                                       const char *field_name, size_t field_offset,
553cdf32b93SJeremy L Thompson                                       const char *field_description) {
554cdf32b93SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset,
555cdf32b93SJeremy L Thompson          field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int));
556cdf32b93SJeremy L Thompson }
557cdf32b93SJeremy L Thompson 
558cdf32b93SJeremy L Thompson /**
5593668ca4bSJeremy L Thompson   @brief Get labels for all registered QFunctionContext fields
560cdf32b93SJeremy L Thompson 
561cdf32b93SJeremy L Thompson   @param ctx                CeedQFunctionContext
5623668ca4bSJeremy L Thompson   @param[out] field_labels  Variable to hold array of field labels
563cdf32b93SJeremy L Thompson   @param[out] num_fields    Length of field descriptions array
564cdf32b93SJeremy L Thompson 
565cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
566cdf32b93SJeremy L Thompson 
567cdf32b93SJeremy L Thompson   @ref User
568cdf32b93SJeremy L Thompson **/
5693668ca4bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx,
5703668ca4bSJeremy L Thompson     const CeedContextFieldLabel **field_labels, CeedInt *num_fields) {
5713668ca4bSJeremy L Thompson   *field_labels = ctx->field_labels;
572cdf32b93SJeremy L Thompson   *num_fields = ctx->num_fields;
573cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
574cdf32b93SJeremy L Thompson }
575cdf32b93SJeremy L Thompson 
576cdf32b93SJeremy L Thompson /**
5773668ca4bSJeremy L Thompson   @brief Get label for a registered QFunctionContext field, or `NULL` if no
5783668ca4bSJeremy L Thompson            field has been registered with this `field_name`
5793668ca4bSJeremy L Thompson 
5803668ca4bSJeremy L Thompson   @param[in] ctx           CeedQFunctionContext
5813668ca4bSJeremy L Thompson   @param[in] field_name    Name of field to retrieve label
5823668ca4bSJeremy L Thompson   @param[out] field_label  Variable to field label
5833668ca4bSJeremy L Thompson 
5843668ca4bSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
5853668ca4bSJeremy L Thompson 
5863668ca4bSJeremy L Thompson   @ref User
5873668ca4bSJeremy L Thompson **/
5883668ca4bSJeremy L Thompson int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx,
5893668ca4bSJeremy L Thompson                                       const char *field_name, CeedContextFieldLabel *field_label) {
5903668ca4bSJeremy L Thompson   int ierr;
5913668ca4bSJeremy L Thompson 
5923668ca4bSJeremy L Thompson   CeedInt field_index;
5933668ca4bSJeremy L Thompson   ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index);
5943668ca4bSJeremy L Thompson   CeedChk(ierr);
5953668ca4bSJeremy L Thompson 
5963668ca4bSJeremy L Thompson   if (field_index != -1) {
5973668ca4bSJeremy L Thompson     *field_label = ctx->field_labels[field_index];
5983668ca4bSJeremy L Thompson   } else {
5993668ca4bSJeremy L Thompson     *field_label = NULL;
6003668ca4bSJeremy L Thompson   }
6013668ca4bSJeremy L Thompson 
6023668ca4bSJeremy L Thompson   return CEED_ERROR_SUCCESS;
6033668ca4bSJeremy L Thompson }
6043668ca4bSJeremy L Thompson 
6053668ca4bSJeremy L Thompson /**
606*0f86cbe7SJeremy L Thompson   @brief Get the descriptive information about a CeedContextFieldLabel
607*0f86cbe7SJeremy L Thompson 
608*0f86cbe7SJeremy L Thompson   @param[in] label              CeedContextFieldLabel
609*0f86cbe7SJeremy L Thompson   @param[out] field_name        Name of labeled field
610*0f86cbe7SJeremy L Thompson   @param[out] field_description Description of field, or NULL for none
611*0f86cbe7SJeremy L Thompson   @param[out] field_type        CeedContextFieldType
612*0f86cbe7SJeremy L Thompson 
613*0f86cbe7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
614*0f86cbe7SJeremy L Thompson 
615*0f86cbe7SJeremy L Thompson   @ref User
616*0f86cbe7SJeremy L Thompson **/
617*0f86cbe7SJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label,
618*0f86cbe7SJeremy L Thompson                                         const char **field_name,
619*0f86cbe7SJeremy L Thompson                                         const char **field_description,
620*0f86cbe7SJeremy L Thompson                                         CeedContextFieldType *field_type) {
621*0f86cbe7SJeremy L Thompson   if (field_name) *field_name = label->name;
622*0f86cbe7SJeremy L Thompson   if (field_description) *field_description = label->description;
623*0f86cbe7SJeremy L Thompson   if (field_type) *field_type = label->type;
624*0f86cbe7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
625*0f86cbe7SJeremy L Thompson }
626*0f86cbe7SJeremy L Thompson 
627*0f86cbe7SJeremy L Thompson /**
628cdf32b93SJeremy L Thompson   @brief Set QFunctionContext field holding a double precision value
629cdf32b93SJeremy L Thompson 
630cdf32b93SJeremy L Thompson   @param ctx         CeedQFunctionContext
6313668ca4bSJeremy L Thompson   @param field_label Label for field to register
632cdf32b93SJeremy L Thompson   @param value       Value to set
633cdf32b93SJeremy L Thompson 
634cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
635cdf32b93SJeremy L Thompson 
636cdf32b93SJeremy L Thompson   @ref User
637cdf32b93SJeremy L Thompson **/
638cdf32b93SJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx,
6393668ca4bSJeremy L Thompson                                   CeedContextFieldLabel field_label, double value) {
640d8dd9a91SJeremy L Thompson   int ierr;
641d8dd9a91SJeremy L Thompson 
6423668ca4bSJeremy L Thompson   if (!field_label)
643d8dd9a91SJeremy L Thompson     // LCOV_EXCL_START
644d8dd9a91SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
6453668ca4bSJeremy L Thompson                      "Invalid field label");
646d8dd9a91SJeremy L Thompson   // LCOV_EXCL_STOP
647d8dd9a91SJeremy L Thompson 
6483668ca4bSJeremy L Thompson   ierr = CeedQFunctionContextSetGeneric(ctx, field_label,
6493668ca4bSJeremy L Thompson                                         CEED_CONTEXT_FIELD_DOUBLE,
6503668ca4bSJeremy L Thompson                                         &value); CeedChk(ierr);
6513668ca4bSJeremy L Thompson 
652d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
653cdf32b93SJeremy L Thompson }
654cdf32b93SJeremy L Thompson 
655cdf32b93SJeremy L Thompson /**
656d8dd9a91SJeremy L Thompson   @brief Set QFunctionContext field holding an int32 value
657cdf32b93SJeremy L Thompson 
658cdf32b93SJeremy L Thompson   @param ctx         CeedQFunctionContext
6593668ca4bSJeremy L Thompson   @param field_label Label for field to register
660cdf32b93SJeremy L Thompson   @param value       Value to set
661cdf32b93SJeremy L Thompson 
662cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
663cdf32b93SJeremy L Thompson 
664cdf32b93SJeremy L Thompson   @ref User
665cdf32b93SJeremy L Thompson **/
666cdf32b93SJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx,
6673668ca4bSJeremy L Thompson                                  CeedContextFieldLabel field_label, int value) {
668d8dd9a91SJeremy L Thompson   int ierr;
669d8dd9a91SJeremy L Thompson 
6703668ca4bSJeremy L Thompson   if (!field_label)
671d8dd9a91SJeremy L Thompson     // LCOV_EXCL_START
672d8dd9a91SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
6733668ca4bSJeremy L Thompson                      "Invalid field label");
674d8dd9a91SJeremy L Thompson   // LCOV_EXCL_STOP
675d8dd9a91SJeremy L Thompson 
6763668ca4bSJeremy L Thompson   ierr = CeedQFunctionContextSetGeneric(ctx, field_label,
6773668ca4bSJeremy L Thompson                                         CEED_CONTEXT_FIELD_INT32,
6783668ca4bSJeremy L Thompson                                         &value); CeedChk(ierr);
6793668ca4bSJeremy L Thompson 
680d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
681cdf32b93SJeremy L Thompson }
682cdf32b93SJeremy L Thompson 
683cdf32b93SJeremy L Thompson /**
68480a9ef05SNatalie Beams   @brief Get data size for a Context
68580a9ef05SNatalie Beams 
68680a9ef05SNatalie Beams   @param ctx            CeedQFunctionContext
68780a9ef05SNatalie Beams   @param[out] ctx_size  Variable to store size of context data values
68880a9ef05SNatalie Beams 
68980a9ef05SNatalie Beams   @return An error code: 0 - success, otherwise - failure
69080a9ef05SNatalie Beams 
69180a9ef05SNatalie Beams   @ref User
69280a9ef05SNatalie Beams **/
69380a9ef05SNatalie Beams int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx,
69480a9ef05SNatalie Beams                                        size_t *ctx_size) {
69580a9ef05SNatalie Beams   *ctx_size = ctx->ctx_size;
69680a9ef05SNatalie Beams   return CEED_ERROR_SUCCESS;
69780a9ef05SNatalie Beams }
69880a9ef05SNatalie Beams 
69980a9ef05SNatalie Beams 
70080a9ef05SNatalie Beams /**
701777ff853SJeremy L Thompson   @brief View a CeedQFunctionContext
702777ff853SJeremy L Thompson 
703777ff853SJeremy L Thompson   @param[in] ctx     CeedQFunctionContext to view
704777ff853SJeremy L Thompson   @param[in] stream  Filestream to write to
705777ff853SJeremy L Thompson 
706777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
707777ff853SJeremy L Thompson 
708777ff853SJeremy L Thompson   @ref User
709777ff853SJeremy L Thompson **/
710777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) {
711777ff853SJeremy L Thompson   fprintf(stream, "CeedQFunctionContext\n");
712d1d35e2fSjeremylt   fprintf(stream, "  Context Data Size: %ld\n", ctx->ctx_size);
7133668ca4bSJeremy L Thompson   for (CeedInt i = 0; i < ctx->num_fields; i++) {
7143668ca4bSJeremy L Thompson     // LCOV_EXCL_START
7153668ca4bSJeremy L Thompson     fprintf(stream, "  Labeled %s field: %s\n",
7163668ca4bSJeremy L Thompson             CeedContextFieldTypes[ctx->field_labels[i]->type],
7173668ca4bSJeremy L Thompson             ctx->field_labels[i]->name);
7183668ca4bSJeremy L Thompson     // LCOV_EXCL_STOP
7193668ca4bSJeremy L Thompson   }
720e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
721777ff853SJeremy L Thompson }
722777ff853SJeremy L Thompson 
723777ff853SJeremy L Thompson /**
724777ff853SJeremy L Thompson   @brief Destroy a CeedQFunctionContext
725777ff853SJeremy L Thompson 
726777ff853SJeremy L Thompson   @param ctx  CeedQFunctionContext to destroy
727777ff853SJeremy L Thompson 
728777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
729777ff853SJeremy L Thompson 
730777ff853SJeremy L Thompson   @ref User
731777ff853SJeremy L Thompson **/
732777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) {
733777ff853SJeremy L Thompson   int ierr;
734777ff853SJeremy L Thompson 
735d1d35e2fSjeremylt   if (!*ctx || --(*ctx)->ref_count > 0)
736e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
737777ff853SJeremy L Thompson 
738777ff853SJeremy L Thompson   if ((*ctx) && ((*ctx)->state % 2) == 1)
739777ff853SJeremy L Thompson     // LCOV_EXCL_START
740777ff853SJeremy L Thompson     return CeedError((*ctx)->ceed, 1,
741777ff853SJeremy L Thompson                      "Cannot destroy CeedQFunctionContext, the access "
742777ff853SJeremy L Thompson                      "lock is in use");
743777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
744777ff853SJeremy L Thompson 
745777ff853SJeremy L Thompson   if ((*ctx)->Destroy) {
746777ff853SJeremy L Thompson     ierr = (*ctx)->Destroy(*ctx); CeedChk(ierr);
747777ff853SJeremy L Thompson   }
748cdf32b93SJeremy L Thompson   for (CeedInt i=0; i<(*ctx)->num_fields; i++) {
7493668ca4bSJeremy L Thompson     ierr = CeedFree(&(*ctx)->field_labels[i]->name); CeedChk(ierr);
7503668ca4bSJeremy L Thompson     ierr = CeedFree(&(*ctx)->field_labels[i]->description); CeedChk(ierr);
7513668ca4bSJeremy L Thompson     ierr = CeedFree(&(*ctx)->field_labels[i]); CeedChk(ierr);
752cdf32b93SJeremy L Thompson   }
7533668ca4bSJeremy L Thompson   ierr = CeedFree(&(*ctx)->field_labels); CeedChk(ierr);
754777ff853SJeremy L Thompson   ierr = CeedDestroy(&(*ctx)->ceed); CeedChk(ierr);
755777ff853SJeremy L Thompson   ierr = CeedFree(ctx); CeedChk(ierr);
756cdf32b93SJeremy L Thompson 
757e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
758777ff853SJeremy L Thompson }
759777ff853SJeremy L Thompson 
760777ff853SJeremy L Thompson /// @}
761