xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-qfunctioncontext.c (revision cdf32b9369b06315737c6f9df3317771bd8e77c7)
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>
22*cdf32b93SJeremy 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 /// ----------------------------------------------------------------------------
28*cdf32b93SJeremy L Thompson /// CeedQFunctionContext Library Internal Functions
29*cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
30*cdf32b93SJeremy L Thompson /// @addtogroup CeedQFunctionDeveloper
31*cdf32b93SJeremy L Thompson /// @{
32*cdf32b93SJeremy L Thompson 
33*cdf32b93SJeremy L Thompson /**
34*cdf32b93SJeremy L Thompson   @brief Get index for QFunctionContext field
35*cdf32b93SJeremy L Thompson 
36*cdf32b93SJeremy L Thompson   @param ctx         CeedQFunctionContext
37*cdf32b93SJeremy L Thompson   @param field_name  Name of field
38*cdf32b93SJeremy L Thompson   @param field_index Index of field, or -1 if field is not registered
39*cdf32b93SJeremy L Thompson 
40*cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
41*cdf32b93SJeremy L Thompson 
42*cdf32b93SJeremy L Thompson   @ref Developer
43*cdf32b93SJeremy L Thompson **/
44*cdf32b93SJeremy L Thompson int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx,
45*cdf32b93SJeremy L Thompson                                       const char *field_name, CeedInt *field_index) {
46*cdf32b93SJeremy L Thompson   *field_index = -1;
47*cdf32b93SJeremy L Thompson   for (CeedInt i=0; i<ctx->num_fields; i++)
48*cdf32b93SJeremy L Thompson     if (!strcmp(ctx->field_descriptions[i].name, field_name))
49*cdf32b93SJeremy L Thompson       *field_index = i;
50*cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
51*cdf32b93SJeremy L Thompson }
52*cdf32b93SJeremy L Thompson 
53*cdf32b93SJeremy L Thompson /**
54*cdf32b93SJeremy L Thompson   @brief Common function for registering QFunctionContext fields
55*cdf32b93SJeremy L Thompson 
56*cdf32b93SJeremy L Thompson   @param ctx               CeedQFunctionContext
57*cdf32b93SJeremy L Thompson   @param field_name        Name of field to register
58*cdf32b93SJeremy L Thompson   @param field_offset      Offset of field to register
59*cdf32b93SJeremy L Thompson   @param field_description Description of field, or NULL for none
60*cdf32b93SJeremy L Thompson   @param field_type        Field data type, such as double or int32
61*cdf32b93SJeremy L Thompson   @param field_size        Size of field, in bytes
62*cdf32b93SJeremy L Thompson 
63*cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
64*cdf32b93SJeremy L Thompson 
65*cdf32b93SJeremy L Thompson   @ref Developer
66*cdf32b93SJeremy L Thompson **/
67*cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx,
68*cdf32b93SJeremy L Thompson                                         const char *field_name, size_t field_offset,
69*cdf32b93SJeremy L Thompson                                         const char *field_description,
70*cdf32b93SJeremy L Thompson                                         CeedContextFieldType field_type,
71*cdf32b93SJeremy L Thompson                                         size_t field_size) {
72*cdf32b93SJeremy L Thompson   int ierr;
73*cdf32b93SJeremy L Thompson 
74*cdf32b93SJeremy L Thompson   // Check for duplicate
75*cdf32b93SJeremy L Thompson   CeedInt field_index = -1;
76*cdf32b93SJeremy L Thompson   ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index);
77*cdf32b93SJeremy L Thompson   CeedChk(ierr);
78*cdf32b93SJeremy L Thompson   if (field_index != -1)
79*cdf32b93SJeremy L Thompson     // LCOV_EXCL_START
80*cdf32b93SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
81*cdf32b93SJeremy L Thompson                      "QFunctionContext field with name \"%s\" already registered",
82*cdf32b93SJeremy L Thompson                      field_name);
83*cdf32b93SJeremy L Thompson   // LCOV_EXCL_STOP
84*cdf32b93SJeremy L Thompson 
85*cdf32b93SJeremy L Thompson   // Allocate space for field data
86*cdf32b93SJeremy L Thompson   if (ctx->num_fields == 0) {
87*cdf32b93SJeremy L Thompson     ierr = CeedCalloc(1, &ctx->field_descriptions); CeedChk(ierr);
88*cdf32b93SJeremy L Thompson     ctx->max_fields = 1;
89*cdf32b93SJeremy L Thompson   } else if (ctx->num_fields == ctx->max_fields) {
90*cdf32b93SJeremy L Thompson     ierr = CeedRealloc(2*ctx->max_fields, &ctx->field_descriptions);
91*cdf32b93SJeremy L Thompson     CeedChk(ierr);
92*cdf32b93SJeremy L Thompson     ctx->max_fields *= 2;
93*cdf32b93SJeremy L Thompson   }
94*cdf32b93SJeremy L Thompson 
95*cdf32b93SJeremy L Thompson   // Copy field data
96*cdf32b93SJeremy L Thompson   {
97*cdf32b93SJeremy L Thompson     size_t len = strlen(field_name);
98*cdf32b93SJeremy L Thompson     char *tmp;
99*cdf32b93SJeremy L Thompson     ierr = CeedCalloc(len + 1, &tmp); CeedChk(ierr);
100*cdf32b93SJeremy L Thompson     memcpy(tmp, field_name, len+1);
101*cdf32b93SJeremy L Thompson     ctx->field_descriptions[ctx->num_fields].name = tmp;
102*cdf32b93SJeremy L Thompson   }
103*cdf32b93SJeremy L Thompson   {
104*cdf32b93SJeremy L Thompson     size_t len = strlen(field_description);
105*cdf32b93SJeremy L Thompson     char *tmp;
106*cdf32b93SJeremy L Thompson     ierr = CeedCalloc(len + 1, &tmp); CeedChk(ierr);
107*cdf32b93SJeremy L Thompson     memcpy(tmp, field_description, len+1);
108*cdf32b93SJeremy L Thompson     ctx->field_descriptions[ctx->num_fields].description = tmp;
109*cdf32b93SJeremy L Thompson   }
110*cdf32b93SJeremy L Thompson   ctx->field_descriptions[ctx->num_fields].type = field_type;
111*cdf32b93SJeremy L Thompson   ctx->field_descriptions[ctx->num_fields].offset = field_offset;
112*cdf32b93SJeremy L Thompson   ctx->field_descriptions[ctx->num_fields].size = field_size;
113*cdf32b93SJeremy L Thompson   ctx->num_fields++;
114*cdf32b93SJeremy L Thompson 
115*cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
116*cdf32b93SJeremy L Thompson }
117*cdf32b93SJeremy L Thompson 
118*cdf32b93SJeremy L Thompson /**
119*cdf32b93SJeremy L Thompson   @brief Set QFunctionContext field holding a double precision value
120*cdf32b93SJeremy L Thompson 
121*cdf32b93SJeremy L Thompson   @param ctx        CeedQFunctionContext
122*cdf32b93SJeremy L Thompson   @param field_name Name of field to set
123*cdf32b93SJeremy L Thompson   @param field_type Type of field to set
124*cdf32b93SJeremy L Thompson   @param value      Value to set
125*cdf32b93SJeremy L Thompson 
126*cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
127*cdf32b93SJeremy L Thompson 
128*cdf32b93SJeremy L Thompson   @ref User
129*cdf32b93SJeremy L Thompson **/
130*cdf32b93SJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx,
131*cdf32b93SJeremy L Thompson                                    const char *field_name,
132*cdf32b93SJeremy L Thompson                                    CeedContextFieldType field_type, void *value) {
133*cdf32b93SJeremy L Thompson   int ierr;
134*cdf32b93SJeremy L Thompson 
135*cdf32b93SJeremy L Thompson   // Check field index
136*cdf32b93SJeremy L Thompson   CeedInt field_index = -1;
137*cdf32b93SJeremy L Thompson   ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index);
138*cdf32b93SJeremy L Thompson   CeedChk(ierr);
139*cdf32b93SJeremy L Thompson   if (field_index == -1)
140*cdf32b93SJeremy L Thompson     // LCOV_EXCL_START
141*cdf32b93SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
142*cdf32b93SJeremy L Thompson                      "QFunctionContext field with name \"%s\" not registered",
143*cdf32b93SJeremy L Thompson                      field_name);
144*cdf32b93SJeremy L Thompson   // LCOV_EXCL_STOP
145*cdf32b93SJeremy L Thompson 
146*cdf32b93SJeremy L Thompson   if (ctx->field_descriptions[field_index].type != field_type)
147*cdf32b93SJeremy L Thompson     // LCOV_EXCL_START
148*cdf32b93SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
149*cdf32b93SJeremy L Thompson                      "QFunctionContext field with name \"%s\" registered as %s, "
150*cdf32b93SJeremy L Thompson                      "not registered as %s", field_name,
151*cdf32b93SJeremy L Thompson                      CeedContextFieldTypes[ctx->field_descriptions[field_index].type],
152*cdf32b93SJeremy L Thompson                      CeedContextFieldTypes[field_type]);
153*cdf32b93SJeremy L Thompson   // LCOV_EXCL_STOP
154*cdf32b93SJeremy L Thompson 
155*cdf32b93SJeremy L Thompson   char *data;
156*cdf32b93SJeremy L Thompson   ierr = CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data); CeedChk(ierr);
157*cdf32b93SJeremy L Thompson   memcpy(&data[ctx->field_descriptions[field_index].offset], value,
158*cdf32b93SJeremy L Thompson          ctx->field_descriptions[field_index].size);
159*cdf32b93SJeremy L Thompson   ierr = CeedQFunctionContextRestoreData(ctx, &data); CeedChk(ierr);
160*cdf32b93SJeremy L Thompson 
161*cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
162*cdf32b93SJeremy L Thompson }
163*cdf32b93SJeremy L Thompson 
164*cdf32b93SJeremy L Thompson /// @}
165*cdf32b93SJeremy L Thompson 
166*cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
167777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API
168777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
169777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend
170777ff853SJeremy L Thompson /// @{
171777ff853SJeremy L Thompson 
172777ff853SJeremy L Thompson /**
173777ff853SJeremy L Thompson   @brief Get the Ceed associated with a CeedQFunctionContext
174777ff853SJeremy L Thompson 
175777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
176777ff853SJeremy L Thompson   @param[out] ceed  Variable to store Ceed
177777ff853SJeremy L Thompson 
178777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
179777ff853SJeremy L Thompson 
180777ff853SJeremy L Thompson   @ref Backend
181777ff853SJeremy L Thompson **/
182777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) {
183777ff853SJeremy L Thompson   *ceed = ctx->ceed;
184e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
185777ff853SJeremy L Thompson }
186777ff853SJeremy L Thompson 
187777ff853SJeremy L Thompson /**
1889c774eddSJeremy L Thompson   @brief Check for valid data in a CeedQFunctionContext
1899c774eddSJeremy L Thompson 
1909c774eddSJeremy L Thompson   @param ctx                  CeedQFunctionContext to check validity
1919c774eddSJeremy L Thompson   @param[out] has_valid_data  Variable to store validity
1929c774eddSJeremy L Thompson 
1939c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1949c774eddSJeremy L Thompson 
1959c774eddSJeremy L Thompson   @ref Backend
1969c774eddSJeremy L Thompson **/
1979c774eddSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx,
1989c774eddSJeremy L Thompson                                      bool *has_valid_data) {
1999c774eddSJeremy L Thompson   int ierr;
2009c774eddSJeremy L Thompson 
2019c774eddSJeremy L Thompson   if (!ctx->HasValidData)
2029c774eddSJeremy L Thompson     // LCOV_EXCL_START
2039c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
2049c774eddSJeremy L Thompson                      "Backend does not support HasValidData");
2059c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
2069c774eddSJeremy L Thompson 
2079c774eddSJeremy L Thompson   ierr = ctx->HasValidData(ctx, has_valid_data); CeedChk(ierr);
2089c774eddSJeremy L Thompson 
2099c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
2109c774eddSJeremy L Thompson }
2119c774eddSJeremy L Thompson 
2129c774eddSJeremy L Thompson /**
2139c774eddSJeremy L Thompson   @brief Check for borrowed data of a specific CeedMemType in a
2149c774eddSJeremy L Thompson            CeedQFunctionContext
2159c774eddSJeremy L Thompson 
2169c774eddSJeremy L Thompson   @param ctx                             CeedQFunctionContext to check
2179c774eddSJeremy L Thompson   @param mem_type                        Memory type to check
2189c774eddSJeremy L Thompson   @param[out] has_borrowed_data_of_type  Variable to store result
2199c774eddSJeremy L Thompson 
2209c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
2219c774eddSJeremy L Thompson 
2229c774eddSJeremy L Thompson   @ref Backend
2239c774eddSJeremy L Thompson **/
2249c774eddSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx,
2259c774eddSJeremy L Thompson     CeedMemType mem_type, bool *has_borrowed_data_of_type) {
2269c774eddSJeremy L Thompson   int ierr;
2279c774eddSJeremy L Thompson 
2289c774eddSJeremy L Thompson   if (!ctx->HasBorrowedDataOfType)
2299c774eddSJeremy L Thompson     // LCOV_EXCL_START
2309c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
2319c774eddSJeremy L Thompson                      "Backend does not support HasBorrowedDataOfType");
2329c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
2339c774eddSJeremy L Thompson 
2349c774eddSJeremy L Thompson   ierr = ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type);
2359c774eddSJeremy L Thompson   CeedChk(ierr);
2369c774eddSJeremy L Thompson 
2379c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
2389c774eddSJeremy L Thompson }
2399c774eddSJeremy L Thompson 
2409c774eddSJeremy L Thompson /**
241777ff853SJeremy L Thompson   @brief Get the state of a CeedQFunctionContext
242777ff853SJeremy L Thompson 
243777ff853SJeremy L Thompson   @param ctx         CeedQFunctionContext to retrieve state
244777ff853SJeremy L Thompson   @param[out] state  Variable to store state
245777ff853SJeremy L Thompson 
246777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
247777ff853SJeremy L Thompson 
248777ff853SJeremy L Thompson   @ref Backend
249777ff853SJeremy L Thompson **/
250777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) {
251777ff853SJeremy L Thompson   *state = ctx->state;
252e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
253777ff853SJeremy L Thompson }
254777ff853SJeremy L Thompson 
255777ff853SJeremy L Thompson /**
256777ff853SJeremy L Thompson   @brief Get backend data of a CeedQFunctionContext
257777ff853SJeremy L Thompson 
258777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
259777ff853SJeremy L Thompson   @param[out] data  Variable to store data
260777ff853SJeremy L Thompson 
261777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
262777ff853SJeremy L Thompson 
263777ff853SJeremy L Thompson   @ref Backend
264777ff853SJeremy L Thompson **/
265777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) {
266777ff853SJeremy L Thompson   *(void **)data = ctx->data;
267e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
268777ff853SJeremy L Thompson }
269777ff853SJeremy L Thompson 
270777ff853SJeremy L Thompson /**
271777ff853SJeremy L Thompson   @brief Set backend data of a CeedQFunctionContext
272777ff853SJeremy L Thompson 
273777ff853SJeremy L Thompson   @param[out] ctx  CeedQFunctionContext
274777ff853SJeremy L Thompson   @param data      Data to set
275777ff853SJeremy L Thompson 
276777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
277777ff853SJeremy L Thompson 
278777ff853SJeremy L Thompson   @ref Backend
279777ff853SJeremy L Thompson **/
280777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) {
281777ff853SJeremy L Thompson   ctx->data = data;
282e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
283777ff853SJeremy L Thompson }
284777ff853SJeremy L Thompson 
28534359f16Sjeremylt /**
28634359f16Sjeremylt   @brief Increment the reference counter for a CeedQFunctionContext
28734359f16Sjeremylt 
28834359f16Sjeremylt   @param ctx  CeedQFunctionContext to increment the reference counter
28934359f16Sjeremylt 
29034359f16Sjeremylt   @return An error code: 0 - success, otherwise - failure
29134359f16Sjeremylt 
29234359f16Sjeremylt   @ref Backend
29334359f16Sjeremylt **/
2949560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) {
29534359f16Sjeremylt   ctx->ref_count++;
29634359f16Sjeremylt   return CEED_ERROR_SUCCESS;
29734359f16Sjeremylt }
29834359f16Sjeremylt 
299777ff853SJeremy L Thompson /// @}
300777ff853SJeremy L Thompson 
301777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
302777ff853SJeremy L Thompson /// CeedQFunctionContext Public API
303777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
304777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser
305777ff853SJeremy L Thompson /// @{
306777ff853SJeremy L Thompson 
307777ff853SJeremy L Thompson /**
308777ff853SJeremy L Thompson   @brief Create a CeedQFunctionContext for storing CeedQFunction user context data
309777ff853SJeremy L Thompson 
310777ff853SJeremy L Thompson   @param ceed      A Ceed object where the CeedQFunctionContext will be created
311777ff853SJeremy L Thompson   @param[out] ctx  Address of the variable where the newly created
312777ff853SJeremy L Thompson                      CeedQFunctionContext will be stored
313777ff853SJeremy L Thompson 
314777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
315777ff853SJeremy L Thompson 
316777ff853SJeremy L Thompson   @ref User
317777ff853SJeremy L Thompson **/
318777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) {
319777ff853SJeremy L Thompson   int ierr;
320777ff853SJeremy L Thompson 
321777ff853SJeremy L Thompson   if (!ceed->QFunctionContextCreate) {
322777ff853SJeremy L Thompson     Ceed delegate;
323777ff853SJeremy L Thompson     ierr = CeedGetObjectDelegate(ceed, &delegate, "Context"); CeedChk(ierr);
324777ff853SJeremy L Thompson 
325777ff853SJeremy L Thompson     if (!delegate)
326777ff853SJeremy L Thompson       // LCOV_EXCL_START
327e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
328e15f9bd0SJeremy L Thompson                        "Backend does not support ContextCreate");
329777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
330777ff853SJeremy L Thompson 
331777ff853SJeremy L Thompson     ierr = CeedQFunctionContextCreate(delegate, ctx); CeedChk(ierr);
332e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
333777ff853SJeremy L Thompson   }
334777ff853SJeremy L Thompson 
335777ff853SJeremy L Thompson   ierr = CeedCalloc(1, ctx); CeedChk(ierr);
336777ff853SJeremy L Thompson   (*ctx)->ceed = ceed;
3379560d06aSjeremylt   ierr = CeedReference(ceed); CeedChk(ierr);
338d1d35e2fSjeremylt   (*ctx)->ref_count = 1;
339777ff853SJeremy L Thompson   ierr = ceed->QFunctionContextCreate(*ctx); CeedChk(ierr);
340e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
341777ff853SJeremy L Thompson }
342777ff853SJeremy L Thompson 
343777ff853SJeremy L Thompson /**
3449560d06aSjeremylt   @brief Copy the pointer to a CeedQFunctionContext. Both pointers should
3459560d06aSjeremylt            be destroyed with `CeedQFunctionContextDestroy()`;
3469560d06aSjeremylt            Note: If `*ctx_copy` is non-NULL, then it is assumed that
3479560d06aSjeremylt            `*ctx_copy` is a pointer to a CeedQFunctionContext. This
3489560d06aSjeremylt            CeedQFunctionContext will be destroyed if `*ctx_copy` is the
3499560d06aSjeremylt            only reference to this CeedQFunctionContext.
3509560d06aSjeremylt 
3519560d06aSjeremylt   @param ctx            CeedQFunctionContext to copy reference to
3529560d06aSjeremylt   @param[out] ctx_copy  Variable to store copied reference
3539560d06aSjeremylt 
3549560d06aSjeremylt   @return An error code: 0 - success, otherwise - failure
3559560d06aSjeremylt 
3569560d06aSjeremylt   @ref User
3579560d06aSjeremylt **/
3589560d06aSjeremylt int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx,
3599560d06aSjeremylt                                       CeedQFunctionContext *ctx_copy) {
3609560d06aSjeremylt   int ierr;
3619560d06aSjeremylt 
3629560d06aSjeremylt   ierr = CeedQFunctionContextReference(ctx); CeedChk(ierr);
3639560d06aSjeremylt   ierr = CeedQFunctionContextDestroy(ctx_copy); CeedChk(ierr);
3649560d06aSjeremylt   *ctx_copy = ctx;
3659560d06aSjeremylt   return CEED_ERROR_SUCCESS;
3669560d06aSjeremylt }
3679560d06aSjeremylt 
3689560d06aSjeremylt /**
369777ff853SJeremy L Thompson   @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated
370777ff853SJeremy L Thompson            data if applicable. The backend may copy values to a different
371777ff853SJeremy L Thompson            memtype, such as during @ref CeedQFunctionApply().
372777ff853SJeremy L Thompson            See also @ref CeedQFunctionContextTakeData().
373777ff853SJeremy L Thompson 
374777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
375d1d35e2fSjeremylt   @param mem_type   Memory type of the data being passed
376d1d35e2fSjeremylt   @param copy_mode  Copy mode for the data
377891038deSjeremylt   @param size       Size of data, in bytes
378777ff853SJeremy L Thompson   @param data       Data to be used
379777ff853SJeremy L Thompson 
380777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
381777ff853SJeremy L Thompson 
382777ff853SJeremy L Thompson   @ref User
383777ff853SJeremy L Thompson **/
384d1d35e2fSjeremylt int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type,
385d1d35e2fSjeremylt                                 CeedCopyMode copy_mode,
386777ff853SJeremy L Thompson                                 size_t size, void *data) {
387777ff853SJeremy L Thompson   int ierr;
388777ff853SJeremy L Thompson 
389777ff853SJeremy L Thompson   if (!ctx->SetData)
390777ff853SJeremy L Thompson     // LCOV_EXCL_START
391e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
392e15f9bd0SJeremy L Thompson                      "Backend does not support ContextSetData");
393777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
394777ff853SJeremy L Thompson 
395777ff853SJeremy L Thompson   if (ctx->state % 2 == 1)
396777ff853SJeremy L Thompson     // LCOV_EXCL_START
397777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
398777ff853SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
399777ff853SJeremy L Thompson                      "access lock is already in use");
400777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
401777ff853SJeremy L Thompson 
402d1d35e2fSjeremylt   ctx->ctx_size = size;
403d1d35e2fSjeremylt   ierr = ctx->SetData(ctx, mem_type, copy_mode, data); CeedChk(ierr);
404777ff853SJeremy L Thompson   ctx->state += 2;
405e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
406777ff853SJeremy L Thompson }
407777ff853SJeremy L Thompson 
408777ff853SJeremy L Thompson /**
409891038deSjeremylt   @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type.
410891038deSjeremylt            The caller is responsible for managing and freeing the memory.
411891038deSjeremylt 
412891038deSjeremylt   @param ctx        CeedQFunctionContext to access
413891038deSjeremylt   @param mem_type   Memory type on which to access the data. If the backend
414891038deSjeremylt                       uses a different memory type, this will perform a copy.
415891038deSjeremylt   @param[out] data  Data on memory type mem_type
416891038deSjeremylt 
417891038deSjeremylt   @return An error code: 0 - success, otherwise - failure
418891038deSjeremylt 
419891038deSjeremylt   @ref User
420891038deSjeremylt **/
421891038deSjeremylt int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type,
422891038deSjeremylt                                  void *data) {
423891038deSjeremylt   int ierr;
424891038deSjeremylt 
4259c774eddSJeremy L Thompson   bool has_valid_data = true;
4269c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr);
4279c774eddSJeremy L Thompson   if (!has_valid_data)
4289c774eddSJeremy L Thompson     // LCOV_EXCL_START
4299c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
4309c774eddSJeremy L Thompson                      "CeedQFunctionContext has no valid data to take, must set data");
4319c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
4329c774eddSJeremy L Thompson 
433891038deSjeremylt   if (!ctx->TakeData)
434891038deSjeremylt     // LCOV_EXCL_START
435891038deSjeremylt     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
436891038deSjeremylt                      "Backend does not support TakeData");
437891038deSjeremylt   // LCOV_EXCL_STOP
438891038deSjeremylt 
439891038deSjeremylt   if (ctx->state % 2 == 1)
440891038deSjeremylt     // LCOV_EXCL_START
441891038deSjeremylt     return CeedError(ctx->ceed, 1,
442891038deSjeremylt                      "Cannot grant CeedQFunctionContext data access, the "
443891038deSjeremylt                      "access lock is already in use");
444891038deSjeremylt   // LCOV_EXCL_STOP
445891038deSjeremylt 
4469c774eddSJeremy L Thompson   bool has_borrowed_data_of_type = true;
4479c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type,
4489c774eddSJeremy L Thompson          &has_borrowed_data_of_type); CeedChk(ierr);
4499c774eddSJeremy L Thompson   if (!has_borrowed_data_of_type)
4509c774eddSJeremy L Thompson     // LCOV_EXCL_START
4519c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
4529c774eddSJeremy L Thompson                      "CeedQFunctionContext has no borowed %s data, "
4539c774eddSJeremy L Thompson                      "must set data with CeedQFunctionContextSetData",
4549c774eddSJeremy L Thompson                      CeedMemTypes[mem_type]);
4559c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
4569c774eddSJeremy L Thompson 
457891038deSjeremylt   void *temp_data = NULL;
458891038deSjeremylt   ierr = ctx->TakeData(ctx, mem_type, &temp_data); CeedChk(ierr);
459891038deSjeremylt   if (data) (*(void **)data) = temp_data;
460891038deSjeremylt   return CEED_ERROR_SUCCESS;
461891038deSjeremylt }
462891038deSjeremylt 
463891038deSjeremylt /**
464777ff853SJeremy L Thompson   @brief Get read/write access to a CeedQFunctionContext via the specified memory type.
465777ff853SJeremy L Thompson            Restore access with @ref CeedQFunctionContextRestoreData().
466777ff853SJeremy L Thompson 
467777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext to access
468d1d35e2fSjeremylt   @param mem_type   Memory type on which to access the data. If the backend
469777ff853SJeremy L Thompson                       uses a different memory type, this will perform a copy.
470d1d35e2fSjeremylt   @param[out] data  Data on memory type mem_type
471777ff853SJeremy L Thompson 
472777ff853SJeremy L Thompson   @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions
473777ff853SJeremy L Thompson     provide access to array pointers in the desired memory space. Pairing
474777ff853SJeremy L Thompson     get/restore allows the Context to track access.
475777ff853SJeremy L Thompson 
476777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
477777ff853SJeremy L Thompson 
478777ff853SJeremy L Thompson   @ref User
479777ff853SJeremy L Thompson **/
480d1d35e2fSjeremylt int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type,
481777ff853SJeremy L Thompson                                 void *data) {
482777ff853SJeremy L Thompson   int ierr;
483777ff853SJeremy L Thompson 
484777ff853SJeremy L Thompson   if (!ctx->GetData)
485777ff853SJeremy L Thompson     // LCOV_EXCL_START
486e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
487e15f9bd0SJeremy L Thompson                      "Backend does not support GetData");
488777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
489777ff853SJeremy L Thompson 
490777ff853SJeremy L Thompson   if (ctx->state % 2 == 1)
491777ff853SJeremy L Thompson     // LCOV_EXCL_START
492777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
493777ff853SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
494777ff853SJeremy L Thompson                      "access lock is already in use");
495777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
496777ff853SJeremy L Thompson 
4979c774eddSJeremy L Thompson   bool has_valid_data = true;
4989c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr);
4999c774eddSJeremy L Thompson   if (!has_valid_data)
5009c774eddSJeremy L Thompson     // LCOV_EXCL_START
5019c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
5029c774eddSJeremy L Thompson                      "CeedQFunctionContext has no valid data to get, must set data");
5039c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
5049c774eddSJeremy L Thompson 
505d1d35e2fSjeremylt   ierr = ctx->GetData(ctx, mem_type, data); CeedChk(ierr);
506777ff853SJeremy L Thompson   ctx->state += 1;
507e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
508777ff853SJeremy L Thompson }
509777ff853SJeremy L Thompson 
510777ff853SJeremy L Thompson /**
511777ff853SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetData()
512777ff853SJeremy L Thompson 
513777ff853SJeremy L Thompson   @param ctx   CeedQFunctionContext to restore
514777ff853SJeremy L Thompson   @param data  Data to restore
515777ff853SJeremy L Thompson 
516777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
517777ff853SJeremy L Thompson 
518777ff853SJeremy L Thompson   @ref User
519777ff853SJeremy L Thompson **/
520777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) {
521777ff853SJeremy L Thompson   int ierr;
522777ff853SJeremy L Thompson 
523777ff853SJeremy L Thompson   if (!ctx->RestoreData)
524777ff853SJeremy L Thompson     // LCOV_EXCL_START
525e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
526e15f9bd0SJeremy L Thompson                      "Backend does not support RestoreData");
527777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
528777ff853SJeremy L Thompson 
529777ff853SJeremy L Thompson   if (ctx->state % 2 != 1)
530777ff853SJeremy L Thompson     // LCOV_EXCL_START
531777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
532777ff853SJeremy L Thompson                      "Cannot restore CeedQFunctionContext array access, "
533777ff853SJeremy L Thompson                      "access was not granted");
534777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
535777ff853SJeremy L Thompson 
536777ff853SJeremy L Thompson   ierr = ctx->RestoreData(ctx); CeedChk(ierr);
537777ff853SJeremy L Thompson   *(void **)data = NULL;
538777ff853SJeremy L Thompson   ctx->state += 1;
539e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
540777ff853SJeremy L Thompson }
541777ff853SJeremy L Thompson 
542777ff853SJeremy L Thompson /**
543*cdf32b93SJeremy L Thompson   @brief Register QFunctionContext a field holding a double precision value
544*cdf32b93SJeremy L Thompson 
545*cdf32b93SJeremy L Thompson   @param ctx               CeedQFunctionContext
546*cdf32b93SJeremy L Thompson   @param field_name        Name of field to register
547*cdf32b93SJeremy L Thompson   @param field_offset      Offset of field to register
548*cdf32b93SJeremy L Thompson   @param field_description Description of field, or NULL for none
549*cdf32b93SJeremy L Thompson 
550*cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
551*cdf32b93SJeremy L Thompson 
552*cdf32b93SJeremy L Thompson   @ref User
553*cdf32b93SJeremy L Thompson **/
554*cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx,
555*cdf32b93SJeremy L Thompson                                        const char *field_name, size_t field_offset,
556*cdf32b93SJeremy L Thompson                                        const char *field_description) {
557*cdf32b93SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset,
558*cdf32b93SJeremy L Thompson          field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double));
559*cdf32b93SJeremy L Thompson }
560*cdf32b93SJeremy L Thompson 
561*cdf32b93SJeremy L Thompson /**
562*cdf32b93SJeremy L Thompson   @brief Register QFunctionContext a field holding a int32 value
563*cdf32b93SJeremy L Thompson 
564*cdf32b93SJeremy L Thompson   @param ctx               CeedQFunctionContext
565*cdf32b93SJeremy L Thompson   @param field_name        Name of field to register
566*cdf32b93SJeremy L Thompson   @param field_offset      Offset of field to register
567*cdf32b93SJeremy L Thompson   @param field_description Description of field, or NULL for none
568*cdf32b93SJeremy L Thompson 
569*cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
570*cdf32b93SJeremy L Thompson 
571*cdf32b93SJeremy L Thompson   @ref User
572*cdf32b93SJeremy L Thompson **/
573*cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx,
574*cdf32b93SJeremy L Thompson                                       const char *field_name, size_t field_offset,
575*cdf32b93SJeremy L Thompson                                       const char *field_description) {
576*cdf32b93SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset,
577*cdf32b93SJeremy L Thompson          field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int));
578*cdf32b93SJeremy L Thompson }
579*cdf32b93SJeremy L Thompson 
580*cdf32b93SJeremy L Thompson /**
581*cdf32b93SJeremy L Thompson   @brief Get descriptions for registered QFunctionContext fields
582*cdf32b93SJeremy L Thompson 
583*cdf32b93SJeremy L Thompson   @param ctx                     CeedQFunctionContext
584*cdf32b93SJeremy L Thompson   @param[out] field_descriptions Variable to hold array of field descriptions
585*cdf32b93SJeremy L Thompson   @param[out] num_fields         Length of field descriptions array
586*cdf32b93SJeremy L Thompson 
587*cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
588*cdf32b93SJeremy L Thompson 
589*cdf32b93SJeremy L Thompson   @ref User
590*cdf32b93SJeremy L Thompson **/
591*cdf32b93SJeremy L Thompson int CeedQFunctionContextGetFieldDescriptions(CeedQFunctionContext ctx,
592*cdf32b93SJeremy L Thompson     const CeedQFunctionContextFieldDescription **field_descriptions,
593*cdf32b93SJeremy L Thompson     CeedInt *num_fields) {
594*cdf32b93SJeremy L Thompson   *field_descriptions = ctx->field_descriptions;
595*cdf32b93SJeremy L Thompson   *num_fields = ctx->num_fields;
596*cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
597*cdf32b93SJeremy L Thompson }
598*cdf32b93SJeremy L Thompson 
599*cdf32b93SJeremy L Thompson /**
600*cdf32b93SJeremy L Thompson   @brief Set QFunctionContext field holding a double precision value
601*cdf32b93SJeremy L Thompson 
602*cdf32b93SJeremy L Thompson   @param ctx        CeedQFunctionContext
603*cdf32b93SJeremy L Thompson   @param field_name Name of field to register
604*cdf32b93SJeremy L Thompson   @param value      Value to set
605*cdf32b93SJeremy L Thompson 
606*cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
607*cdf32b93SJeremy L Thompson 
608*cdf32b93SJeremy L Thompson   @ref User
609*cdf32b93SJeremy L Thompson **/
610*cdf32b93SJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx,
611*cdf32b93SJeremy L Thompson                                   const char *field_name, double value) {
612*cdf32b93SJeremy L Thompson   return CeedQFunctionContextSetGeneric(ctx, field_name,
613*cdf32b93SJeremy L Thompson                                         CEED_CONTEXT_FIELD_DOUBLE,
614*cdf32b93SJeremy L Thompson                                         &value);
615*cdf32b93SJeremy L Thompson }
616*cdf32b93SJeremy L Thompson 
617*cdf32b93SJeremy L Thompson /**
618*cdf32b93SJeremy L Thompson   @brief Set QFunctionContext field holding a int32 value
619*cdf32b93SJeremy L Thompson 
620*cdf32b93SJeremy L Thompson   @param ctx        CeedQFunctionContext
621*cdf32b93SJeremy L Thompson   @param field_name Name of field to set
622*cdf32b93SJeremy L Thompson   @param value      Value to set
623*cdf32b93SJeremy L Thompson 
624*cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
625*cdf32b93SJeremy L Thompson 
626*cdf32b93SJeremy L Thompson   @ref User
627*cdf32b93SJeremy L Thompson **/
628*cdf32b93SJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx,
629*cdf32b93SJeremy L Thompson                                  const char *field_name, int value) {
630*cdf32b93SJeremy L Thompson   return CeedQFunctionContextSetGeneric(ctx, field_name, CEED_CONTEXT_FIELD_INT32,
631*cdf32b93SJeremy L Thompson                                         &value);
632*cdf32b93SJeremy L Thompson }
633*cdf32b93SJeremy L Thompson 
634*cdf32b93SJeremy L Thompson /**
63580a9ef05SNatalie Beams   @brief Get data size for a Context
63680a9ef05SNatalie Beams 
63780a9ef05SNatalie Beams   @param ctx            CeedQFunctionContext
63880a9ef05SNatalie Beams   @param[out] ctx_size  Variable to store size of context data values
63980a9ef05SNatalie Beams 
64080a9ef05SNatalie Beams   @return An error code: 0 - success, otherwise - failure
64180a9ef05SNatalie Beams 
64280a9ef05SNatalie Beams   @ref User
64380a9ef05SNatalie Beams **/
64480a9ef05SNatalie Beams int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx,
64580a9ef05SNatalie Beams                                        size_t *ctx_size) {
64680a9ef05SNatalie Beams   *ctx_size = ctx->ctx_size;
64780a9ef05SNatalie Beams   return CEED_ERROR_SUCCESS;
64880a9ef05SNatalie Beams }
64980a9ef05SNatalie Beams 
65080a9ef05SNatalie Beams 
65180a9ef05SNatalie Beams /**
652777ff853SJeremy L Thompson   @brief View a CeedQFunctionContext
653777ff853SJeremy L Thompson 
654777ff853SJeremy L Thompson   @param[in] ctx     CeedQFunctionContext to view
655777ff853SJeremy L Thompson   @param[in] stream  Filestream to write to
656777ff853SJeremy L Thompson 
657777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
658777ff853SJeremy L Thompson 
659777ff853SJeremy L Thompson   @ref User
660777ff853SJeremy L Thompson **/
661777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) {
662777ff853SJeremy L Thompson   fprintf(stream, "CeedQFunctionContext\n");
663d1d35e2fSjeremylt   fprintf(stream, "  Context Data Size: %ld\n", ctx->ctx_size);
664e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
665777ff853SJeremy L Thompson }
666777ff853SJeremy L Thompson 
667777ff853SJeremy L Thompson /**
668777ff853SJeremy L Thompson   @brief Destroy a CeedQFunctionContext
669777ff853SJeremy L Thompson 
670777ff853SJeremy L Thompson   @param ctx  CeedQFunctionContext to destroy
671777ff853SJeremy L Thompson 
672777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
673777ff853SJeremy L Thompson 
674777ff853SJeremy L Thompson   @ref User
675777ff853SJeremy L Thompson **/
676777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) {
677777ff853SJeremy L Thompson   int ierr;
678777ff853SJeremy L Thompson 
679d1d35e2fSjeremylt   if (!*ctx || --(*ctx)->ref_count > 0)
680e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
681777ff853SJeremy L Thompson 
682777ff853SJeremy L Thompson   if ((*ctx) && ((*ctx)->state % 2) == 1)
683777ff853SJeremy L Thompson     // LCOV_EXCL_START
684777ff853SJeremy L Thompson     return CeedError((*ctx)->ceed, 1,
685777ff853SJeremy L Thompson                      "Cannot destroy CeedQFunctionContext, the access "
686777ff853SJeremy L Thompson                      "lock is in use");
687777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
688777ff853SJeremy L Thompson 
689777ff853SJeremy L Thompson   if ((*ctx)->Destroy) {
690777ff853SJeremy L Thompson     ierr = (*ctx)->Destroy(*ctx); CeedChk(ierr);
691777ff853SJeremy L Thompson   }
692*cdf32b93SJeremy L Thompson   for (CeedInt i=0; i<(*ctx)->num_fields; i++) {
693*cdf32b93SJeremy L Thompson     ierr = CeedFree(&(*ctx)->field_descriptions[i].name); CeedChk(ierr);
694*cdf32b93SJeremy L Thompson     ierr = CeedFree(&(*ctx)->field_descriptions[i].description); CeedChk(ierr);
695*cdf32b93SJeremy L Thompson   }
696*cdf32b93SJeremy L Thompson   ierr = CeedFree(&(*ctx)->field_descriptions); CeedChk(ierr);
697777ff853SJeremy L Thompson   ierr = CeedDestroy(&(*ctx)->ceed); CeedChk(ierr);
698777ff853SJeremy L Thompson   ierr = CeedFree(ctx); CeedChk(ierr);
699*cdf32b93SJeremy L Thompson 
700e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
701777ff853SJeremy L Thompson }
702777ff853SJeremy L Thompson 
703777ff853SJeremy L Thompson /// @}
704