xref: /libCEED/interface/ceed-qfunctioncontext.c (revision 28bfd0b742d5bb98b1c0887e682aa0983923c5c6)
1777ff853SJeremy L Thompson // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2777ff853SJeremy L Thompson // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3777ff853SJeremy L Thompson // reserved. See files LICENSE and NOTICE for details.
4777ff853SJeremy L Thompson //
5777ff853SJeremy L Thompson // This file is part of CEED, a collection of benchmarks, miniapps, software
6777ff853SJeremy L Thompson // libraries and APIs for efficient high-order finite element and spectral
7777ff853SJeremy L Thompson // element discretizations for exascale applications. For more information and
8777ff853SJeremy L Thompson // source code availability see http://github.com/ceed.
9777ff853SJeremy L Thompson //
10777ff853SJeremy L Thompson // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11777ff853SJeremy L Thompson // a collaborative effort of two U.S. Department of Energy organizations (Office
12777ff853SJeremy L Thompson // of Science and the National Nuclear Security Administration) responsible for
13777ff853SJeremy L Thompson // the planning and preparation of a capable exascale ecosystem, including
14777ff853SJeremy L Thompson // software, applications, hardware, advanced system engineering and early
15777ff853SJeremy L Thompson // testbed platforms, in support of the nation's exascale computing imperative.
16777ff853SJeremy L Thompson 
17ec3da8bcSJed Brown #include <ceed/ceed.h>
18ec3da8bcSJed Brown #include <ceed/backend.h>
193d576824SJeremy L Thompson #include <ceed-impl.h>
203d576824SJeremy L Thompson #include <stdint.h>
213d576824SJeremy L Thompson #include <stdio.h>
22cdf32b93SJeremy L Thompson #include <string.h>
23777ff853SJeremy L Thompson 
24777ff853SJeremy L Thompson /// @file
25777ff853SJeremy L Thompson /// Implementation of public CeedQFunctionContext interfaces
26777ff853SJeremy L Thompson 
27777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
28cdf32b93SJeremy L Thompson /// CeedQFunctionContext Library Internal Functions
29cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
30cdf32b93SJeremy L Thompson /// @addtogroup CeedQFunctionDeveloper
31cdf32b93SJeremy L Thompson /// @{
32cdf32b93SJeremy L Thompson 
33cdf32b93SJeremy L Thompson /**
34cdf32b93SJeremy L Thompson   @brief Get index for QFunctionContext field
35cdf32b93SJeremy L Thompson 
36cdf32b93SJeremy L Thompson   @param ctx         CeedQFunctionContext
37cdf32b93SJeremy L Thompson   @param field_name  Name of field
38cdf32b93SJeremy L Thompson   @param field_index Index of field, or -1 if field is not registered
39cdf32b93SJeremy L Thompson 
40cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
41cdf32b93SJeremy L Thompson 
42cdf32b93SJeremy L Thompson   @ref Developer
43cdf32b93SJeremy L Thompson **/
44cdf32b93SJeremy L Thompson int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx,
45cdf32b93SJeremy L Thompson                                       const char *field_name, CeedInt *field_index) {
46cdf32b93SJeremy L Thompson   *field_index = -1;
47cdf32b93SJeremy L Thompson   for (CeedInt i=0; i<ctx->num_fields; i++)
483668ca4bSJeremy L Thompson     if (!strcmp(ctx->field_labels[i]->name, field_name))
49cdf32b93SJeremy L Thompson       *field_index = i;
50cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
51cdf32b93SJeremy L Thompson }
52cdf32b93SJeremy L Thompson 
53cdf32b93SJeremy L Thompson /**
54cdf32b93SJeremy L Thompson   @brief Common function for registering QFunctionContext fields
55cdf32b93SJeremy L Thompson 
56cdf32b93SJeremy L Thompson   @param ctx               CeedQFunctionContext
57cdf32b93SJeremy L Thompson   @param field_name        Name of field to register
58cdf32b93SJeremy L Thompson   @param field_offset      Offset of field to register
59cdf32b93SJeremy L Thompson   @param field_description Description of field, or NULL for none
60cdf32b93SJeremy L Thompson   @param field_type        Field data type, such as double or int32
61cdf32b93SJeremy L Thompson   @param field_size        Size of field, in bytes
627bfe0f0eSJeremy L Thompson   @param num_values        Number of values to register, must be contiguous in memory
63cdf32b93SJeremy L Thompson 
64cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
65cdf32b93SJeremy L Thompson 
66cdf32b93SJeremy L Thompson   @ref Developer
67cdf32b93SJeremy L Thompson **/
68cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx,
69cdf32b93SJeremy L Thompson                                         const char *field_name, size_t field_offset,
70cdf32b93SJeremy L Thompson                                         const char *field_description,
71cdf32b93SJeremy L Thompson                                         CeedContextFieldType field_type,
727bfe0f0eSJeremy L Thompson                                         size_t field_size, size_t num_values) {
73cdf32b93SJeremy L Thompson   int ierr;
74cdf32b93SJeremy L Thompson 
75cdf32b93SJeremy L Thompson   // Check for duplicate
76cdf32b93SJeremy L Thompson   CeedInt field_index = -1;
77cdf32b93SJeremy L Thompson   ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index);
78cdf32b93SJeremy L Thompson   CeedChk(ierr);
79cdf32b93SJeremy L Thompson   if (field_index != -1)
80cdf32b93SJeremy L Thompson     // LCOV_EXCL_START
81cdf32b93SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
82cdf32b93SJeremy L Thompson                      "QFunctionContext field with name \"%s\" already registered",
83cdf32b93SJeremy L Thompson                      field_name);
84cdf32b93SJeremy L Thompson   // LCOV_EXCL_STOP
85cdf32b93SJeremy L Thompson 
86cdf32b93SJeremy L Thompson   // Allocate space for field data
87cdf32b93SJeremy L Thompson   if (ctx->num_fields == 0) {
883668ca4bSJeremy L Thompson     ierr = CeedCalloc(1, &ctx->field_labels); CeedChk(ierr);
89cdf32b93SJeremy L Thompson     ctx->max_fields = 1;
90cdf32b93SJeremy L Thompson   } else if (ctx->num_fields == ctx->max_fields) {
913668ca4bSJeremy L Thompson     ierr = CeedRealloc(2*ctx->max_fields, &ctx->field_labels);
92cdf32b93SJeremy L Thompson     CeedChk(ierr);
93cdf32b93SJeremy L Thompson     ctx->max_fields *= 2;
94cdf32b93SJeremy L Thompson   }
953668ca4bSJeremy L Thompson   ierr = CeedCalloc(1, &ctx->field_labels[ctx->num_fields]); CeedChk(ierr);
96cdf32b93SJeremy L Thompson 
97cdf32b93SJeremy L Thompson   // Copy field data
98f7e22acaSJeremy L Thompson   ierr = CeedStringAllocCopy(field_name,
993668ca4bSJeremy L Thompson                              (char **)&ctx->field_labels[ctx->num_fields]->name);
100f7e22acaSJeremy L Thompson   CeedChk(ierr);
101f7e22acaSJeremy L Thompson   ierr = CeedStringAllocCopy(field_description,
1023668ca4bSJeremy L Thompson                              (char **)&ctx->field_labels[ctx->num_fields]->description);
103f7e22acaSJeremy L Thompson   CeedChk(ierr);
1043668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->type = field_type;
1053668ca4bSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->offset = field_offset;
1067bfe0f0eSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->size = field_size * num_values;
1077bfe0f0eSJeremy L Thompson   ctx->field_labels[ctx->num_fields]->num_values = num_values;
108cdf32b93SJeremy L Thompson   ctx->num_fields++;
109cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
110cdf32b93SJeremy L Thompson }
111cdf32b93SJeremy L Thompson 
112cdf32b93SJeremy L Thompson /// @}
113cdf32b93SJeremy L Thompson 
114cdf32b93SJeremy L Thompson /// ----------------------------------------------------------------------------
115777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API
116777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
117777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend
118777ff853SJeremy L Thompson /// @{
119777ff853SJeremy L Thompson 
120777ff853SJeremy L Thompson /**
121777ff853SJeremy L Thompson   @brief Get the Ceed associated with a CeedQFunctionContext
122777ff853SJeremy L Thompson 
123777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
124777ff853SJeremy L Thompson   @param[out] ceed  Variable to store Ceed
125777ff853SJeremy L Thompson 
126777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
127777ff853SJeremy L Thompson 
128777ff853SJeremy L Thompson   @ref Backend
129777ff853SJeremy L Thompson **/
130777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) {
131777ff853SJeremy L Thompson   *ceed = ctx->ceed;
132e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
133777ff853SJeremy L Thompson }
134777ff853SJeremy L Thompson 
135777ff853SJeremy L Thompson /**
1369c774eddSJeremy L Thompson   @brief Check for valid data in a CeedQFunctionContext
1379c774eddSJeremy L Thompson 
1389c774eddSJeremy L Thompson   @param ctx                  CeedQFunctionContext to check validity
1399c774eddSJeremy L Thompson   @param[out] has_valid_data  Variable to store validity
1409c774eddSJeremy L Thompson 
1419c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1429c774eddSJeremy L Thompson 
1439c774eddSJeremy L Thompson   @ref Backend
1449c774eddSJeremy L Thompson **/
1459c774eddSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx,
1469c774eddSJeremy L Thompson                                      bool *has_valid_data) {
1479c774eddSJeremy L Thompson   int ierr;
1489c774eddSJeremy L Thompson 
1499c774eddSJeremy L Thompson   if (!ctx->HasValidData)
1509c774eddSJeremy L Thompson     // LCOV_EXCL_START
1519c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
1529c774eddSJeremy L Thompson                      "Backend does not support HasValidData");
1539c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
1549c774eddSJeremy L Thompson 
1559c774eddSJeremy L Thompson   ierr = ctx->HasValidData(ctx, has_valid_data); CeedChk(ierr);
1569c774eddSJeremy L Thompson 
1579c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1589c774eddSJeremy L Thompson }
1599c774eddSJeremy L Thompson 
1609c774eddSJeremy L Thompson /**
1619c774eddSJeremy L Thompson   @brief Check for borrowed data of a specific CeedMemType in a
1629c774eddSJeremy L Thompson            CeedQFunctionContext
1639c774eddSJeremy L Thompson 
1649c774eddSJeremy L Thompson   @param ctx                             CeedQFunctionContext to check
1659c774eddSJeremy L Thompson   @param mem_type                        Memory type to check
1669c774eddSJeremy L Thompson   @param[out] has_borrowed_data_of_type  Variable to store result
1679c774eddSJeremy L Thompson 
1689c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1699c774eddSJeremy L Thompson 
1709c774eddSJeremy L Thompson   @ref Backend
1719c774eddSJeremy L Thompson **/
1729c774eddSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx,
1739c774eddSJeremy L Thompson     CeedMemType mem_type, bool *has_borrowed_data_of_type) {
1749c774eddSJeremy L Thompson   int ierr;
1759c774eddSJeremy L Thompson 
1769c774eddSJeremy L Thompson   if (!ctx->HasBorrowedDataOfType)
1779c774eddSJeremy L Thompson     // LCOV_EXCL_START
1789c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
1799c774eddSJeremy L Thompson                      "Backend does not support HasBorrowedDataOfType");
1809c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
1819c774eddSJeremy L Thompson 
1829c774eddSJeremy L Thompson   ierr = ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type);
1839c774eddSJeremy L Thompson   CeedChk(ierr);
1849c774eddSJeremy L Thompson 
1859c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
1869c774eddSJeremy L Thompson }
1879c774eddSJeremy L Thompson 
1889c774eddSJeremy L Thompson /**
189777ff853SJeremy L Thompson   @brief Get the state of a CeedQFunctionContext
190777ff853SJeremy L Thompson 
191777ff853SJeremy L Thompson   @param ctx         CeedQFunctionContext to retrieve state
192777ff853SJeremy L Thompson   @param[out] state  Variable to store state
193777ff853SJeremy L Thompson 
194777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
195777ff853SJeremy L Thompson 
196777ff853SJeremy L Thompson   @ref Backend
197777ff853SJeremy L Thompson **/
198777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) {
199777ff853SJeremy L Thompson   *state = ctx->state;
200e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
201777ff853SJeremy L Thompson }
202777ff853SJeremy L Thompson 
203777ff853SJeremy L Thompson /**
204777ff853SJeremy L Thompson   @brief Get backend data of a CeedQFunctionContext
205777ff853SJeremy L Thompson 
206777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
207777ff853SJeremy L Thompson   @param[out] data  Variable to store data
208777ff853SJeremy L Thompson 
209777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
210777ff853SJeremy L Thompson 
211777ff853SJeremy L Thompson   @ref Backend
212777ff853SJeremy L Thompson **/
213777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) {
214777ff853SJeremy L Thompson   *(void **)data = ctx->data;
215e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
216777ff853SJeremy L Thompson }
217777ff853SJeremy L Thompson 
218777ff853SJeremy L Thompson /**
219777ff853SJeremy L Thompson   @brief Set backend data of a CeedQFunctionContext
220777ff853SJeremy L Thompson 
221777ff853SJeremy L Thompson   @param[out] ctx  CeedQFunctionContext
222777ff853SJeremy L Thompson   @param data      Data to set
223777ff853SJeremy L Thompson 
224777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
225777ff853SJeremy L Thompson 
226777ff853SJeremy L Thompson   @ref Backend
227777ff853SJeremy L Thompson **/
228777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) {
229777ff853SJeremy L Thompson   ctx->data = data;
230e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
231777ff853SJeremy L Thompson }
232777ff853SJeremy L Thompson 
23334359f16Sjeremylt /**
234d8dd9a91SJeremy L Thompson   @brief Set QFunctionContext field
235d8dd9a91SJeremy L Thompson 
236d8dd9a91SJeremy L Thompson   @param ctx         CeedQFunctionContext
2373668ca4bSJeremy L Thompson   @param field_label Label of field to set
238d8dd9a91SJeremy L Thompson   @param field_type  Type of field to set
239d8dd9a91SJeremy L Thompson   @param value       Value to set
240d8dd9a91SJeremy L Thompson 
241d8dd9a91SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
242d8dd9a91SJeremy L Thompson 
243d8dd9a91SJeremy L Thompson   @ref User
244d8dd9a91SJeremy L Thompson **/
245d8dd9a91SJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx,
2463668ca4bSJeremy L Thompson                                    CeedContextFieldLabel field_label,
247d8dd9a91SJeremy L Thompson                                    CeedContextFieldType field_type,
2483668ca4bSJeremy L Thompson                                    void *value) {
249d8dd9a91SJeremy L Thompson   int ierr;
250d8dd9a91SJeremy L Thompson 
2513668ca4bSJeremy L Thompson   // Check field type
2523668ca4bSJeremy L Thompson   if (field_label->type != field_type)
253d8dd9a91SJeremy L Thompson     // LCOV_EXCL_START
254d8dd9a91SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
255d8dd9a91SJeremy L Thompson                      "QFunctionContext field with name \"%s\" registered as %s, "
2563668ca4bSJeremy L Thompson                      "not registered as %s", field_label->name,
2573668ca4bSJeremy L Thompson                      CeedContextFieldTypes[field_label->type],
258d8dd9a91SJeremy L Thompson                      CeedContextFieldTypes[field_type]);
259d8dd9a91SJeremy L Thompson   // LCOV_EXCL_STOP
260d8dd9a91SJeremy L Thompson 
261d8dd9a91SJeremy L Thompson   char *data;
262d8dd9a91SJeremy L Thompson   ierr = CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data); CeedChk(ierr);
2633668ca4bSJeremy L Thompson   memcpy(&data[field_label->offset], value, field_label->size);
264d8dd9a91SJeremy L Thompson   ierr = CeedQFunctionContextRestoreData(ctx, &data); CeedChk(ierr);
265d8dd9a91SJeremy L Thompson 
266d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
267d8dd9a91SJeremy L Thompson }
268d8dd9a91SJeremy L Thompson 
269d8dd9a91SJeremy L Thompson /**
27034359f16Sjeremylt   @brief Increment the reference counter for a CeedQFunctionContext
27134359f16Sjeremylt 
27234359f16Sjeremylt   @param ctx  CeedQFunctionContext to increment the reference counter
27334359f16Sjeremylt 
27434359f16Sjeremylt   @return An error code: 0 - success, otherwise - failure
27534359f16Sjeremylt 
27634359f16Sjeremylt   @ref Backend
27734359f16Sjeremylt **/
2789560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) {
27934359f16Sjeremylt   ctx->ref_count++;
28034359f16Sjeremylt   return CEED_ERROR_SUCCESS;
28134359f16Sjeremylt }
28234359f16Sjeremylt 
283777ff853SJeremy L Thompson /// @}
284777ff853SJeremy L Thompson 
285777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
286777ff853SJeremy L Thompson /// CeedQFunctionContext Public API
287777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
288777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser
289777ff853SJeremy L Thompson /// @{
290777ff853SJeremy L Thompson 
291777ff853SJeremy L Thompson /**
292777ff853SJeremy L Thompson   @brief Create a CeedQFunctionContext for storing CeedQFunction user context data
293777ff853SJeremy L Thompson 
294777ff853SJeremy L Thompson   @param ceed      A Ceed object where the CeedQFunctionContext will be created
295777ff853SJeremy L Thompson   @param[out] ctx  Address of the variable where the newly created
296777ff853SJeremy L Thompson                      CeedQFunctionContext will be stored
297777ff853SJeremy L Thompson 
298777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
299777ff853SJeremy L Thompson 
300777ff853SJeremy L Thompson   @ref User
301777ff853SJeremy L Thompson **/
302777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) {
303777ff853SJeremy L Thompson   int ierr;
304777ff853SJeremy L Thompson 
305777ff853SJeremy L Thompson   if (!ceed->QFunctionContextCreate) {
306777ff853SJeremy L Thompson     Ceed delegate;
307777ff853SJeremy L Thompson     ierr = CeedGetObjectDelegate(ceed, &delegate, "Context"); CeedChk(ierr);
308777ff853SJeremy L Thompson 
309777ff853SJeremy L Thompson     if (!delegate)
310777ff853SJeremy L Thompson       // LCOV_EXCL_START
311e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
312e15f9bd0SJeremy L Thompson                        "Backend does not support ContextCreate");
313777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
314777ff853SJeremy L Thompson 
315777ff853SJeremy L Thompson     ierr = CeedQFunctionContextCreate(delegate, ctx); CeedChk(ierr);
316e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
317777ff853SJeremy L Thompson   }
318777ff853SJeremy L Thompson 
319777ff853SJeremy L Thompson   ierr = CeedCalloc(1, ctx); CeedChk(ierr);
320777ff853SJeremy L Thompson   (*ctx)->ceed = ceed;
3219560d06aSjeremylt   ierr = CeedReference(ceed); CeedChk(ierr);
322d1d35e2fSjeremylt   (*ctx)->ref_count = 1;
323777ff853SJeremy L Thompson   ierr = ceed->QFunctionContextCreate(*ctx); CeedChk(ierr);
324e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
325777ff853SJeremy L Thompson }
326777ff853SJeremy L Thompson 
327777ff853SJeremy L Thompson /**
3289560d06aSjeremylt   @brief Copy the pointer to a CeedQFunctionContext. Both pointers should
3299560d06aSjeremylt            be destroyed with `CeedQFunctionContextDestroy()`;
3309560d06aSjeremylt            Note: If `*ctx_copy` is non-NULL, then it is assumed that
3319560d06aSjeremylt            `*ctx_copy` is a pointer to a CeedQFunctionContext. This
3329560d06aSjeremylt            CeedQFunctionContext will be destroyed if `*ctx_copy` is the
3339560d06aSjeremylt            only reference to this CeedQFunctionContext.
3349560d06aSjeremylt 
3359560d06aSjeremylt   @param ctx            CeedQFunctionContext to copy reference to
3369560d06aSjeremylt   @param[out] ctx_copy  Variable to store copied reference
3379560d06aSjeremylt 
3389560d06aSjeremylt   @return An error code: 0 - success, otherwise - failure
3399560d06aSjeremylt 
3409560d06aSjeremylt   @ref User
3419560d06aSjeremylt **/
3429560d06aSjeremylt int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx,
3439560d06aSjeremylt                                       CeedQFunctionContext *ctx_copy) {
3449560d06aSjeremylt   int ierr;
3459560d06aSjeremylt 
3469560d06aSjeremylt   ierr = CeedQFunctionContextReference(ctx); CeedChk(ierr);
3479560d06aSjeremylt   ierr = CeedQFunctionContextDestroy(ctx_copy); CeedChk(ierr);
3489560d06aSjeremylt   *ctx_copy = ctx;
3499560d06aSjeremylt   return CEED_ERROR_SUCCESS;
3509560d06aSjeremylt }
3519560d06aSjeremylt 
3529560d06aSjeremylt /**
353777ff853SJeremy L Thompson   @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated
354777ff853SJeremy L Thompson            data if applicable. The backend may copy values to a different
355777ff853SJeremy L Thompson            memtype, such as during @ref CeedQFunctionApply().
356777ff853SJeremy L Thompson            See also @ref CeedQFunctionContextTakeData().
357777ff853SJeremy L Thompson 
358777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
359d1d35e2fSjeremylt   @param mem_type   Memory type of the data being passed
360d1d35e2fSjeremylt   @param copy_mode  Copy mode for the data
361891038deSjeremylt   @param size       Size of data, in bytes
362777ff853SJeremy L Thompson   @param data       Data to be used
363777ff853SJeremy L Thompson 
364777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
365777ff853SJeremy L Thompson 
366777ff853SJeremy L Thompson   @ref User
367777ff853SJeremy L Thompson **/
368d1d35e2fSjeremylt int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type,
369d1d35e2fSjeremylt                                 CeedCopyMode copy_mode,
370777ff853SJeremy L Thompson                                 size_t size, void *data) {
371777ff853SJeremy L Thompson   int ierr;
372777ff853SJeremy L Thompson 
373777ff853SJeremy L Thompson   if (!ctx->SetData)
374777ff853SJeremy L Thompson     // LCOV_EXCL_START
375e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
376e15f9bd0SJeremy L Thompson                      "Backend does not support ContextSetData");
377777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
378777ff853SJeremy L Thompson 
379777ff853SJeremy L Thompson   if (ctx->state % 2 == 1)
380777ff853SJeremy L Thompson     // LCOV_EXCL_START
381777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
382777ff853SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
383777ff853SJeremy L Thompson                      "access lock is already in use");
384777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
385777ff853SJeremy L Thompson 
386d1d35e2fSjeremylt   ctx->ctx_size = size;
387d1d35e2fSjeremylt   ierr = ctx->SetData(ctx, mem_type, copy_mode, data); CeedChk(ierr);
388777ff853SJeremy L Thompson   ctx->state += 2;
389e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
390777ff853SJeremy L Thompson }
391777ff853SJeremy L Thompson 
392777ff853SJeremy L Thompson /**
393891038deSjeremylt   @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type.
394891038deSjeremylt            The caller is responsible for managing and freeing the memory.
395891038deSjeremylt 
396891038deSjeremylt   @param ctx        CeedQFunctionContext to access
397891038deSjeremylt   @param mem_type   Memory type on which to access the data. If the backend
398891038deSjeremylt                       uses a different memory type, this will perform a copy.
399891038deSjeremylt   @param[out] data  Data on memory type mem_type
400891038deSjeremylt 
401891038deSjeremylt   @return An error code: 0 - success, otherwise - failure
402891038deSjeremylt 
403891038deSjeremylt   @ref User
404891038deSjeremylt **/
405891038deSjeremylt int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type,
406891038deSjeremylt                                  void *data) {
407891038deSjeremylt   int ierr;
408891038deSjeremylt 
4099c774eddSJeremy L Thompson   bool has_valid_data = true;
4109c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr);
4119c774eddSJeremy L Thompson   if (!has_valid_data)
4129c774eddSJeremy L Thompson     // LCOV_EXCL_START
4139c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
4149c774eddSJeremy L Thompson                      "CeedQFunctionContext has no valid data to take, must set data");
4159c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
4169c774eddSJeremy L Thompson 
417891038deSjeremylt   if (!ctx->TakeData)
418891038deSjeremylt     // LCOV_EXCL_START
419891038deSjeremylt     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
420891038deSjeremylt                      "Backend does not support TakeData");
421891038deSjeremylt   // LCOV_EXCL_STOP
422891038deSjeremylt 
423891038deSjeremylt   if (ctx->state % 2 == 1)
424891038deSjeremylt     // LCOV_EXCL_START
425891038deSjeremylt     return CeedError(ctx->ceed, 1,
426891038deSjeremylt                      "Cannot grant CeedQFunctionContext data access, the "
427891038deSjeremylt                      "access lock is already in use");
428891038deSjeremylt   // LCOV_EXCL_STOP
429891038deSjeremylt 
4309c774eddSJeremy L Thompson   bool has_borrowed_data_of_type = true;
4319c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type,
4329c774eddSJeremy L Thompson          &has_borrowed_data_of_type); CeedChk(ierr);
4339c774eddSJeremy L Thompson   if (!has_borrowed_data_of_type)
4349c774eddSJeremy L Thompson     // LCOV_EXCL_START
4359c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
4369c774eddSJeremy L Thompson                      "CeedQFunctionContext has no borowed %s data, "
4379c774eddSJeremy L Thompson                      "must set data with CeedQFunctionContextSetData",
4389c774eddSJeremy L Thompson                      CeedMemTypes[mem_type]);
4399c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
4409c774eddSJeremy L Thompson 
441891038deSjeremylt   void *temp_data = NULL;
442891038deSjeremylt   ierr = ctx->TakeData(ctx, mem_type, &temp_data); CeedChk(ierr);
443891038deSjeremylt   if (data) (*(void **)data) = temp_data;
444891038deSjeremylt   return CEED_ERROR_SUCCESS;
445891038deSjeremylt }
446891038deSjeremylt 
447891038deSjeremylt /**
448777ff853SJeremy L Thompson   @brief Get read/write access to a CeedQFunctionContext via the specified memory type.
449777ff853SJeremy L Thompson            Restore access with @ref CeedQFunctionContextRestoreData().
450777ff853SJeremy L Thompson 
451777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext to access
452d1d35e2fSjeremylt   @param mem_type   Memory type on which to access the data. If the backend
453777ff853SJeremy L Thompson                       uses a different memory type, this will perform a copy.
454d1d35e2fSjeremylt   @param[out] data  Data on memory type mem_type
455777ff853SJeremy L Thompson 
456777ff853SJeremy L Thompson   @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions
457777ff853SJeremy L Thompson     provide access to array pointers in the desired memory space. Pairing
458777ff853SJeremy L Thompson     get/restore allows the Context to track access.
459777ff853SJeremy L Thompson 
460777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
461777ff853SJeremy L Thompson 
462777ff853SJeremy L Thompson   @ref User
463777ff853SJeremy L Thompson **/
464d1d35e2fSjeremylt int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type,
465777ff853SJeremy L Thompson                                 void *data) {
466777ff853SJeremy L Thompson   int ierr;
467777ff853SJeremy L Thompson 
468777ff853SJeremy L Thompson   if (!ctx->GetData)
469777ff853SJeremy L Thompson     // LCOV_EXCL_START
470e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
471e15f9bd0SJeremy L Thompson                      "Backend does not support GetData");
472777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
473777ff853SJeremy L Thompson 
474777ff853SJeremy L Thompson   if (ctx->state % 2 == 1)
475777ff853SJeremy L Thompson     // LCOV_EXCL_START
476777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
477777ff853SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
478777ff853SJeremy L Thompson                      "access lock is already in use");
479777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
480777ff853SJeremy L Thompson 
481*28bfd0b7SJeremy L Thompson   if (ctx->num_readers > 0)
482*28bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
483*28bfd0b7SJeremy L Thompson     return CeedError(ctx->ceed, 1,
484*28bfd0b7SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, a "
485*28bfd0b7SJeremy L Thompson                      "process has read access");
486*28bfd0b7SJeremy L Thompson   // LCOV_EXCL_STOP
487*28bfd0b7SJeremy L Thompson 
4889c774eddSJeremy L Thompson   bool has_valid_data = true;
4899c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr);
4909c774eddSJeremy L Thompson   if (!has_valid_data)
4919c774eddSJeremy L Thompson     // LCOV_EXCL_START
4929c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
4939c774eddSJeremy L Thompson                      "CeedQFunctionContext has no valid data to get, must set data");
4949c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
4959c774eddSJeremy L Thompson 
496d1d35e2fSjeremylt   ierr = ctx->GetData(ctx, mem_type, data); CeedChk(ierr);
497*28bfd0b7SJeremy L Thompson   ctx->state++;
498*28bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
499*28bfd0b7SJeremy L Thompson }
500*28bfd0b7SJeremy L Thompson 
501*28bfd0b7SJeremy L Thompson /**
502*28bfd0b7SJeremy L Thompson   @brief Get read only access to a CeedQFunctionContext via the specified memory type.
503*28bfd0b7SJeremy L Thompson            Restore access with @ref CeedQFunctionContextRestoreData().
504*28bfd0b7SJeremy L Thompson 
505*28bfd0b7SJeremy L Thompson   @param ctx        CeedQFunctionContext to access
506*28bfd0b7SJeremy L Thompson   @param mem_type   Memory type on which to access the data. If the backend
507*28bfd0b7SJeremy L Thompson                       uses a different memory type, this will perform a copy.
508*28bfd0b7SJeremy L Thompson   @param[out] data  Data on memory type mem_type
509*28bfd0b7SJeremy L Thompson 
510*28bfd0b7SJeremy L Thompson   @note The CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead()
511*28bfd0b7SJeremy L Thompson     functions provide access to array pointers in the desired memory space. Pairing
512*28bfd0b7SJeremy L Thompson     get/restore allows the Context to track access.
513*28bfd0b7SJeremy L Thompson 
514*28bfd0b7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
515*28bfd0b7SJeremy L Thompson 
516*28bfd0b7SJeremy L Thompson   @ref User
517*28bfd0b7SJeremy L Thompson **/
518*28bfd0b7SJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx,
519*28bfd0b7SJeremy L Thompson                                     CeedMemType mem_type,
520*28bfd0b7SJeremy L Thompson                                     void *data) {
521*28bfd0b7SJeremy L Thompson   int ierr;
522*28bfd0b7SJeremy L Thompson 
523*28bfd0b7SJeremy L Thompson   if (!ctx->GetDataRead)
524*28bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
525*28bfd0b7SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
526*28bfd0b7SJeremy L Thompson                      "Backend does not support GetDataRead");
527*28bfd0b7SJeremy L Thompson   // LCOV_EXCL_STOP
528*28bfd0b7SJeremy L Thompson 
529*28bfd0b7SJeremy L Thompson   if (ctx->state % 2 == 1)
530*28bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
531*28bfd0b7SJeremy L Thompson     return CeedError(ctx->ceed, 1,
532*28bfd0b7SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
533*28bfd0b7SJeremy L Thompson                      "access lock is already in use");
534*28bfd0b7SJeremy L Thompson   // LCOV_EXCL_STOP
535*28bfd0b7SJeremy L Thompson 
536*28bfd0b7SJeremy L Thompson   bool has_valid_data = true;
537*28bfd0b7SJeremy L Thompson   ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr);
538*28bfd0b7SJeremy L Thompson   if (!has_valid_data)
539*28bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
540*28bfd0b7SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
541*28bfd0b7SJeremy L Thompson                      "CeedQFunctionContext has no valid data to get, must set data");
542*28bfd0b7SJeremy L Thompson   // LCOV_EXCL_STOP
543*28bfd0b7SJeremy L Thompson 
544*28bfd0b7SJeremy L Thompson   ierr = ctx->GetDataRead(ctx, mem_type, data); CeedChk(ierr);
545*28bfd0b7SJeremy L Thompson   ctx->num_readers++;
546e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
547777ff853SJeremy L Thompson }
548777ff853SJeremy L Thompson 
549777ff853SJeremy L Thompson /**
550777ff853SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetData()
551777ff853SJeremy L Thompson 
552777ff853SJeremy L Thompson   @param ctx   CeedQFunctionContext to restore
553777ff853SJeremy L Thompson   @param data  Data to restore
554777ff853SJeremy L Thompson 
555777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
556777ff853SJeremy L Thompson 
557777ff853SJeremy L Thompson   @ref User
558777ff853SJeremy L Thompson **/
559777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) {
560777ff853SJeremy L Thompson   int ierr;
561777ff853SJeremy L Thompson 
562777ff853SJeremy L Thompson   if (ctx->state % 2 != 1)
563777ff853SJeremy L Thompson     // LCOV_EXCL_START
564777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
565777ff853SJeremy L Thompson                      "Cannot restore CeedQFunctionContext array access, "
566777ff853SJeremy L Thompson                      "access was not granted");
567777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
568777ff853SJeremy L Thompson 
569706efda3SJeremy L Thompson   if (ctx->RestoreData) {
570777ff853SJeremy L Thompson     ierr = ctx->RestoreData(ctx); CeedChk(ierr);
571706efda3SJeremy L Thompson   }
572777ff853SJeremy L Thompson   *(void **)data = NULL;
573*28bfd0b7SJeremy L Thompson   ctx->state++;
574*28bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
575*28bfd0b7SJeremy L Thompson }
576*28bfd0b7SJeremy L Thompson 
577*28bfd0b7SJeremy L Thompson /**
578*28bfd0b7SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead()
579*28bfd0b7SJeremy L Thompson 
580*28bfd0b7SJeremy L Thompson   @param ctx   CeedQFunctionContext to restore
581*28bfd0b7SJeremy L Thompson   @param data  Data to restore
582*28bfd0b7SJeremy L Thompson 
583*28bfd0b7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
584*28bfd0b7SJeremy L Thompson 
585*28bfd0b7SJeremy L Thompson   @ref User
586*28bfd0b7SJeremy L Thompson **/
587*28bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) {
588*28bfd0b7SJeremy L Thompson   int ierr;
589*28bfd0b7SJeremy L Thompson 
590*28bfd0b7SJeremy L Thompson   if (ctx->num_readers == 0)
591*28bfd0b7SJeremy L Thompson     // LCOV_EXCL_START
592*28bfd0b7SJeremy L Thompson     return CeedError(ctx->ceed, 1,
593*28bfd0b7SJeremy L Thompson                      "Cannot restore CeedQFunctionContext array access, "
594*28bfd0b7SJeremy L Thompson                      "access was not granted");
595*28bfd0b7SJeremy L Thompson   // LCOV_EXCL_STOP
596*28bfd0b7SJeremy L Thompson 
597*28bfd0b7SJeremy L Thompson   if (ctx->RestoreDataRead) {
598*28bfd0b7SJeremy L Thompson     ierr = ctx->RestoreData(ctx); CeedChk(ierr);
599*28bfd0b7SJeremy L Thompson   }
600*28bfd0b7SJeremy L Thompson   *(void **)data = NULL;
601*28bfd0b7SJeremy L Thompson   ctx->num_readers--;
602e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
603777ff853SJeremy L Thompson }
604777ff853SJeremy L Thompson 
605777ff853SJeremy L Thompson /**
606cdf32b93SJeremy L Thompson   @brief Register QFunctionContext a field holding a double precision value
607cdf32b93SJeremy L Thompson 
608cdf32b93SJeremy L Thompson   @param ctx               CeedQFunctionContext
609cdf32b93SJeremy L Thompson   @param field_name        Name of field to register
610cdf32b93SJeremy L Thompson   @param field_offset      Offset of field to register
6117bfe0f0eSJeremy L Thompson   @param num_values        Number of values to register, must be contiguous in memory
612cdf32b93SJeremy L Thompson   @param field_description Description of field, or NULL for none
613cdf32b93SJeremy L Thompson 
614cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
615cdf32b93SJeremy L Thompson 
616cdf32b93SJeremy L Thompson   @ref User
617cdf32b93SJeremy L Thompson **/
618cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx,
619cdf32b93SJeremy L Thompson                                        const char *field_name, size_t field_offset,
6207bfe0f0eSJeremy L Thompson                                        size_t num_values,
621cdf32b93SJeremy L Thompson                                        const char *field_description) {
622cdf32b93SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset,
6237bfe0f0eSJeremy L Thompson          field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double), num_values);
624cdf32b93SJeremy L Thompson }
625cdf32b93SJeremy L Thompson 
626cdf32b93SJeremy L Thompson /**
627cdf32b93SJeremy L Thompson   @brief Register QFunctionContext a field holding a int32 value
628cdf32b93SJeremy L Thompson 
629cdf32b93SJeremy L Thompson   @param ctx               CeedQFunctionContext
630cdf32b93SJeremy L Thompson   @param field_name        Name of field to register
631cdf32b93SJeremy L Thompson   @param field_offset      Offset of field to register
6327bfe0f0eSJeremy L Thompson   @param num_values        Number of values to register, must be contiguous in memory
633cdf32b93SJeremy L Thompson   @param field_description Description of field, or NULL for none
634cdf32b93SJeremy L Thompson 
635cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
636cdf32b93SJeremy L Thompson 
637cdf32b93SJeremy L Thompson   @ref User
638cdf32b93SJeremy L Thompson **/
639cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx,
640cdf32b93SJeremy L Thompson                                       const char *field_name, size_t field_offset,
6417bfe0f0eSJeremy L Thompson                                       size_t num_values,
642cdf32b93SJeremy L Thompson                                       const char *field_description) {
643cdf32b93SJeremy L Thompson   return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset,
6447bfe0f0eSJeremy L Thompson          field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int), num_values);
645cdf32b93SJeremy L Thompson }
646cdf32b93SJeremy L Thompson 
647cdf32b93SJeremy L Thompson /**
6483668ca4bSJeremy L Thompson   @brief Get labels for all registered QFunctionContext fields
649cdf32b93SJeremy L Thompson 
650cdf32b93SJeremy L Thompson   @param ctx                CeedQFunctionContext
6513668ca4bSJeremy L Thompson   @param[out] field_labels  Variable to hold array of field labels
652cdf32b93SJeremy L Thompson   @param[out] num_fields    Length of field descriptions array
653cdf32b93SJeremy L Thompson 
654cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
655cdf32b93SJeremy L Thompson 
656cdf32b93SJeremy L Thompson   @ref User
657cdf32b93SJeremy L Thompson **/
6583668ca4bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx,
6593668ca4bSJeremy L Thompson     const CeedContextFieldLabel **field_labels, CeedInt *num_fields) {
6603668ca4bSJeremy L Thompson   *field_labels = ctx->field_labels;
661cdf32b93SJeremy L Thompson   *num_fields = ctx->num_fields;
662cdf32b93SJeremy L Thompson   return CEED_ERROR_SUCCESS;
663cdf32b93SJeremy L Thompson }
664cdf32b93SJeremy L Thompson 
665cdf32b93SJeremy L Thompson /**
6663668ca4bSJeremy L Thompson   @brief Get label for a registered QFunctionContext field, or `NULL` if no
6673668ca4bSJeremy L Thompson            field has been registered with this `field_name`
6683668ca4bSJeremy L Thompson 
6693668ca4bSJeremy L Thompson   @param[in] ctx           CeedQFunctionContext
6703668ca4bSJeremy L Thompson   @param[in] field_name    Name of field to retrieve label
6713668ca4bSJeremy L Thompson   @param[out] field_label  Variable to field label
6723668ca4bSJeremy L Thompson 
6733668ca4bSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
6743668ca4bSJeremy L Thompson 
6753668ca4bSJeremy L Thompson   @ref User
6763668ca4bSJeremy L Thompson **/
6773668ca4bSJeremy L Thompson int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx,
6787bfe0f0eSJeremy L Thompson                                       const char *field_name,
6797bfe0f0eSJeremy L Thompson                                       CeedContextFieldLabel *field_label) {
6803668ca4bSJeremy L Thompson   int ierr;
6813668ca4bSJeremy L Thompson 
6823668ca4bSJeremy L Thompson   CeedInt field_index;
6833668ca4bSJeremy L Thompson   ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index);
6843668ca4bSJeremy L Thompson   CeedChk(ierr);
6853668ca4bSJeremy L Thompson 
6863668ca4bSJeremy L Thompson   if (field_index != -1) {
6873668ca4bSJeremy L Thompson     *field_label = ctx->field_labels[field_index];
6883668ca4bSJeremy L Thompson   } else {
6893668ca4bSJeremy L Thompson     *field_label = NULL;
6903668ca4bSJeremy L Thompson   }
6913668ca4bSJeremy L Thompson 
6923668ca4bSJeremy L Thompson   return CEED_ERROR_SUCCESS;
6933668ca4bSJeremy L Thompson }
6943668ca4bSJeremy L Thompson 
6953668ca4bSJeremy L Thompson /**
6960f86cbe7SJeremy L Thompson   @brief Get the descriptive information about a CeedContextFieldLabel
6970f86cbe7SJeremy L Thompson 
6980f86cbe7SJeremy L Thompson   @param[in] label              CeedContextFieldLabel
6990f86cbe7SJeremy L Thompson   @param[out] field_name        Name of labeled field
7000f86cbe7SJeremy L Thompson   @param[out] field_description Description of field, or NULL for none
7017bfe0f0eSJeremy L Thompson   @param[out] num_values        Number of values registered
7020f86cbe7SJeremy L Thompson   @param[out] field_type        CeedContextFieldType
7030f86cbe7SJeremy L Thompson 
7040f86cbe7SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
7050f86cbe7SJeremy L Thompson 
7060f86cbe7SJeremy L Thompson   @ref User
7070f86cbe7SJeremy L Thompson **/
7080f86cbe7SJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label,
7090f86cbe7SJeremy L Thompson                                         const char **field_name,
7100f86cbe7SJeremy L Thompson                                         const char **field_description,
7117bfe0f0eSJeremy L Thompson                                         size_t *num_values,
7120f86cbe7SJeremy L Thompson                                         CeedContextFieldType *field_type) {
7130f86cbe7SJeremy L Thompson   if (field_name) *field_name = label->name;
7140f86cbe7SJeremy L Thompson   if (field_description) *field_description = label->description;
7157bfe0f0eSJeremy L Thompson   if (num_values) *num_values = label->num_values;
7160f86cbe7SJeremy L Thompson   if (field_type) *field_type = label->type;
7170f86cbe7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
7180f86cbe7SJeremy L Thompson }
7190f86cbe7SJeremy L Thompson 
7200f86cbe7SJeremy L Thompson /**
721cdf32b93SJeremy L Thompson   @brief Set QFunctionContext field holding a double precision value
722cdf32b93SJeremy L Thompson 
723cdf32b93SJeremy L Thompson   @param ctx         CeedQFunctionContext
7243668ca4bSJeremy L Thompson   @param field_label Label for field to register
7257bfe0f0eSJeremy L Thompson   @param values      Values to set
726cdf32b93SJeremy L Thompson 
727cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
728cdf32b93SJeremy L Thompson 
729cdf32b93SJeremy L Thompson   @ref User
730cdf32b93SJeremy L Thompson **/
731cdf32b93SJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx,
7327bfe0f0eSJeremy L Thompson                                   CeedContextFieldLabel field_label, double *values) {
733d8dd9a91SJeremy L Thompson   int ierr;
734d8dd9a91SJeremy L Thompson 
7353668ca4bSJeremy L Thompson   if (!field_label)
736d8dd9a91SJeremy L Thompson     // LCOV_EXCL_START
737d8dd9a91SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
7383668ca4bSJeremy L Thompson                      "Invalid field label");
739d8dd9a91SJeremy L Thompson   // LCOV_EXCL_STOP
740d8dd9a91SJeremy L Thompson 
7413668ca4bSJeremy L Thompson   ierr = CeedQFunctionContextSetGeneric(ctx, field_label,
7423668ca4bSJeremy L Thompson                                         CEED_CONTEXT_FIELD_DOUBLE,
7437bfe0f0eSJeremy L Thompson                                         values); CeedChk(ierr);
7443668ca4bSJeremy L Thompson 
745d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
746cdf32b93SJeremy L Thompson }
747cdf32b93SJeremy L Thompson 
748cdf32b93SJeremy L Thompson /**
749d8dd9a91SJeremy L Thompson   @brief Set QFunctionContext field holding an int32 value
750cdf32b93SJeremy L Thompson 
751cdf32b93SJeremy L Thompson   @param ctx         CeedQFunctionContext
7523668ca4bSJeremy L Thompson   @param field_label Label for field to register
7537bfe0f0eSJeremy L Thompson   @param values      Values to set
754cdf32b93SJeremy L Thompson 
755cdf32b93SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
756cdf32b93SJeremy L Thompson 
757cdf32b93SJeremy L Thompson   @ref User
758cdf32b93SJeremy L Thompson **/
759cdf32b93SJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx,
7607bfe0f0eSJeremy L Thompson                                  CeedContextFieldLabel field_label, int *values) {
761d8dd9a91SJeremy L Thompson   int ierr;
762d8dd9a91SJeremy L Thompson 
7633668ca4bSJeremy L Thompson   if (!field_label)
764d8dd9a91SJeremy L Thompson     // LCOV_EXCL_START
765d8dd9a91SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
7663668ca4bSJeremy L Thompson                      "Invalid field label");
767d8dd9a91SJeremy L Thompson   // LCOV_EXCL_STOP
768d8dd9a91SJeremy L Thompson 
7693668ca4bSJeremy L Thompson   ierr = CeedQFunctionContextSetGeneric(ctx, field_label,
7703668ca4bSJeremy L Thompson                                         CEED_CONTEXT_FIELD_INT32,
7717bfe0f0eSJeremy L Thompson                                         values); CeedChk(ierr);
7723668ca4bSJeremy L Thompson 
773d8dd9a91SJeremy L Thompson   return CEED_ERROR_SUCCESS;
774cdf32b93SJeremy L Thompson }
775cdf32b93SJeremy L Thompson 
776cdf32b93SJeremy L Thompson /**
77780a9ef05SNatalie Beams   @brief Get data size for a Context
77880a9ef05SNatalie Beams 
77980a9ef05SNatalie Beams   @param ctx            CeedQFunctionContext
78080a9ef05SNatalie Beams   @param[out] ctx_size  Variable to store size of context data values
78180a9ef05SNatalie Beams 
78280a9ef05SNatalie Beams   @return An error code: 0 - success, otherwise - failure
78380a9ef05SNatalie Beams 
78480a9ef05SNatalie Beams   @ref User
78580a9ef05SNatalie Beams **/
78680a9ef05SNatalie Beams int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx,
78780a9ef05SNatalie Beams                                        size_t *ctx_size) {
78880a9ef05SNatalie Beams   *ctx_size = ctx->ctx_size;
78980a9ef05SNatalie Beams   return CEED_ERROR_SUCCESS;
79080a9ef05SNatalie Beams }
79180a9ef05SNatalie Beams 
79280a9ef05SNatalie Beams 
79380a9ef05SNatalie Beams /**
794777ff853SJeremy L Thompson   @brief View a CeedQFunctionContext
795777ff853SJeremy L Thompson 
796777ff853SJeremy L Thompson   @param[in] ctx     CeedQFunctionContext to view
797777ff853SJeremy L Thompson   @param[in] stream  Filestream to write to
798777ff853SJeremy L Thompson 
799777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
800777ff853SJeremy L Thompson 
801777ff853SJeremy L Thompson   @ref User
802777ff853SJeremy L Thompson **/
803777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) {
804777ff853SJeremy L Thompson   fprintf(stream, "CeedQFunctionContext\n");
805d1d35e2fSjeremylt   fprintf(stream, "  Context Data Size: %ld\n", ctx->ctx_size);
8063668ca4bSJeremy L Thompson   for (CeedInt i = 0; i < ctx->num_fields; i++) {
8073668ca4bSJeremy L Thompson     // LCOV_EXCL_START
8083668ca4bSJeremy L Thompson     fprintf(stream, "  Labeled %s field: %s\n",
8093668ca4bSJeremy L Thompson             CeedContextFieldTypes[ctx->field_labels[i]->type],
8103668ca4bSJeremy L Thompson             ctx->field_labels[i]->name);
8113668ca4bSJeremy L Thompson     // LCOV_EXCL_STOP
8123668ca4bSJeremy L Thompson   }
813e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
814777ff853SJeremy L Thompson }
815777ff853SJeremy L Thompson 
816777ff853SJeremy L Thompson /**
817777ff853SJeremy L Thompson   @brief Destroy a CeedQFunctionContext
818777ff853SJeremy L Thompson 
819777ff853SJeremy L Thompson   @param ctx  CeedQFunctionContext to destroy
820777ff853SJeremy L Thompson 
821777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
822777ff853SJeremy L Thompson 
823777ff853SJeremy L Thompson   @ref User
824777ff853SJeremy L Thompson **/
825777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) {
826777ff853SJeremy L Thompson   int ierr;
827777ff853SJeremy L Thompson 
828d1d35e2fSjeremylt   if (!*ctx || --(*ctx)->ref_count > 0)
829e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
830777ff853SJeremy L Thompson 
831777ff853SJeremy L Thompson   if ((*ctx) && ((*ctx)->state % 2) == 1)
832777ff853SJeremy L Thompson     // LCOV_EXCL_START
833777ff853SJeremy L Thompson     return CeedError((*ctx)->ceed, 1,
834777ff853SJeremy L Thompson                      "Cannot destroy CeedQFunctionContext, the access "
835777ff853SJeremy L Thompson                      "lock is in use");
836777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
837777ff853SJeremy L Thompson 
838777ff853SJeremy L Thompson   if ((*ctx)->Destroy) {
839777ff853SJeremy L Thompson     ierr = (*ctx)->Destroy(*ctx); CeedChk(ierr);
840777ff853SJeremy L Thompson   }
841cdf32b93SJeremy L Thompson   for (CeedInt i=0; i<(*ctx)->num_fields; i++) {
8423668ca4bSJeremy L Thompson     ierr = CeedFree(&(*ctx)->field_labels[i]->name); CeedChk(ierr);
8433668ca4bSJeremy L Thompson     ierr = CeedFree(&(*ctx)->field_labels[i]->description); CeedChk(ierr);
8443668ca4bSJeremy L Thompson     ierr = CeedFree(&(*ctx)->field_labels[i]); CeedChk(ierr);
845cdf32b93SJeremy L Thompson   }
8463668ca4bSJeremy L Thompson   ierr = CeedFree(&(*ctx)->field_labels); CeedChk(ierr);
847777ff853SJeremy L Thompson   ierr = CeedDestroy(&(*ctx)->ceed); CeedChk(ierr);
848777ff853SJeremy L Thompson   ierr = CeedFree(ctx); CeedChk(ierr);
849cdf32b93SJeremy L Thompson 
850e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
851777ff853SJeremy L Thompson }
852777ff853SJeremy L Thompson 
853777ff853SJeremy L Thompson /// @}
854