xref: /libCEED/interface/ceed-qfunctioncontext.c (revision 3d8e882215d238700cdceb37404f76ca7fa24eaa)
1*3d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors.
2*3d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3777ff853SJeremy L Thompson //
4*3d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
5777ff853SJeremy L Thompson //
6*3d8e8822SJeremy L Thompson // This file is part of CEED:  http://github.com/ceed
7777ff853SJeremy L Thompson 
8ec3da8bcSJed Brown #include <ceed/ceed.h>
9ec3da8bcSJed Brown #include <ceed/backend.h>
103d576824SJeremy L Thompson #include <ceed-impl.h>
113d576824SJeremy L Thompson #include <stdint.h>
123d576824SJeremy L Thompson #include <stdio.h>
13cdf32b93SJeremy L Thompson #include <string.h>
14777ff853SJeremy L Thompson 
15777ff853SJeremy L Thompson /// @file
16777ff853SJeremy L Thompson /// Implementation of public CeedQFunctionContext interfaces
17777ff853SJeremy L Thompson 
18777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
19cdf32b93SJeremy L Thompson /// CeedQFunctionContext Library Internal Functions
20cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
21cdf32b93SJeremy L Thompson /// @addtogroup CeedQFunctionDeveloper
22cdf32b93SJeremy L Thompson /// @{
23cdf32b93SJeremy L Thompson 
24cdf32b93SJeremy L Thompson /**
25cdf32b93SJeremy L Thompson   @brief Get index for QFunctionContext field
26cdf32b93SJeremy L Thompson 
27cdf32b93SJeremy L Thompson   @param ctx         CeedQFunctionContext
28cdf32b93SJeremy L Thompson   @param field_name  Name of field
29cdf32b93SJeremy L Thompson   @param field_index Index of field, or -1 if field is not registered
30cdf32b93SJeremy L Thompson 
31cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
32cdf32b93SJeremy L Thompson 
33cdf32b93SJeremy L Thompson   @ref Developer
34cdf32b93SJeremy L Thompson **/
35cdf32b93SJeremy L Thompson int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx,
36cdf32b93SJeremy L Thompson                                       const char *field_name, CeedInt *field_index) {
37cdf32b93SJeremy L Thompson   *field_index = -1;
38cdf32b93SJeremy L Thompson   for (CeedInt i=0; i<ctx->num_fields; i++)
393668ca4bSJeremy L Thompson     if (!strcmp(ctx->field_labels[i]->name, field_name))
40cdf32b93SJeremy L Thompson       *field_index = i;
41cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
42cdf32b93SJeremy L Thompson }
43cdf32b93SJeremy L Thompson 
44cdf32b93SJeremy L Thompson /**
45cdf32b93SJeremy L Thompson   @brief Common function for registering QFunctionContext fields
46cdf32b93SJeremy L Thompson 
47cdf32b93SJeremy L Thompson   @param ctx               CeedQFunctionContext
48cdf32b93SJeremy L Thompson   @param field_name        Name of field to register
49cdf32b93SJeremy L Thompson   @param field_offset      Offset of field to register
50cdf32b93SJeremy L Thompson   @param field_description Description of field, or NULL for none
51cdf32b93SJeremy L Thompson   @param field_type        Field data type, such as double or int32
52cdf32b93SJeremy L Thompson   @param field_size        Size of field, in bytes
537bfe0f0eSJeremy L Thompson   @param num_values        Number of values to register, must be contiguous in memory
54cdf32b93SJeremy L Thompson 
55cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
56cdf32b93SJeremy L Thompson 
57cdf32b93SJeremy L Thompson   @ref Developer
58cdf32b93SJeremy L Thompson **/
59cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx,
60cdf32b93SJeremy L Thompson                                         const char *field_name, size_t field_offset,
61cdf32b93SJeremy L Thompson                                         const char *field_description,
62cdf32b93SJeremy L Thompson                                         CeedContextFieldType field_type,
637bfe0f0eSJeremy L Thompson                                         size_t field_size, size_t num_values) {
64cdf32b93SJeremy L Thompson   int ierr;
65cdf32b93SJeremy L Thompson 
66cdf32b93SJeremy L Thompson   // Check for duplicate
67cdf32b93SJeremy L Thompson   CeedInt field_index = -1;
68cdf32b93SJeremy L Thompson   ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index);
69cdf32b93SJeremy L Thompson   CeedChk(ierr);
70cdf32b93SJeremy L Thompson   if (field_index != -1)
71cdf32b93SJeremy L Thompson     // LCOV_EXCL_START
72cdf32b93SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
73cdf32b93SJeremy L Thompson                      "QFunctionContext field with name \"%s\" already registered",
74cdf32b93SJeremy L Thompson                      field_name);
75cdf32b93SJeremy L Thompson   // LCOV_EXCL_STOP
76cdf32b93SJeremy L Thompson 
77cdf32b93SJeremy L Thompson   // Allocate space for field data
78cdf32b93SJeremy L Thompson   if (ctx->num_fields == 0) {
793668ca4bSJeremy L Thompson     ierr = CeedCalloc(1, &ctx->field_labels); CeedChk(ierr);
80cdf32b93SJeremy L Thompson     ctx->max_fields = 1;
81cdf32b93SJeremy L Thompson   } else if (ctx->num_fields == ctx->max_fields) {
823668ca4bSJeremy L Thompson     ierr = CeedRealloc(2*ctx->max_fields, &ctx->field_labels);
83cdf32b93SJeremy L Thompson     CeedChk(ierr);
84cdf32b93SJeremy L Thompson     ctx->max_fields *= 2;
85cdf32b93SJeremy L Thompson   }
863668ca4bSJeremy L Thompson   ierr = CeedCalloc(1, &ctx->field_labels[ctx->num_fields]); CeedChk(ierr);
87cdf32b93SJeremy L Thompson 
88cdf32b93SJeremy L Thompson   // Copy field data
89f7e22acaSJeremy L Thompson   ierr = CeedStringAllocCopy(field_name,
903668ca4bSJeremy L Thompson                              (char **)&ctx->field_labels[ctx->num_fields]->name);
91f7e22acaSJeremy L Thompson   CeedChk(ierr);
92f7e22acaSJeremy L Thompson   ierr = CeedStringAllocCopy(field_description,
933668ca4bSJeremy L Thompson                              (char **)&ctx->field_labels[ctx->num_fields]->description);
94f7e22acaSJeremy L Thompson   CeedChk(ierr);
953668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->type = field_type;
963668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->offset = field_offset;
977bfe0f0eSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->size = field_size * num_values;
987bfe0f0eSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->num_values = num_values;
99cdf32b93SJeremy L Thompson   ctx->num_fields++;
100cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
101cdf32b93SJeremy L Thompson }
102cdf32b93SJeremy L Thompson 
103cdf32b93SJeremy L Thompson /// @}
104cdf32b93SJeremy L Thompson 
105cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
106777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API
107777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
108777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend
109777ff853SJeremy L Thompson /// @{
110777ff853SJeremy L Thompson 
111777ff853SJeremy L Thompson /**
112777ff853SJeremy L Thompson   @brief Get the Ceed associated with a CeedQFunctionContext
113777ff853SJeremy L Thompson 
114777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
115777ff853SJeremy L Thompson   @param[out] ceed  Variable to store Ceed
116777ff853SJeremy L Thompson 
117777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
118777ff853SJeremy L Thompson 
119777ff853SJeremy L Thompson   @ref Backend
120777ff853SJeremy L Thompson **/
121777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) {
122777ff853SJeremy L Thompson   *ceed = ctx->ceed;
123e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
124777ff853SJeremy L Thompson }
125777ff853SJeremy L Thompson 
126777ff853SJeremy L Thompson /**
1279c774eddSJeremy L Thompson   @brief Check for valid data in a CeedQFunctionContext
1289c774eddSJeremy L Thompson 
1299c774eddSJeremy L Thompson   @param ctx                  CeedQFunctionContext to check validity
1309c774eddSJeremy L Thompson   @param[out] has_valid_data  Variable to store validity
1319c774eddSJeremy L Thompson 
1329c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1339c774eddSJeremy L Thompson 
1349c774eddSJeremy L Thompson   @ref Backend
1359c774eddSJeremy L Thompson **/
1369c774eddSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx,
1379c774eddSJeremy L Thompson                                      bool *has_valid_data) {
1389c774eddSJeremy L Thompson   int ierr;
1399c774eddSJeremy L Thompson 
1409c774eddSJeremy L Thompson   if (!ctx->HasValidData)
1419c774eddSJeremy L Thompson     // LCOV_EXCL_START
1429c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
1439c774eddSJeremy L Thompson                      "Backend does not support HasValidData");
1449c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
1459c774eddSJeremy L Thompson 
1469c774eddSJeremy L Thompson   ierr = ctx->HasValidData(ctx, has_valid_data); CeedChk(ierr);
1479c774eddSJeremy L Thompson 
1489c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1499c774eddSJeremy L Thompson }
1509c774eddSJeremy L Thompson 
1519c774eddSJeremy L Thompson /**
1529c774eddSJeremy L Thompson   @brief Check for borrowed data of a specific CeedMemType in a
1539c774eddSJeremy L Thompson            CeedQFunctionContext
1549c774eddSJeremy L Thompson 
1559c774eddSJeremy L Thompson   @param ctx                             CeedQFunctionContext to check
1569c774eddSJeremy L Thompson   @param mem_type                        Memory type to check
1579c774eddSJeremy L Thompson   @param[out] has_borrowed_data_of_type  Variable to store result
1589c774eddSJeremy L Thompson 
1599c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1609c774eddSJeremy L Thompson 
1619c774eddSJeremy L Thompson   @ref Backend
1629c774eddSJeremy L Thompson **/
1639c774eddSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx,
1649c774eddSJeremy L Thompson     CeedMemType mem_type, bool *has_borrowed_data_of_type) {
1659c774eddSJeremy L Thompson   int ierr;
1669c774eddSJeremy L Thompson 
1679c774eddSJeremy L Thompson   if (!ctx->HasBorrowedDataOfType)
1689c774eddSJeremy L Thompson     // LCOV_EXCL_START
1699c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
1709c774eddSJeremy L Thompson                      "Backend does not support HasBorrowedDataOfType");
1719c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
1729c774eddSJeremy L Thompson 
1739c774eddSJeremy L Thompson   ierr = ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type);
1749c774eddSJeremy L Thompson   CeedChk(ierr);
1759c774eddSJeremy L Thompson 
1769c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1779c774eddSJeremy L Thompson }
1789c774eddSJeremy L Thompson 
1799c774eddSJeremy L Thompson /**
180777ff853SJeremy L Thompson   @brief Get the state of a CeedQFunctionContext
181777ff853SJeremy L Thompson 
182777ff853SJeremy L Thompson   @param ctx         CeedQFunctionContext to retrieve state
183777ff853SJeremy L Thompson   @param[out] state  Variable to store state
184777ff853SJeremy L Thompson 
185777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
186777ff853SJeremy L Thompson 
187777ff853SJeremy L Thompson   @ref Backend
188777ff853SJeremy L Thompson **/
189777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) {
190777ff853SJeremy L Thompson   *state = ctx->state;
191e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
192777ff853SJeremy L Thompson }
193777ff853SJeremy L Thompson 
194777ff853SJeremy L Thompson /**
195777ff853SJeremy L Thompson   @brief Get backend data of a CeedQFunctionContext
196777ff853SJeremy L Thompson 
197777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
198777ff853SJeremy L Thompson   @param[out] data  Variable to store data
199777ff853SJeremy L Thompson 
200777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
201777ff853SJeremy L Thompson 
202777ff853SJeremy L Thompson   @ref Backend
203777ff853SJeremy L Thompson **/
204777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) {
205777ff853SJeremy L Thompson   *(void **)data = ctx->data;
206e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
207777ff853SJeremy L Thompson }
208777ff853SJeremy L Thompson 
209777ff853SJeremy L Thompson /**
210777ff853SJeremy L Thompson   @brief Set backend data of a CeedQFunctionContext
211777ff853SJeremy L Thompson 
212777ff853SJeremy L Thompson   @param[out] ctx  CeedQFunctionContext
213777ff853SJeremy L Thompson   @param data      Data to set
214777ff853SJeremy L Thompson 
215777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
216777ff853SJeremy L Thompson 
217777ff853SJeremy L Thompson   @ref Backend
218777ff853SJeremy L Thompson **/
219777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) {
220777ff853SJeremy L Thompson   ctx->data = data;
221e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
222777ff853SJeremy L Thompson }
223777ff853SJeremy L Thompson 
22434359f16Sjeremylt /**
225d8dd9a91SJeremy L Thompson   @brief Set QFunctionContext field
226d8dd9a91SJeremy L Thompson 
227d8dd9a91SJeremy L Thompson   @param ctx         CeedQFunctionContext
2283668ca4bSJeremy L Thompson   @param field_label Label of field to set
229d8dd9a91SJeremy L Thompson   @param field_type  Type of field to set
230d8dd9a91SJeremy L Thompson   @param value       Value to set
231d8dd9a91SJeremy L Thompson 
232d8dd9a91SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
233d8dd9a91SJeremy L Thompson 
234d8dd9a91SJeremy L Thompson   @ref User
235d8dd9a91SJeremy L Thompson **/
236d8dd9a91SJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx,
2373668ca4bSJeremy L Thompson                                    CeedContextFieldLabel field_label,
238d8dd9a91SJeremy L Thompson                                    CeedContextFieldType field_type,
2393668ca4bSJeremy L Thompson                                    void *value) {
240d8dd9a91SJeremy L Thompson   int ierr;
241d8dd9a91SJeremy L Thompson 
2423668ca4bSJeremy L Thompson   // Check field type
2433668ca4bSJeremy L Thompson   if (field_label->type != field_type)
244d8dd9a91SJeremy L Thompson     // LCOV_EXCL_START
245d8dd9a91SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
246d8dd9a91SJeremy L Thompson                      "QFunctionContext field with name \"%s\" registered as %s, "
2473668ca4bSJeremy L Thompson                      "not registered as %s", field_label->name,
2483668ca4bSJeremy L Thompson                      CeedContextFieldTypes[field_label->type],
249d8dd9a91SJeremy L Thompson                      CeedContextFieldTypes[field_type]);
250d8dd9a91SJeremy L Thompson   // LCOV_EXCL_STOP
251d8dd9a91SJeremy L Thompson 
252d8dd9a91SJeremy L Thompson   char *data;
253d8dd9a91SJeremy L Thompson   ierr = CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data); CeedChk(ierr);
2543668ca4bSJeremy L Thompson   memcpy(&data[field_label->offset], value, field_label->size);
255d8dd9a91SJeremy L Thompson   ierr = CeedQFunctionContextRestoreData(ctx, &data); CeedChk(ierr);
256d8dd9a91SJeremy L Thompson 
257d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
258d8dd9a91SJeremy L Thompson }
259d8dd9a91SJeremy L Thompson 
260d8dd9a91SJeremy L Thompson /**
26134359f16Sjeremylt   @brief Increment the reference counter for a CeedQFunctionContext
26234359f16Sjeremylt 
26334359f16Sjeremylt   @param ctx  CeedQFunctionContext to increment the reference counter
26434359f16Sjeremylt 
26534359f16Sjeremylt   @return An error code: 0 - success, otherwise - failure
26634359f16Sjeremylt 
26734359f16Sjeremylt   @ref Backend
26834359f16Sjeremylt **/
2699560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) {
27034359f16Sjeremylt   ctx->ref_count++;
27134359f16Sjeremylt   return CEED_ERROR_SUCCESS;
27234359f16Sjeremylt }
27334359f16Sjeremylt 
274777ff853SJeremy L Thompson /// @}
275777ff853SJeremy L Thompson 
276777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
277777ff853SJeremy L Thompson /// CeedQFunctionContext Public API
278777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
279777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser
280777ff853SJeremy L Thompson /// @{
281777ff853SJeremy L Thompson 
282777ff853SJeremy L Thompson /**
283777ff853SJeremy L Thompson   @brief Create a CeedQFunctionContext for storing CeedQFunction user context data
284777ff853SJeremy L Thompson 
285777ff853SJeremy L Thompson   @param ceed      A Ceed object where the CeedQFunctionContext will be created
286777ff853SJeremy L Thompson   @param[out] ctx  Address of the variable where the newly created
287777ff853SJeremy L Thompson                      CeedQFunctionContext will be stored
288777ff853SJeremy L Thompson 
289777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
290777ff853SJeremy L Thompson 
291777ff853SJeremy L Thompson   @ref User
292777ff853SJeremy L Thompson **/
293777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) {
294777ff853SJeremy L Thompson   int ierr;
295777ff853SJeremy L Thompson 
296777ff853SJeremy L Thompson   if (!ceed->QFunctionContextCreate) {
297777ff853SJeremy L Thompson     Ceed delegate;
298777ff853SJeremy L Thompson     ierr = CeedGetObjectDelegate(ceed, &delegate, "Context"); CeedChk(ierr);
299777ff853SJeremy L Thompson 
300777ff853SJeremy L Thompson     if (!delegate)
301777ff853SJeremy L Thompson       // LCOV_EXCL_START
302e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
303e15f9bd0SJeremy L Thompson                        "Backend does not support ContextCreate");
304777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
305777ff853SJeremy L Thompson 
306777ff853SJeremy L Thompson     ierr = CeedQFunctionContextCreate(delegate, ctx); CeedChk(ierr);
307e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
308777ff853SJeremy L Thompson   }
309777ff853SJeremy L Thompson 
310777ff853SJeremy L Thompson   ierr = CeedCalloc(1, ctx); CeedChk(ierr);
311777ff853SJeremy L Thompson   (*ctx)->ceed = ceed;
3129560d06aSjeremylt   ierr = CeedReference(ceed); CeedChk(ierr);
313d1d35e2fSjeremylt   (*ctx)->ref_count = 1;
314777ff853SJeremy L Thompson   ierr = ceed->QFunctionContextCreate(*ctx); CeedChk(ierr);
315e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
316777ff853SJeremy L Thompson }
317777ff853SJeremy L Thompson 
318777ff853SJeremy L Thompson /**
3199560d06aSjeremylt   @brief Copy the pointer to a CeedQFunctionContext. Both pointers should
3209560d06aSjeremylt            be destroyed with `CeedQFunctionContextDestroy()`;
3219560d06aSjeremylt            Note: If `*ctx_copy` is non-NULL, then it is assumed that
3229560d06aSjeremylt            `*ctx_copy` is a pointer to a CeedQFunctionContext. This
3239560d06aSjeremylt            CeedQFunctionContext will be destroyed if `*ctx_copy` is the
3249560d06aSjeremylt            only reference to this CeedQFunctionContext.
3259560d06aSjeremylt 
3269560d06aSjeremylt   @param ctx            CeedQFunctionContext to copy reference to
3279560d06aSjeremylt   @param[out] ctx_copy  Variable to store copied reference
3289560d06aSjeremylt 
3299560d06aSjeremylt   @return An error code: 0 - success, otherwise - failure
3309560d06aSjeremylt 
3319560d06aSjeremylt   @ref User
3329560d06aSjeremylt **/
3339560d06aSjeremylt int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx,
3349560d06aSjeremylt                                       CeedQFunctionContext *ctx_copy) {
3359560d06aSjeremylt   int ierr;
3369560d06aSjeremylt 
3379560d06aSjeremylt   ierr = CeedQFunctionContextReference(ctx); CeedChk(ierr);
3389560d06aSjeremylt   ierr = CeedQFunctionContextDestroy(ctx_copy); CeedChk(ierr);
3399560d06aSjeremylt   *ctx_copy = ctx;
3409560d06aSjeremylt   return CEED_ERROR_SUCCESS;
3419560d06aSjeremylt }
3429560d06aSjeremylt 
3439560d06aSjeremylt /**
344777ff853SJeremy L Thompson   @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated
345777ff853SJeremy L Thompson            data if applicable. The backend may copy values to a different
346777ff853SJeremy L Thompson            memtype, such as during @ref CeedQFunctionApply().
347777ff853SJeremy L Thompson            See also @ref CeedQFunctionContextTakeData().
348777ff853SJeremy L Thompson 
349777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
350d1d35e2fSjeremylt   @param mem_type   Memory type of the data being passed
351d1d35e2fSjeremylt   @param copy_mode  Copy mode for the data
352891038deSjeremylt   @param size       Size of data, in bytes
353777ff853SJeremy L Thompson   @param data       Data to be used
354777ff853SJeremy L Thompson 
355777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
356777ff853SJeremy L Thompson 
357777ff853SJeremy L Thompson   @ref User
358777ff853SJeremy L Thompson **/
359d1d35e2fSjeremylt int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type,
360d1d35e2fSjeremylt                                 CeedCopyMode copy_mode,
361777ff853SJeremy L Thompson                                 size_t size, void *data) {
362777ff853SJeremy L Thompson   int ierr;
363777ff853SJeremy L Thompson 
364777ff853SJeremy L Thompson   if (!ctx->SetData)
365777ff853SJeremy L Thompson     // LCOV_EXCL_START
366e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
367e15f9bd0SJeremy L Thompson                      "Backend does not support ContextSetData");
368777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
369777ff853SJeremy L Thompson 
370777ff853SJeremy L Thompson   if (ctx->state % 2 == 1)
371777ff853SJeremy L Thompson     // LCOV_EXCL_START
372777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
373777ff853SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
374777ff853SJeremy L Thompson                      "access lock is already in use");
375777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
376777ff853SJeremy L Thompson 
377d1d35e2fSjeremylt   ctx->ctx_size = size;
378d1d35e2fSjeremylt   ierr = ctx->SetData(ctx, mem_type, copy_mode, data); CeedChk(ierr);
379777ff853SJeremy L Thompson   ctx->state += 2;
380e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
381777ff853SJeremy L Thompson }
382777ff853SJeremy L Thompson 
383777ff853SJeremy L Thompson /**
384891038deSjeremylt   @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type.
385891038deSjeremylt            The caller is responsible for managing and freeing the memory.
386891038deSjeremylt 
387891038deSjeremylt   @param ctx        CeedQFunctionContext to access
388891038deSjeremylt   @param mem_type   Memory type on which to access the data. If the backend
389891038deSjeremylt                       uses a different memory type, this will perform a copy.
390891038deSjeremylt   @param[out] data  Data on memory type mem_type
391891038deSjeremylt 
392891038deSjeremylt   @return An error code: 0 - success, otherwise - failure
393891038deSjeremylt 
394891038deSjeremylt   @ref User
395891038deSjeremylt **/
396891038deSjeremylt int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type,
397891038deSjeremylt                                  void *data) {
398891038deSjeremylt   int ierr;
399891038deSjeremylt 
4009c774eddSJeremy L Thompson   bool has_valid_data = true;
4019c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr);
4029c774eddSJeremy L Thompson   if (!has_valid_data)
4039c774eddSJeremy L Thompson     // LCOV_EXCL_START
4049c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
4059c774eddSJeremy L Thompson                      "CeedQFunctionContext has no valid data to take, must set data");
4069c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
4079c774eddSJeremy L Thompson 
408891038deSjeremylt   if (!ctx->TakeData)
409891038deSjeremylt     // LCOV_EXCL_START
410891038deSjeremylt     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
411891038deSjeremylt                      "Backend does not support TakeData");
412891038deSjeremylt   // LCOV_EXCL_STOP
413891038deSjeremylt 
414891038deSjeremylt   if (ctx->state % 2 == 1)
415891038deSjeremylt     // LCOV_EXCL_START
416891038deSjeremylt     return CeedError(ctx->ceed, 1,
417891038deSjeremylt                      "Cannot grant CeedQFunctionContext data access, the "
418891038deSjeremylt                      "access lock is already in use");
419891038deSjeremylt   // LCOV_EXCL_STOP
420891038deSjeremylt 
4219c774eddSJeremy L Thompson   bool has_borrowed_data_of_type = true;
4229c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type,
4239c774eddSJeremy L Thompson          &has_borrowed_data_of_type); CeedChk(ierr);
4249c774eddSJeremy L Thompson   if (!has_borrowed_data_of_type)
4259c774eddSJeremy L Thompson     // LCOV_EXCL_START
4269c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
4279c774eddSJeremy L Thompson                      "CeedQFunctionContext has no borowed %s data, "
4289c774eddSJeremy L Thompson                      "must set data with CeedQFunctionContextSetData",
4299c774eddSJeremy L Thompson                      CeedMemTypes[mem_type]);
4309c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
4319c774eddSJeremy L Thompson 
432891038deSjeremylt   void *temp_data = NULL;
433891038deSjeremylt   ierr = ctx->TakeData(ctx, mem_type, &temp_data); CeedChk(ierr);
434891038deSjeremylt   if (data) (*(void **)data) = temp_data;
435891038deSjeremylt   return CEED_ERROR_SUCCESS;
436891038deSjeremylt }
437891038deSjeremylt 
438891038deSjeremylt /**
439777ff853SJeremy L Thompson   @brief Get read/write access to a CeedQFunctionContext via the specified memory type.
440777ff853SJeremy L Thompson            Restore access with @ref CeedQFunctionContextRestoreData().
441777ff853SJeremy L Thompson 
442777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext to access
443d1d35e2fSjeremylt   @param mem_type   Memory type on which to access the data. If the backend
444777ff853SJeremy L Thompson                       uses a different memory type, this will perform a copy.
445d1d35e2fSjeremylt   @param[out] data  Data on memory type mem_type
446777ff853SJeremy L Thompson 
447777ff853SJeremy L Thompson   @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions
448777ff853SJeremy L Thompson     provide access to array pointers in the desired memory space. Pairing
449777ff853SJeremy L Thompson     get/restore allows the Context to track access.
450777ff853SJeremy L Thompson 
451777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
452777ff853SJeremy L Thompson 
453777ff853SJeremy L Thompson   @ref User
454777ff853SJeremy L Thompson **/
455d1d35e2fSjeremylt int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type,
456777ff853SJeremy L Thompson                                 void *data) {
457777ff853SJeremy L Thompson   int ierr;
458777ff853SJeremy L Thompson 
459777ff853SJeremy L Thompson   if (!ctx->GetData)
460777ff853SJeremy L Thompson     // LCOV_EXCL_START
461e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
462e15f9bd0SJeremy L Thompson                      "Backend does not support GetData");
463777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
464777ff853SJeremy L Thompson 
465777ff853SJeremy L Thompson   if (ctx->state % 2 == 1)
466777ff853SJeremy L Thompson     // LCOV_EXCL_START
467777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
468777ff853SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
469777ff853SJeremy L Thompson                      "access lock is already in use");
470777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
471777ff853SJeremy L Thompson 
47228bfd0b7SJeremy L Thompson   if (ctx->num_readers > 0)
47328bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
47428bfd0b7SJeremy L Thompson     return CeedError(ctx->ceed, 1,
47528bfd0b7SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, a "
47628bfd0b7SJeremy L Thompson                      "process has read access");
47728bfd0b7SJeremy L Thompson   // LCOV_EXCL_STOP
47828bfd0b7SJeremy 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);
48828bfd0b7SJeremy L Thompson   ctx->state++;
48928bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
49028bfd0b7SJeremy L Thompson }
49128bfd0b7SJeremy L Thompson 
49228bfd0b7SJeremy L Thompson /**
49328bfd0b7SJeremy L Thompson   @brief Get read only access to a CeedQFunctionContext via the specified memory type.
49428bfd0b7SJeremy L Thompson            Restore access with @ref CeedQFunctionContextRestoreData().
49528bfd0b7SJeremy L Thompson 
49628bfd0b7SJeremy L Thompson   @param ctx        CeedQFunctionContext to access
49728bfd0b7SJeremy L Thompson   @param mem_type   Memory type on which to access the data. If the backend
49828bfd0b7SJeremy L Thompson                       uses a different memory type, this will perform a copy.
49928bfd0b7SJeremy L Thompson   @param[out] data  Data on memory type mem_type
50028bfd0b7SJeremy L Thompson 
50128bfd0b7SJeremy L Thompson   @note The CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead()
50228bfd0b7SJeremy L Thompson     functions provide access to array pointers in the desired memory space. Pairing
50328bfd0b7SJeremy L Thompson     get/restore allows the Context to track access.
50428bfd0b7SJeremy L Thompson 
50528bfd0b7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
50628bfd0b7SJeremy L Thompson 
50728bfd0b7SJeremy L Thompson   @ref User
50828bfd0b7SJeremy L Thompson **/
50928bfd0b7SJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx,
51028bfd0b7SJeremy L Thompson                                     CeedMemType mem_type,
51128bfd0b7SJeremy L Thompson                                     void *data) {
51228bfd0b7SJeremy L Thompson   int ierr;
51328bfd0b7SJeremy L Thompson 
51428bfd0b7SJeremy L Thompson   if (!ctx->GetDataRead)
51528bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
51628bfd0b7SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
51728bfd0b7SJeremy L Thompson                      "Backend does not support GetDataRead");
51828bfd0b7SJeremy L Thompson   // LCOV_EXCL_STOP
51928bfd0b7SJeremy L Thompson 
52028bfd0b7SJeremy L Thompson   if (ctx->state % 2 == 1)
52128bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
52228bfd0b7SJeremy L Thompson     return CeedError(ctx->ceed, 1,
52328bfd0b7SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
52428bfd0b7SJeremy L Thompson                      "access lock is already in use");
52528bfd0b7SJeremy L Thompson   // LCOV_EXCL_STOP
52628bfd0b7SJeremy L Thompson 
52728bfd0b7SJeremy L Thompson   bool has_valid_data = true;
52828bfd0b7SJeremy L Thompson   ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr);
52928bfd0b7SJeremy L Thompson   if (!has_valid_data)
53028bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
53128bfd0b7SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
53228bfd0b7SJeremy L Thompson                      "CeedQFunctionContext has no valid data to get, must set data");
53328bfd0b7SJeremy L Thompson   // LCOV_EXCL_STOP
53428bfd0b7SJeremy L Thompson 
53528bfd0b7SJeremy L Thompson   ierr = ctx->GetDataRead(ctx, mem_type, data); CeedChk(ierr);
53628bfd0b7SJeremy L Thompson   ctx->num_readers++;
537e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
538777ff853SJeremy L Thompson }
539777ff853SJeremy L Thompson 
540777ff853SJeremy L Thompson /**
541777ff853SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetData()
542777ff853SJeremy L Thompson 
543777ff853SJeremy L Thompson   @param ctx   CeedQFunctionContext to restore
544777ff853SJeremy L Thompson   @param data  Data to restore
545777ff853SJeremy L Thompson 
546777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
547777ff853SJeremy L Thompson 
548777ff853SJeremy L Thompson   @ref User
549777ff853SJeremy L Thompson **/
550777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) {
551777ff853SJeremy L Thompson   int ierr;
552777ff853SJeremy L Thompson 
553777ff853SJeremy L Thompson   if (ctx->state % 2 != 1)
554777ff853SJeremy L Thompson     // LCOV_EXCL_START
555777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
556777ff853SJeremy L Thompson                      "Cannot restore CeedQFunctionContext array access, "
557777ff853SJeremy L Thompson                      "access was not granted");
558777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
559777ff853SJeremy L Thompson 
560706efda3SJeremy L Thompson   if (ctx->RestoreData) {
561777ff853SJeremy L Thompson     ierr = ctx->RestoreData(ctx); CeedChk(ierr);
562706efda3SJeremy L Thompson   }
563777ff853SJeremy L Thompson   *(void **)data = NULL;
56428bfd0b7SJeremy L Thompson   ctx->state++;
56528bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
56628bfd0b7SJeremy L Thompson }
56728bfd0b7SJeremy L Thompson 
56828bfd0b7SJeremy L Thompson /**
56928bfd0b7SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead()
57028bfd0b7SJeremy L Thompson 
57128bfd0b7SJeremy L Thompson   @param ctx   CeedQFunctionContext to restore
57228bfd0b7SJeremy L Thompson   @param data  Data to restore
57328bfd0b7SJeremy L Thompson 
57428bfd0b7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
57528bfd0b7SJeremy L Thompson 
57628bfd0b7SJeremy L Thompson   @ref User
57728bfd0b7SJeremy L Thompson **/
57828bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) {
57928bfd0b7SJeremy L Thompson   int ierr;
58028bfd0b7SJeremy L Thompson 
58128bfd0b7SJeremy L Thompson   if (ctx->num_readers == 0)
58228bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
58328bfd0b7SJeremy L Thompson     return CeedError(ctx->ceed, 1,
58428bfd0b7SJeremy L Thompson                      "Cannot restore CeedQFunctionContext array access, "
58528bfd0b7SJeremy L Thompson                      "access was not granted");
58628bfd0b7SJeremy L Thompson   // LCOV_EXCL_STOP
58728bfd0b7SJeremy L Thompson 
58828bfd0b7SJeremy L Thompson   if (ctx->RestoreDataRead) {
58928bfd0b7SJeremy L Thompson     ierr = ctx->RestoreData(ctx); CeedChk(ierr);
59028bfd0b7SJeremy L Thompson   }
59128bfd0b7SJeremy L Thompson   *(void **)data = NULL;
59228bfd0b7SJeremy L Thompson   ctx->num_readers--;
593e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
594777ff853SJeremy L Thompson }
595777ff853SJeremy L Thompson 
596777ff853SJeremy L Thompson /**
597cdf32b93SJeremy L Thompson   @brief Register QFunctionContext a field holding a double precision value
598cdf32b93SJeremy L Thompson 
599cdf32b93SJeremy L Thompson   @param ctx               CeedQFunctionContext
600cdf32b93SJeremy L Thompson   @param field_name        Name of field to register
601cdf32b93SJeremy L Thompson   @param field_offset      Offset of field to register
6027bfe0f0eSJeremy L Thompson   @param num_values        Number of values to register, must be contiguous in memory
603cdf32b93SJeremy L Thompson   @param field_description Description of field, or NULL for none
604cdf32b93SJeremy L Thompson 
605cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
606cdf32b93SJeremy L Thompson 
607cdf32b93SJeremy L Thompson   @ref User
608cdf32b93SJeremy L Thompson **/
609cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx,
610cdf32b93SJeremy L Thompson                                        const char *field_name, size_t field_offset,
6117bfe0f0eSJeremy L Thompson                                        size_t num_values,
612cdf32b93SJeremy L Thompson                                        const char *field_description) {
613cdf32b93SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset,
6147bfe0f0eSJeremy L Thompson          field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double), num_values);
615cdf32b93SJeremy L Thompson }
616cdf32b93SJeremy L Thompson 
617cdf32b93SJeremy L Thompson /**
618cdf32b93SJeremy L Thompson   @brief Register QFunctionContext a field holding a int32 value
619cdf32b93SJeremy L Thompson 
620cdf32b93SJeremy L Thompson   @param ctx               CeedQFunctionContext
621cdf32b93SJeremy L Thompson   @param field_name        Name of field to register
622cdf32b93SJeremy L Thompson   @param field_offset      Offset of field to register
6237bfe0f0eSJeremy L Thompson   @param num_values        Number of values to register, must be contiguous in memory
624cdf32b93SJeremy L Thompson   @param field_description Description of field, or NULL for none
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 CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx,
631cdf32b93SJeremy L Thompson                                       const char *field_name, size_t field_offset,
6327bfe0f0eSJeremy L Thompson                                       size_t num_values,
633cdf32b93SJeremy L Thompson                                       const char *field_description) {
634cdf32b93SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset,
6357bfe0f0eSJeremy L Thompson          field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int), num_values);
636cdf32b93SJeremy L Thompson }
637cdf32b93SJeremy L Thompson 
638cdf32b93SJeremy L Thompson /**
6393668ca4bSJeremy L Thompson   @brief Get labels for all registered QFunctionContext fields
640cdf32b93SJeremy L Thompson 
641cdf32b93SJeremy L Thompson   @param ctx                CeedQFunctionContext
6423668ca4bSJeremy L Thompson   @param[out] field_labels  Variable to hold array of field labels
643cdf32b93SJeremy L Thompson   @param[out] num_fields    Length of field descriptions array
644cdf32b93SJeremy L Thompson 
645cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
646cdf32b93SJeremy L Thompson 
647cdf32b93SJeremy L Thompson   @ref User
648cdf32b93SJeremy L Thompson **/
6493668ca4bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx,
6503668ca4bSJeremy L Thompson     const CeedContextFieldLabel **field_labels, CeedInt *num_fields) {
6513668ca4bSJeremy L Thompson   *field_labels = ctx->field_labels;
652cdf32b93SJeremy L Thompson   *num_fields = ctx->num_fields;
653cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
654cdf32b93SJeremy L Thompson }
655cdf32b93SJeremy L Thompson 
656cdf32b93SJeremy L Thompson /**
6573668ca4bSJeremy L Thompson   @brief Get label for a registered QFunctionContext field, or `NULL` if no
6583668ca4bSJeremy L Thompson            field has been registered with this `field_name`
6593668ca4bSJeremy L Thompson 
6603668ca4bSJeremy L Thompson   @param[in] ctx           CeedQFunctionContext
6613668ca4bSJeremy L Thompson   @param[in] field_name    Name of field to retrieve label
6623668ca4bSJeremy L Thompson   @param[out] field_label  Variable to field label
6633668ca4bSJeremy L Thompson 
6643668ca4bSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
6653668ca4bSJeremy L Thompson 
6663668ca4bSJeremy L Thompson   @ref User
6673668ca4bSJeremy L Thompson **/
6683668ca4bSJeremy L Thompson int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx,
6697bfe0f0eSJeremy L Thompson                                       const char *field_name,
6707bfe0f0eSJeremy L Thompson                                       CeedContextFieldLabel *field_label) {
6713668ca4bSJeremy L Thompson   int ierr;
6723668ca4bSJeremy L Thompson 
6733668ca4bSJeremy L Thompson   CeedInt field_index;
6743668ca4bSJeremy L Thompson   ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index);
6753668ca4bSJeremy L Thompson   CeedChk(ierr);
6763668ca4bSJeremy L Thompson 
6773668ca4bSJeremy L Thompson   if (field_index != -1) {
6783668ca4bSJeremy L Thompson     *field_label = ctx->field_labels[field_index];
6793668ca4bSJeremy L Thompson   } else {
6803668ca4bSJeremy L Thompson     *field_label = NULL;
6813668ca4bSJeremy L Thompson   }
6823668ca4bSJeremy L Thompson 
6833668ca4bSJeremy L Thompson   return CEED_ERROR_SUCCESS;
6843668ca4bSJeremy L Thompson }
6853668ca4bSJeremy L Thompson 
6863668ca4bSJeremy L Thompson /**
6870f86cbe7SJeremy L Thompson   @brief Get the descriptive information about a CeedContextFieldLabel
6880f86cbe7SJeremy L Thompson 
6890f86cbe7SJeremy L Thompson   @param[in] label              CeedContextFieldLabel
6900f86cbe7SJeremy L Thompson   @param[out] field_name        Name of labeled field
6910f86cbe7SJeremy L Thompson   @param[out] field_description Description of field, or NULL for none
6927bfe0f0eSJeremy L Thompson   @param[out] num_values        Number of values registered
6930f86cbe7SJeremy L Thompson   @param[out] field_type        CeedContextFieldType
6940f86cbe7SJeremy L Thompson 
6950f86cbe7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
6960f86cbe7SJeremy L Thompson 
6970f86cbe7SJeremy L Thompson   @ref User
6980f86cbe7SJeremy L Thompson **/
6990f86cbe7SJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label,
7000f86cbe7SJeremy L Thompson                                         const char **field_name,
7010f86cbe7SJeremy L Thompson                                         const char **field_description,
7027bfe0f0eSJeremy L Thompson                                         size_t *num_values,
7030f86cbe7SJeremy L Thompson                                         CeedContextFieldType *field_type) {
7040f86cbe7SJeremy L Thompson   if (field_name) *field_name = label->name;
7050f86cbe7SJeremy L Thompson   if (field_description) *field_description = label->description;
7067bfe0f0eSJeremy L Thompson   if (num_values) *num_values = label->num_values;
7070f86cbe7SJeremy L Thompson   if (field_type) *field_type = label->type;
7080f86cbe7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
7090f86cbe7SJeremy L Thompson }
7100f86cbe7SJeremy L Thompson 
7110f86cbe7SJeremy L Thompson /**
712cdf32b93SJeremy L Thompson   @brief Set QFunctionContext field holding a double precision value
713cdf32b93SJeremy L Thompson 
714cdf32b93SJeremy L Thompson   @param ctx         CeedQFunctionContext
7153668ca4bSJeremy L Thompson   @param field_label Label for field to register
7167bfe0f0eSJeremy L Thompson   @param values      Values to set
717cdf32b93SJeremy L Thompson 
718cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
719cdf32b93SJeremy L Thompson 
720cdf32b93SJeremy L Thompson   @ref User
721cdf32b93SJeremy L Thompson **/
722cdf32b93SJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx,
7237bfe0f0eSJeremy L Thompson                                   CeedContextFieldLabel field_label, double *values) {
724d8dd9a91SJeremy L Thompson   int ierr;
725d8dd9a91SJeremy L Thompson 
7263668ca4bSJeremy L Thompson   if (!field_label)
727d8dd9a91SJeremy L Thompson     // LCOV_EXCL_START
728d8dd9a91SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
7293668ca4bSJeremy L Thompson                      "Invalid field label");
730d8dd9a91SJeremy L Thompson   // LCOV_EXCL_STOP
731d8dd9a91SJeremy L Thompson 
7323668ca4bSJeremy L Thompson   ierr = CeedQFunctionContextSetGeneric(ctx, field_label,
7333668ca4bSJeremy L Thompson                                         CEED_CONTEXT_FIELD_DOUBLE,
7347bfe0f0eSJeremy L Thompson                                         values); CeedChk(ierr);
7353668ca4bSJeremy L Thompson 
736d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
737cdf32b93SJeremy L Thompson }
738cdf32b93SJeremy L Thompson 
739cdf32b93SJeremy L Thompson /**
740d8dd9a91SJeremy L Thompson   @brief Set QFunctionContext field holding an int32 value
741cdf32b93SJeremy L Thompson 
742cdf32b93SJeremy L Thompson   @param ctx         CeedQFunctionContext
7433668ca4bSJeremy L Thompson   @param field_label Label for field to register
7447bfe0f0eSJeremy L Thompson   @param values      Values to set
745cdf32b93SJeremy L Thompson 
746cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
747cdf32b93SJeremy L Thompson 
748cdf32b93SJeremy L Thompson   @ref User
749cdf32b93SJeremy L Thompson **/
750cdf32b93SJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx,
7517bfe0f0eSJeremy L Thompson                                  CeedContextFieldLabel field_label, int *values) {
752d8dd9a91SJeremy L Thompson   int ierr;
753d8dd9a91SJeremy L Thompson 
7543668ca4bSJeremy L Thompson   if (!field_label)
755d8dd9a91SJeremy L Thompson     // LCOV_EXCL_START
756d8dd9a91SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
7573668ca4bSJeremy L Thompson                      "Invalid field label");
758d8dd9a91SJeremy L Thompson   // LCOV_EXCL_STOP
759d8dd9a91SJeremy L Thompson 
7603668ca4bSJeremy L Thompson   ierr = CeedQFunctionContextSetGeneric(ctx, field_label,
7613668ca4bSJeremy L Thompson                                         CEED_CONTEXT_FIELD_INT32,
7627bfe0f0eSJeremy L Thompson                                         values); CeedChk(ierr);
7633668ca4bSJeremy L Thompson 
764d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
765cdf32b93SJeremy L Thompson }
766cdf32b93SJeremy L Thompson 
767cdf32b93SJeremy L Thompson /**
76880a9ef05SNatalie Beams   @brief Get data size for a Context
76980a9ef05SNatalie Beams 
77080a9ef05SNatalie Beams   @param ctx            CeedQFunctionContext
77180a9ef05SNatalie Beams   @param[out] ctx_size  Variable to store size of context data values
77280a9ef05SNatalie Beams 
77380a9ef05SNatalie Beams   @return An error code: 0 - success, otherwise - failure
77480a9ef05SNatalie Beams 
77580a9ef05SNatalie Beams   @ref User
77680a9ef05SNatalie Beams **/
77780a9ef05SNatalie Beams int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx,
77880a9ef05SNatalie Beams                                        size_t *ctx_size) {
77980a9ef05SNatalie Beams   *ctx_size = ctx->ctx_size;
78080a9ef05SNatalie Beams   return CEED_ERROR_SUCCESS;
78180a9ef05SNatalie Beams }
78280a9ef05SNatalie Beams 
78380a9ef05SNatalie Beams 
78480a9ef05SNatalie Beams /**
785777ff853SJeremy L Thompson   @brief View a CeedQFunctionContext
786777ff853SJeremy L Thompson 
787777ff853SJeremy L Thompson   @param[in] ctx     CeedQFunctionContext to view
788777ff853SJeremy L Thompson   @param[in] stream  Filestream to write to
789777ff853SJeremy L Thompson 
790777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
791777ff853SJeremy L Thompson 
792777ff853SJeremy L Thompson   @ref User
793777ff853SJeremy L Thompson **/
794777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) {
795777ff853SJeremy L Thompson   fprintf(stream, "CeedQFunctionContext\n");
796d1d35e2fSjeremylt   fprintf(stream, "  Context Data Size: %ld\n", ctx->ctx_size);
7973668ca4bSJeremy L Thompson   for (CeedInt i = 0; i < ctx->num_fields; i++) {
7983668ca4bSJeremy L Thompson     // LCOV_EXCL_START
7993668ca4bSJeremy L Thompson     fprintf(stream, "  Labeled %s field: %s\n",
8003668ca4bSJeremy L Thompson             CeedContextFieldTypes[ctx->field_labels[i]->type],
8013668ca4bSJeremy L Thompson             ctx->field_labels[i]->name);
8023668ca4bSJeremy L Thompson     // LCOV_EXCL_STOP
8033668ca4bSJeremy L Thompson   }
804e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
805777ff853SJeremy L Thompson }
806777ff853SJeremy L Thompson 
807777ff853SJeremy L Thompson /**
808777ff853SJeremy L Thompson   @brief Destroy a CeedQFunctionContext
809777ff853SJeremy L Thompson 
810777ff853SJeremy L Thompson   @param ctx  CeedQFunctionContext to destroy
811777ff853SJeremy L Thompson 
812777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
813777ff853SJeremy L Thompson 
814777ff853SJeremy L Thompson   @ref User
815777ff853SJeremy L Thompson **/
816777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) {
817777ff853SJeremy L Thompson   int ierr;
818777ff853SJeremy L Thompson 
819d1d35e2fSjeremylt   if (!*ctx || --(*ctx)->ref_count > 0)
820e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
821777ff853SJeremy L Thompson 
822777ff853SJeremy L Thompson   if ((*ctx) && ((*ctx)->state % 2) == 1)
823777ff853SJeremy L Thompson     // LCOV_EXCL_START
824777ff853SJeremy L Thompson     return CeedError((*ctx)->ceed, 1,
825777ff853SJeremy L Thompson                      "Cannot destroy CeedQFunctionContext, the access "
826777ff853SJeremy L Thompson                      "lock is in use");
827777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
828777ff853SJeremy L Thompson 
829777ff853SJeremy L Thompson   if ((*ctx)->Destroy) {
830777ff853SJeremy L Thompson     ierr = (*ctx)->Destroy(*ctx); CeedChk(ierr);
831777ff853SJeremy L Thompson   }
832cdf32b93SJeremy L Thompson   for (CeedInt i=0; i<(*ctx)->num_fields; i++) {
8333668ca4bSJeremy L Thompson     ierr = CeedFree(&(*ctx)->field_labels[i]->name); CeedChk(ierr);
8343668ca4bSJeremy L Thompson     ierr = CeedFree(&(*ctx)->field_labels[i]->description); CeedChk(ierr);
8353668ca4bSJeremy L Thompson     ierr = CeedFree(&(*ctx)->field_labels[i]); CeedChk(ierr);
836cdf32b93SJeremy L Thompson   }
8373668ca4bSJeremy L Thompson   ierr = CeedFree(&(*ctx)->field_labels); CeedChk(ierr);
838777ff853SJeremy L Thompson   ierr = CeedDestroy(&(*ctx)->ceed); CeedChk(ierr);
839777ff853SJeremy L Thompson   ierr = CeedFree(ctx); CeedChk(ierr);
840cdf32b93SJeremy L Thompson 
841e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
842777ff853SJeremy L Thompson }
843777ff853SJeremy L Thompson 
844777ff853SJeremy L Thompson /// @}
845