xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-qfunctioncontext.c (revision d8dd9a912dc9d585dc5c0667639a4157f4b711a3)
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++)
48cdf32b93SJeremy L Thompson     if (!strcmp(ctx->field_descriptions[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) {
87cdf32b93SJeremy L Thompson     ierr = CeedCalloc(1, &ctx->field_descriptions); CeedChk(ierr);
88cdf32b93SJeremy L Thompson     ctx->max_fields = 1;
89cdf32b93SJeremy L Thompson   } else if (ctx->num_fields == ctx->max_fields) {
90cdf32b93SJeremy L Thompson     ierr = CeedRealloc(2*ctx->max_fields, &ctx->field_descriptions);
91cdf32b93SJeremy L Thompson     CeedChk(ierr);
92cdf32b93SJeremy L Thompson     ctx->max_fields *= 2;
93cdf32b93SJeremy L Thompson   }
94cdf32b93SJeremy L Thompson 
95cdf32b93SJeremy L Thompson   // Copy field data
96f7e22acaSJeremy L Thompson   ierr = CeedStringAllocCopy(field_name,
97f7e22acaSJeremy L Thompson                              (char **)&ctx->field_descriptions[ctx->num_fields].name);
98f7e22acaSJeremy L Thompson   CeedChk(ierr);
99f7e22acaSJeremy L Thompson   ierr = CeedStringAllocCopy(field_description,
100f7e22acaSJeremy L Thompson                              (char **)&ctx->field_descriptions[ctx->num_fields].description);
101f7e22acaSJeremy L Thompson   CeedChk(ierr);
102cdf32b93SJeremy L Thompson   ctx->field_descriptions[ctx->num_fields].type = field_type;
103cdf32b93SJeremy L Thompson   ctx->field_descriptions[ctx->num_fields].offset = field_offset;
104cdf32b93SJeremy L Thompson   ctx->field_descriptions[ctx->num_fields].size = field_size;
105cdf32b93SJeremy L Thompson   ctx->num_fields++;
106cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
107cdf32b93SJeremy L Thompson }
108cdf32b93SJeremy L Thompson 
109cdf32b93SJeremy L Thompson /// @}
110cdf32b93SJeremy L Thompson 
111cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
112777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API
113777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
114777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend
115777ff853SJeremy L Thompson /// @{
116777ff853SJeremy L Thompson 
117777ff853SJeremy L Thompson /**
118777ff853SJeremy L Thompson   @brief Get the Ceed associated with a CeedQFunctionContext
119777ff853SJeremy L Thompson 
120777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
121777ff853SJeremy L Thompson   @param[out] ceed  Variable to store Ceed
122777ff853SJeremy L Thompson 
123777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
124777ff853SJeremy L Thompson 
125777ff853SJeremy L Thompson   @ref Backend
126777ff853SJeremy L Thompson **/
127777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) {
128777ff853SJeremy L Thompson   *ceed = ctx->ceed;
129e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
130777ff853SJeremy L Thompson }
131777ff853SJeremy L Thompson 
132777ff853SJeremy L Thompson /**
1339c774eddSJeremy L Thompson   @brief Check for valid data in a CeedQFunctionContext
1349c774eddSJeremy L Thompson 
1359c774eddSJeremy L Thompson   @param ctx                  CeedQFunctionContext to check validity
1369c774eddSJeremy L Thompson   @param[out] has_valid_data  Variable to store validity
1379c774eddSJeremy L Thompson 
1389c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1399c774eddSJeremy L Thompson 
1409c774eddSJeremy L Thompson   @ref Backend
1419c774eddSJeremy L Thompson **/
1429c774eddSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx,
1439c774eddSJeremy L Thompson                                      bool *has_valid_data) {
1449c774eddSJeremy L Thompson   int ierr;
1459c774eddSJeremy L Thompson 
1469c774eddSJeremy L Thompson   if (!ctx->HasValidData)
1479c774eddSJeremy L Thompson     // LCOV_EXCL_START
1489c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
1499c774eddSJeremy L Thompson                      "Backend does not support HasValidData");
1509c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
1519c774eddSJeremy L Thompson 
1529c774eddSJeremy L Thompson   ierr = ctx->HasValidData(ctx, has_valid_data); CeedChk(ierr);
1539c774eddSJeremy L Thompson 
1549c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1559c774eddSJeremy L Thompson }
1569c774eddSJeremy L Thompson 
1579c774eddSJeremy L Thompson /**
1589c774eddSJeremy L Thompson   @brief Check for borrowed data of a specific CeedMemType in a
1599c774eddSJeremy L Thompson            CeedQFunctionContext
1609c774eddSJeremy L Thompson 
1619c774eddSJeremy L Thompson   @param ctx                             CeedQFunctionContext to check
1629c774eddSJeremy L Thompson   @param mem_type                        Memory type to check
1639c774eddSJeremy L Thompson   @param[out] has_borrowed_data_of_type  Variable to store result
1649c774eddSJeremy L Thompson 
1659c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1669c774eddSJeremy L Thompson 
1679c774eddSJeremy L Thompson   @ref Backend
1689c774eddSJeremy L Thompson **/
1699c774eddSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx,
1709c774eddSJeremy L Thompson     CeedMemType mem_type, bool *has_borrowed_data_of_type) {
1719c774eddSJeremy L Thompson   int ierr;
1729c774eddSJeremy L Thompson 
1739c774eddSJeremy L Thompson   if (!ctx->HasBorrowedDataOfType)
1749c774eddSJeremy L Thompson     // LCOV_EXCL_START
1759c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
1769c774eddSJeremy L Thompson                      "Backend does not support HasBorrowedDataOfType");
1779c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
1789c774eddSJeremy L Thompson 
1799c774eddSJeremy L Thompson   ierr = ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type);
1809c774eddSJeremy L Thompson   CeedChk(ierr);
1819c774eddSJeremy L Thompson 
1829c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1839c774eddSJeremy L Thompson }
1849c774eddSJeremy L Thompson 
1859c774eddSJeremy L Thompson /**
186777ff853SJeremy L Thompson   @brief Get the state of a CeedQFunctionContext
187777ff853SJeremy L Thompson 
188777ff853SJeremy L Thompson   @param ctx         CeedQFunctionContext to retrieve state
189777ff853SJeremy L Thompson   @param[out] state  Variable to store state
190777ff853SJeremy L Thompson 
191777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
192777ff853SJeremy L Thompson 
193777ff853SJeremy L Thompson   @ref Backend
194777ff853SJeremy L Thompson **/
195777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) {
196777ff853SJeremy L Thompson   *state = ctx->state;
197e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
198777ff853SJeremy L Thompson }
199777ff853SJeremy L Thompson 
200777ff853SJeremy L Thompson /**
201777ff853SJeremy L Thompson   @brief Get backend data of a CeedQFunctionContext
202777ff853SJeremy L Thompson 
203777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
204777ff853SJeremy L Thompson   @param[out] data  Variable to store data
205777ff853SJeremy L Thompson 
206777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
207777ff853SJeremy L Thompson 
208777ff853SJeremy L Thompson   @ref Backend
209777ff853SJeremy L Thompson **/
210777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) {
211777ff853SJeremy L Thompson   *(void **)data = ctx->data;
212e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
213777ff853SJeremy L Thompson }
214777ff853SJeremy L Thompson 
215777ff853SJeremy L Thompson /**
216777ff853SJeremy L Thompson   @brief Set backend data of a CeedQFunctionContext
217777ff853SJeremy L Thompson 
218777ff853SJeremy L Thompson   @param[out] ctx  CeedQFunctionContext
219777ff853SJeremy L Thompson   @param data      Data to set
220777ff853SJeremy L Thompson 
221777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
222777ff853SJeremy L Thompson 
223777ff853SJeremy L Thompson   @ref Backend
224777ff853SJeremy L Thompson **/
225777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) {
226777ff853SJeremy L Thompson   ctx->data = data;
227e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
228777ff853SJeremy L Thompson }
229777ff853SJeremy L Thompson 
23034359f16Sjeremylt /**
231*d8dd9a91SJeremy L Thompson   @brief Set QFunctionContext field
232*d8dd9a91SJeremy L Thompson 
233*d8dd9a91SJeremy L Thompson   @param ctx        CeedQFunctionContext
234*d8dd9a91SJeremy L Thompson   @param field_name Name of field to set
235*d8dd9a91SJeremy L Thompson   @param field_type Type of field to set
236*d8dd9a91SJeremy L Thompson   @param is_set     Boolean flag if value was set
237*d8dd9a91SJeremy L Thompson   @param value      Value to set
238*d8dd9a91SJeremy L Thompson 
239*d8dd9a91SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
240*d8dd9a91SJeremy L Thompson 
241*d8dd9a91SJeremy L Thompson   @ref User
242*d8dd9a91SJeremy L Thompson **/
243*d8dd9a91SJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx,
244*d8dd9a91SJeremy L Thompson                                    const char *field_name,
245*d8dd9a91SJeremy L Thompson                                    CeedContextFieldType field_type,
246*d8dd9a91SJeremy L Thompson                                    bool *is_set, void *value) {
247*d8dd9a91SJeremy L Thompson   int ierr;
248*d8dd9a91SJeremy L Thompson 
249*d8dd9a91SJeremy L Thompson   // Check field index
250*d8dd9a91SJeremy L Thompson   *is_set = false;
251*d8dd9a91SJeremy L Thompson   CeedInt field_index = -1;
252*d8dd9a91SJeremy L Thompson   ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index);
253*d8dd9a91SJeremy L Thompson   CeedChk(ierr);
254*d8dd9a91SJeremy L Thompson   if (field_index == -1)
255*d8dd9a91SJeremy L Thompson     return CEED_ERROR_SUCCESS;
256*d8dd9a91SJeremy L Thompson 
257*d8dd9a91SJeremy L Thompson   if (ctx->field_descriptions[field_index].type != field_type)
258*d8dd9a91SJeremy L Thompson     // LCOV_EXCL_START
259*d8dd9a91SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
260*d8dd9a91SJeremy L Thompson                      "QFunctionContext field with name \"%s\" registered as %s, "
261*d8dd9a91SJeremy L Thompson                      "not registered as %s", field_name,
262*d8dd9a91SJeremy L Thompson                      CeedContextFieldTypes[ctx->field_descriptions[field_index].type],
263*d8dd9a91SJeremy L Thompson                      CeedContextFieldTypes[field_type]);
264*d8dd9a91SJeremy L Thompson   // LCOV_EXCL_STOP
265*d8dd9a91SJeremy L Thompson 
266*d8dd9a91SJeremy L Thompson   char *data;
267*d8dd9a91SJeremy L Thompson   ierr = CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data); CeedChk(ierr);
268*d8dd9a91SJeremy L Thompson   memcpy(&data[ctx->field_descriptions[field_index].offset], value,
269*d8dd9a91SJeremy L Thompson          ctx->field_descriptions[field_index].size);
270*d8dd9a91SJeremy L Thompson   ierr = CeedQFunctionContextRestoreData(ctx, &data); CeedChk(ierr);
271*d8dd9a91SJeremy L Thompson   *is_set = true;
272*d8dd9a91SJeremy L Thompson 
273*d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
274*d8dd9a91SJeremy L Thompson }
275*d8dd9a91SJeremy L Thompson 
276*d8dd9a91SJeremy L Thompson /**
27734359f16Sjeremylt   @brief Increment the reference counter for a CeedQFunctionContext
27834359f16Sjeremylt 
27934359f16Sjeremylt   @param ctx  CeedQFunctionContext to increment the reference counter
28034359f16Sjeremylt 
28134359f16Sjeremylt   @return An error code: 0 - success, otherwise - failure
28234359f16Sjeremylt 
28334359f16Sjeremylt   @ref Backend
28434359f16Sjeremylt **/
2859560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) {
28634359f16Sjeremylt   ctx->ref_count++;
28734359f16Sjeremylt   return CEED_ERROR_SUCCESS;
28834359f16Sjeremylt }
28934359f16Sjeremylt 
290777ff853SJeremy L Thompson /// @}
291777ff853SJeremy L Thompson 
292777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
293777ff853SJeremy L Thompson /// CeedQFunctionContext Public API
294777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
295777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser
296777ff853SJeremy L Thompson /// @{
297777ff853SJeremy L Thompson 
298777ff853SJeremy L Thompson /**
299777ff853SJeremy L Thompson   @brief Create a CeedQFunctionContext for storing CeedQFunction user context data
300777ff853SJeremy L Thompson 
301777ff853SJeremy L Thompson   @param ceed      A Ceed object where the CeedQFunctionContext will be created
302777ff853SJeremy L Thompson   @param[out] ctx  Address of the variable where the newly created
303777ff853SJeremy L Thompson                      CeedQFunctionContext will be stored
304777ff853SJeremy L Thompson 
305777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
306777ff853SJeremy L Thompson 
307777ff853SJeremy L Thompson   @ref User
308777ff853SJeremy L Thompson **/
309777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) {
310777ff853SJeremy L Thompson   int ierr;
311777ff853SJeremy L Thompson 
312777ff853SJeremy L Thompson   if (!ceed->QFunctionContextCreate) {
313777ff853SJeremy L Thompson     Ceed delegate;
314777ff853SJeremy L Thompson     ierr = CeedGetObjectDelegate(ceed, &delegate, "Context"); CeedChk(ierr);
315777ff853SJeremy L Thompson 
316777ff853SJeremy L Thompson     if (!delegate)
317777ff853SJeremy L Thompson       // LCOV_EXCL_START
318e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
319e15f9bd0SJeremy L Thompson                        "Backend does not support ContextCreate");
320777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
321777ff853SJeremy L Thompson 
322777ff853SJeremy L Thompson     ierr = CeedQFunctionContextCreate(delegate, ctx); CeedChk(ierr);
323e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
324777ff853SJeremy L Thompson   }
325777ff853SJeremy L Thompson 
326777ff853SJeremy L Thompson   ierr = CeedCalloc(1, ctx); CeedChk(ierr);
327777ff853SJeremy L Thompson   (*ctx)->ceed = ceed;
3289560d06aSjeremylt   ierr = CeedReference(ceed); CeedChk(ierr);
329d1d35e2fSjeremylt   (*ctx)->ref_count = 1;
330777ff853SJeremy L Thompson   ierr = ceed->QFunctionContextCreate(*ctx); CeedChk(ierr);
331e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
332777ff853SJeremy L Thompson }
333777ff853SJeremy L Thompson 
334777ff853SJeremy L Thompson /**
3359560d06aSjeremylt   @brief Copy the pointer to a CeedQFunctionContext. Both pointers should
3369560d06aSjeremylt            be destroyed with `CeedQFunctionContextDestroy()`;
3379560d06aSjeremylt            Note: If `*ctx_copy` is non-NULL, then it is assumed that
3389560d06aSjeremylt            `*ctx_copy` is a pointer to a CeedQFunctionContext. This
3399560d06aSjeremylt            CeedQFunctionContext will be destroyed if `*ctx_copy` is the
3409560d06aSjeremylt            only reference to this CeedQFunctionContext.
3419560d06aSjeremylt 
3429560d06aSjeremylt   @param ctx            CeedQFunctionContext to copy reference to
3439560d06aSjeremylt   @param[out] ctx_copy  Variable to store copied reference
3449560d06aSjeremylt 
3459560d06aSjeremylt   @return An error code: 0 - success, otherwise - failure
3469560d06aSjeremylt 
3479560d06aSjeremylt   @ref User
3489560d06aSjeremylt **/
3499560d06aSjeremylt int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx,
3509560d06aSjeremylt                                       CeedQFunctionContext *ctx_copy) {
3519560d06aSjeremylt   int ierr;
3529560d06aSjeremylt 
3539560d06aSjeremylt   ierr = CeedQFunctionContextReference(ctx); CeedChk(ierr);
3549560d06aSjeremylt   ierr = CeedQFunctionContextDestroy(ctx_copy); CeedChk(ierr);
3559560d06aSjeremylt   *ctx_copy = ctx;
3569560d06aSjeremylt   return CEED_ERROR_SUCCESS;
3579560d06aSjeremylt }
3589560d06aSjeremylt 
3599560d06aSjeremylt /**
360777ff853SJeremy L Thompson   @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated
361777ff853SJeremy L Thompson            data if applicable. The backend may copy values to a different
362777ff853SJeremy L Thompson            memtype, such as during @ref CeedQFunctionApply().
363777ff853SJeremy L Thompson            See also @ref CeedQFunctionContextTakeData().
364777ff853SJeremy L Thompson 
365777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
366d1d35e2fSjeremylt   @param mem_type   Memory type of the data being passed
367d1d35e2fSjeremylt   @param copy_mode  Copy mode for the data
368891038deSjeremylt   @param size       Size of data, in bytes
369777ff853SJeremy L Thompson   @param data       Data to be used
370777ff853SJeremy L Thompson 
371777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
372777ff853SJeremy L Thompson 
373777ff853SJeremy L Thompson   @ref User
374777ff853SJeremy L Thompson **/
375d1d35e2fSjeremylt int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type,
376d1d35e2fSjeremylt                                 CeedCopyMode copy_mode,
377777ff853SJeremy L Thompson                                 size_t size, void *data) {
378777ff853SJeremy L Thompson   int ierr;
379777ff853SJeremy L Thompson 
380777ff853SJeremy L Thompson   if (!ctx->SetData)
381777ff853SJeremy L Thompson     // LCOV_EXCL_START
382e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
383e15f9bd0SJeremy L Thompson                      "Backend does not support ContextSetData");
384777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
385777ff853SJeremy L Thompson 
386777ff853SJeremy L Thompson   if (ctx->state % 2 == 1)
387777ff853SJeremy L Thompson     // LCOV_EXCL_START
388777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
389777ff853SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
390777ff853SJeremy L Thompson                      "access lock is already in use");
391777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
392777ff853SJeremy L Thompson 
393d1d35e2fSjeremylt   ctx->ctx_size = size;
394d1d35e2fSjeremylt   ierr = ctx->SetData(ctx, mem_type, copy_mode, data); CeedChk(ierr);
395777ff853SJeremy L Thompson   ctx->state += 2;
396e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
397777ff853SJeremy L Thompson }
398777ff853SJeremy L Thompson 
399777ff853SJeremy L Thompson /**
400891038deSjeremylt   @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type.
401891038deSjeremylt            The caller is responsible for managing and freeing the memory.
402891038deSjeremylt 
403891038deSjeremylt   @param ctx        CeedQFunctionContext to access
404891038deSjeremylt   @param mem_type   Memory type on which to access the data. If the backend
405891038deSjeremylt                       uses a different memory type, this will perform a copy.
406891038deSjeremylt   @param[out] data  Data on memory type mem_type
407891038deSjeremylt 
408891038deSjeremylt   @return An error code: 0 - success, otherwise - failure
409891038deSjeremylt 
410891038deSjeremylt   @ref User
411891038deSjeremylt **/
412891038deSjeremylt int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type,
413891038deSjeremylt                                  void *data) {
414891038deSjeremylt   int ierr;
415891038deSjeremylt 
4169c774eddSJeremy L Thompson   bool has_valid_data = true;
4179c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr);
4189c774eddSJeremy L Thompson   if (!has_valid_data)
4199c774eddSJeremy L Thompson     // LCOV_EXCL_START
4209c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
4219c774eddSJeremy L Thompson                      "CeedQFunctionContext has no valid data to take, must set data");
4229c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
4239c774eddSJeremy L Thompson 
424891038deSjeremylt   if (!ctx->TakeData)
425891038deSjeremylt     // LCOV_EXCL_START
426891038deSjeremylt     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
427891038deSjeremylt                      "Backend does not support TakeData");
428891038deSjeremylt   // LCOV_EXCL_STOP
429891038deSjeremylt 
430891038deSjeremylt   if (ctx->state % 2 == 1)
431891038deSjeremylt     // LCOV_EXCL_START
432891038deSjeremylt     return CeedError(ctx->ceed, 1,
433891038deSjeremylt                      "Cannot grant CeedQFunctionContext data access, the "
434891038deSjeremylt                      "access lock is already in use");
435891038deSjeremylt   // LCOV_EXCL_STOP
436891038deSjeremylt 
4379c774eddSJeremy L Thompson   bool has_borrowed_data_of_type = true;
4389c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type,
4399c774eddSJeremy L Thompson          &has_borrowed_data_of_type); CeedChk(ierr);
4409c774eddSJeremy L Thompson   if (!has_borrowed_data_of_type)
4419c774eddSJeremy L Thompson     // LCOV_EXCL_START
4429c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
4439c774eddSJeremy L Thompson                      "CeedQFunctionContext has no borowed %s data, "
4449c774eddSJeremy L Thompson                      "must set data with CeedQFunctionContextSetData",
4459c774eddSJeremy L Thompson                      CeedMemTypes[mem_type]);
4469c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
4479c774eddSJeremy L Thompson 
448891038deSjeremylt   void *temp_data = NULL;
449891038deSjeremylt   ierr = ctx->TakeData(ctx, mem_type, &temp_data); CeedChk(ierr);
450891038deSjeremylt   if (data) (*(void **)data) = temp_data;
451891038deSjeremylt   return CEED_ERROR_SUCCESS;
452891038deSjeremylt }
453891038deSjeremylt 
454891038deSjeremylt /**
455777ff853SJeremy L Thompson   @brief Get read/write access to a CeedQFunctionContext via the specified memory type.
456777ff853SJeremy L Thompson            Restore access with @ref CeedQFunctionContextRestoreData().
457777ff853SJeremy L Thompson 
458777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext to access
459d1d35e2fSjeremylt   @param mem_type   Memory type on which to access the data. If the backend
460777ff853SJeremy L Thompson                       uses a different memory type, this will perform a copy.
461d1d35e2fSjeremylt   @param[out] data  Data on memory type mem_type
462777ff853SJeremy L Thompson 
463777ff853SJeremy L Thompson   @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions
464777ff853SJeremy L Thompson     provide access to array pointers in the desired memory space. Pairing
465777ff853SJeremy L Thompson     get/restore allows the Context to track access.
466777ff853SJeremy L Thompson 
467777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
468777ff853SJeremy L Thompson 
469777ff853SJeremy L Thompson   @ref User
470777ff853SJeremy L Thompson **/
471d1d35e2fSjeremylt int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type,
472777ff853SJeremy L Thompson                                 void *data) {
473777ff853SJeremy L Thompson   int ierr;
474777ff853SJeremy L Thompson 
475777ff853SJeremy L Thompson   if (!ctx->GetData)
476777ff853SJeremy L Thompson     // LCOV_EXCL_START
477e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
478e15f9bd0SJeremy L Thompson                      "Backend does not support GetData");
479777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
480777ff853SJeremy L Thompson 
481777ff853SJeremy L Thompson   if (ctx->state % 2 == 1)
482777ff853SJeremy L Thompson     // LCOV_EXCL_START
483777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
484777ff853SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
485777ff853SJeremy L Thompson                      "access lock is already in use");
486777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
487777ff853SJeremy L Thompson 
4889c774eddSJeremy L Thompson   bool has_valid_data = true;
4899c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr);
4909c774eddSJeremy L Thompson   if (!has_valid_data)
4919c774eddSJeremy L Thompson     // LCOV_EXCL_START
4929c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
4939c774eddSJeremy L Thompson                      "CeedQFunctionContext has no valid data to get, must set data");
4949c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
4959c774eddSJeremy L Thompson 
496d1d35e2fSjeremylt   ierr = ctx->GetData(ctx, mem_type, data); CeedChk(ierr);
497777ff853SJeremy L Thompson   ctx->state += 1;
498e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
499777ff853SJeremy L Thompson }
500777ff853SJeremy L Thompson 
501777ff853SJeremy L Thompson /**
502777ff853SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetData()
503777ff853SJeremy L Thompson 
504777ff853SJeremy L Thompson   @param ctx   CeedQFunctionContext to restore
505777ff853SJeremy L Thompson   @param data  Data to restore
506777ff853SJeremy L Thompson 
507777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
508777ff853SJeremy L Thompson 
509777ff853SJeremy L Thompson   @ref User
510777ff853SJeremy L Thompson **/
511777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) {
512777ff853SJeremy L Thompson   int ierr;
513777ff853SJeremy L Thompson 
514777ff853SJeremy L Thompson   if (!ctx->RestoreData)
515777ff853SJeremy L Thompson     // LCOV_EXCL_START
516e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
517e15f9bd0SJeremy L Thompson                      "Backend does not support RestoreData");
518777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
519777ff853SJeremy L Thompson 
520777ff853SJeremy L Thompson   if (ctx->state % 2 != 1)
521777ff853SJeremy L Thompson     // LCOV_EXCL_START
522777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
523777ff853SJeremy L Thompson                      "Cannot restore CeedQFunctionContext array access, "
524777ff853SJeremy L Thompson                      "access was not granted");
525777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
526777ff853SJeremy L Thompson 
527777ff853SJeremy L Thompson   ierr = ctx->RestoreData(ctx); CeedChk(ierr);
528777ff853SJeremy L Thompson   *(void **)data = NULL;
529777ff853SJeremy L Thompson   ctx->state += 1;
530e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
531777ff853SJeremy L Thompson }
532777ff853SJeremy L Thompson 
533777ff853SJeremy L Thompson /**
534cdf32b93SJeremy L Thompson   @brief Register QFunctionContext a field holding a double precision value
535cdf32b93SJeremy L Thompson 
536cdf32b93SJeremy L Thompson   @param ctx               CeedQFunctionContext
537cdf32b93SJeremy L Thompson   @param field_name        Name of field to register
538cdf32b93SJeremy L Thompson   @param field_offset      Offset of field to register
539cdf32b93SJeremy L Thompson   @param field_description Description of field, or NULL for none
540cdf32b93SJeremy L Thompson 
541cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
542cdf32b93SJeremy L Thompson 
543cdf32b93SJeremy L Thompson   @ref User
544cdf32b93SJeremy L Thompson **/
545cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx,
546cdf32b93SJeremy L Thompson                                        const char *field_name, size_t field_offset,
547cdf32b93SJeremy L Thompson                                        const char *field_description) {
548cdf32b93SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset,
549cdf32b93SJeremy L Thompson          field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double));
550cdf32b93SJeremy L Thompson }
551cdf32b93SJeremy L Thompson 
552cdf32b93SJeremy L Thompson /**
553cdf32b93SJeremy L Thompson   @brief Register QFunctionContext a field holding a int32 value
554cdf32b93SJeremy L Thompson 
555cdf32b93SJeremy L Thompson   @param ctx               CeedQFunctionContext
556cdf32b93SJeremy L Thompson   @param field_name        Name of field to register
557cdf32b93SJeremy L Thompson   @param field_offset      Offset of field to register
558cdf32b93SJeremy L Thompson   @param field_description Description of field, or NULL for none
559cdf32b93SJeremy L Thompson 
560cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
561cdf32b93SJeremy L Thompson 
562cdf32b93SJeremy L Thompson   @ref User
563cdf32b93SJeremy L Thompson **/
564cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx,
565cdf32b93SJeremy L Thompson                                       const char *field_name, size_t field_offset,
566cdf32b93SJeremy L Thompson                                       const char *field_description) {
567cdf32b93SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset,
568cdf32b93SJeremy L Thompson          field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int));
569cdf32b93SJeremy L Thompson }
570cdf32b93SJeremy L Thompson 
571cdf32b93SJeremy L Thompson /**
572cdf32b93SJeremy L Thompson   @brief Get descriptions for registered QFunctionContext fields
573cdf32b93SJeremy L Thompson 
574cdf32b93SJeremy L Thompson   @param ctx                     CeedQFunctionContext
575cdf32b93SJeremy L Thompson   @param[out] field_descriptions Variable to hold array of field descriptions
576cdf32b93SJeremy L Thompson   @param[out] num_fields         Length of field descriptions array
577cdf32b93SJeremy L Thompson 
578cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
579cdf32b93SJeremy L Thompson 
580cdf32b93SJeremy L Thompson   @ref User
581cdf32b93SJeremy L Thompson **/
582cdf32b93SJeremy L Thompson int CeedQFunctionContextGetFieldDescriptions(CeedQFunctionContext ctx,
583cdf32b93SJeremy L Thompson     const CeedQFunctionContextFieldDescription **field_descriptions,
584cdf32b93SJeremy L Thompson     CeedInt *num_fields) {
585cdf32b93SJeremy L Thompson   *field_descriptions = ctx->field_descriptions;
586cdf32b93SJeremy L Thompson   *num_fields = ctx->num_fields;
587cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
588cdf32b93SJeremy L Thompson }
589cdf32b93SJeremy L Thompson 
590cdf32b93SJeremy L Thompson /**
591cdf32b93SJeremy L Thompson   @brief Set QFunctionContext field holding a double precision value
592cdf32b93SJeremy L Thompson 
593cdf32b93SJeremy L Thompson   @param ctx        CeedQFunctionContext
594cdf32b93SJeremy L Thompson   @param field_name Name of field to register
595cdf32b93SJeremy L Thompson   @param value      Value to set
596cdf32b93SJeremy L Thompson 
597cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
598cdf32b93SJeremy L Thompson 
599cdf32b93SJeremy L Thompson   @ref User
600cdf32b93SJeremy L Thompson **/
601cdf32b93SJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx,
602cdf32b93SJeremy L Thompson                                   const char *field_name, double value) {
603*d8dd9a91SJeremy L Thompson   int ierr;
604*d8dd9a91SJeremy L Thompson   bool is_set = false;
605*d8dd9a91SJeremy L Thompson 
606*d8dd9a91SJeremy L Thompson   ierr = CeedQFunctionContextSetGeneric(ctx, field_name,
607cdf32b93SJeremy L Thompson                                         CEED_CONTEXT_FIELD_DOUBLE,
608*d8dd9a91SJeremy L Thompson                                         &is_set, &value); CeedChk(ierr);
609*d8dd9a91SJeremy L Thompson   if (!is_set)
610*d8dd9a91SJeremy L Thompson     // LCOV_EXCL_START
611*d8dd9a91SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
612*d8dd9a91SJeremy L Thompson                      "QFunctionContext field with name \"%s\" not registered",
613*d8dd9a91SJeremy L Thompson                      field_name);
614*d8dd9a91SJeremy L Thompson   // LCOV_EXCL_STOP
615*d8dd9a91SJeremy L Thompson 
616*d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
617cdf32b93SJeremy L Thompson }
618cdf32b93SJeremy L Thompson 
619cdf32b93SJeremy L Thompson /**
620*d8dd9a91SJeremy L Thompson   @brief Set QFunctionContext field holding an int32 value
621cdf32b93SJeremy L Thompson 
622cdf32b93SJeremy L Thompson   @param ctx        CeedQFunctionContext
623cdf32b93SJeremy L Thompson   @param field_name Name of field to set
624cdf32b93SJeremy L Thompson   @param value      Value to set
625cdf32b93SJeremy L Thompson 
626cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
627cdf32b93SJeremy L Thompson 
628cdf32b93SJeremy L Thompson   @ref User
629cdf32b93SJeremy L Thompson **/
630cdf32b93SJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx,
631cdf32b93SJeremy L Thompson                                  const char *field_name, int value) {
632*d8dd9a91SJeremy L Thompson   int ierr;
633*d8dd9a91SJeremy L Thompson   bool is_set = false;
634*d8dd9a91SJeremy L Thompson 
635*d8dd9a91SJeremy L Thompson   ierr = CeedQFunctionContextSetGeneric(ctx, field_name,
636*d8dd9a91SJeremy L Thompson                                         CEED_CONTEXT_FIELD_INT32,
637*d8dd9a91SJeremy L Thompson                                         &is_set, &value); CeedChk(ierr);
638*d8dd9a91SJeremy L Thompson   if (!is_set)
639*d8dd9a91SJeremy L Thompson     // LCOV_EXCL_START
640*d8dd9a91SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
641*d8dd9a91SJeremy L Thompson                      "QFunctionContext field with name \"%s\" not registered",
642*d8dd9a91SJeremy L Thompson                      field_name);
643*d8dd9a91SJeremy L Thompson   // LCOV_EXCL_STOP
644*d8dd9a91SJeremy L Thompson 
645*d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
646cdf32b93SJeremy L Thompson }
647cdf32b93SJeremy L Thompson 
648cdf32b93SJeremy L Thompson /**
64980a9ef05SNatalie Beams   @brief Get data size for a Context
65080a9ef05SNatalie Beams 
65180a9ef05SNatalie Beams   @param ctx            CeedQFunctionContext
65280a9ef05SNatalie Beams   @param[out] ctx_size  Variable to store size of context data values
65380a9ef05SNatalie Beams 
65480a9ef05SNatalie Beams   @return An error code: 0 - success, otherwise - failure
65580a9ef05SNatalie Beams 
65680a9ef05SNatalie Beams   @ref User
65780a9ef05SNatalie Beams **/
65880a9ef05SNatalie Beams int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx,
65980a9ef05SNatalie Beams                                        size_t *ctx_size) {
66080a9ef05SNatalie Beams   *ctx_size = ctx->ctx_size;
66180a9ef05SNatalie Beams   return CEED_ERROR_SUCCESS;
66280a9ef05SNatalie Beams }
66380a9ef05SNatalie Beams 
66480a9ef05SNatalie Beams 
66580a9ef05SNatalie Beams /**
666777ff853SJeremy L Thompson   @brief View a CeedQFunctionContext
667777ff853SJeremy L Thompson 
668777ff853SJeremy L Thompson   @param[in] ctx     CeedQFunctionContext to view
669777ff853SJeremy L Thompson   @param[in] stream  Filestream to write to
670777ff853SJeremy L Thompson 
671777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
672777ff853SJeremy L Thompson 
673777ff853SJeremy L Thompson   @ref User
674777ff853SJeremy L Thompson **/
675777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) {
676777ff853SJeremy L Thompson   fprintf(stream, "CeedQFunctionContext\n");
677d1d35e2fSjeremylt   fprintf(stream, "  Context Data Size: %ld\n", ctx->ctx_size);
678e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
679777ff853SJeremy L Thompson }
680777ff853SJeremy L Thompson 
681777ff853SJeremy L Thompson /**
682777ff853SJeremy L Thompson   @brief Destroy a CeedQFunctionContext
683777ff853SJeremy L Thompson 
684777ff853SJeremy L Thompson   @param ctx  CeedQFunctionContext to destroy
685777ff853SJeremy L Thompson 
686777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
687777ff853SJeremy L Thompson 
688777ff853SJeremy L Thompson   @ref User
689777ff853SJeremy L Thompson **/
690777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) {
691777ff853SJeremy L Thompson   int ierr;
692777ff853SJeremy L Thompson 
693d1d35e2fSjeremylt   if (!*ctx || --(*ctx)->ref_count > 0)
694e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
695777ff853SJeremy L Thompson 
696777ff853SJeremy L Thompson   if ((*ctx) && ((*ctx)->state % 2) == 1)
697777ff853SJeremy L Thompson     // LCOV_EXCL_START
698777ff853SJeremy L Thompson     return CeedError((*ctx)->ceed, 1,
699777ff853SJeremy L Thompson                      "Cannot destroy CeedQFunctionContext, the access "
700777ff853SJeremy L Thompson                      "lock is in use");
701777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
702777ff853SJeremy L Thompson 
703777ff853SJeremy L Thompson   if ((*ctx)->Destroy) {
704777ff853SJeremy L Thompson     ierr = (*ctx)->Destroy(*ctx); CeedChk(ierr);
705777ff853SJeremy L Thompson   }
706cdf32b93SJeremy L Thompson   for (CeedInt i=0; i<(*ctx)->num_fields; i++) {
707cdf32b93SJeremy L Thompson     ierr = CeedFree(&(*ctx)->field_descriptions[i].name); CeedChk(ierr);
708cdf32b93SJeremy L Thompson     ierr = CeedFree(&(*ctx)->field_descriptions[i].description); CeedChk(ierr);
709cdf32b93SJeremy L Thompson   }
710cdf32b93SJeremy L Thompson   ierr = CeedFree(&(*ctx)->field_descriptions); CeedChk(ierr);
711777ff853SJeremy L Thompson   ierr = CeedDestroy(&(*ctx)->ceed); CeedChk(ierr);
712777ff853SJeremy L Thompson   ierr = CeedFree(ctx); CeedChk(ierr);
713cdf32b93SJeremy L Thompson 
714e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
715777ff853SJeremy L Thompson }
716777ff853SJeremy L Thompson 
717777ff853SJeremy L Thompson /// @}
718