13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3777ff853SJeremy L Thompson // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 5777ff853SJeremy L Thompson // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 7777ff853SJeremy L Thompson 83d576824SJeremy L Thompson #include <ceed-impl.h> 9*2b730f8bSJeremy L Thompson #include <ceed/backend.h> 10*2b730f8bSJeremy L Thompson #include <ceed/ceed.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 **/ 35*2b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx, const char *field_name, CeedInt *field_index) { 36cdf32b93SJeremy L Thompson *field_index = -1; 37*2b730f8bSJeremy L Thompson for (CeedInt i = 0; i < ctx->num_fields; i++) { 38*2b730f8bSJeremy L Thompson if (!strcmp(ctx->field_labels[i]->name, field_name)) *field_index = i; 39*2b730f8bSJeremy L Thompson } 40cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 41cdf32b93SJeremy L Thompson } 42cdf32b93SJeremy L Thompson 43cdf32b93SJeremy L Thompson /** 44cdf32b93SJeremy L Thompson @brief Common function for registering QFunctionContext fields 45cdf32b93SJeremy L Thompson 46cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 47cdf32b93SJeremy L Thompson @param field_name Name of field to register 48cdf32b93SJeremy L Thompson @param field_offset Offset of field to register 49cdf32b93SJeremy L Thompson @param field_description Description of field, or NULL for none 50cdf32b93SJeremy L Thompson @param field_type Field data type, such as double or int32 51cdf32b93SJeremy L Thompson @param field_size Size of field, in bytes 527bfe0f0eSJeremy L Thompson @param num_values Number of values to register, must be contiguous in memory 53cdf32b93SJeremy L Thompson 54cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 55cdf32b93SJeremy L Thompson 56cdf32b93SJeremy L Thompson @ref Developer 57cdf32b93SJeremy L Thompson **/ 58*2b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, const char *field_description, 59*2b730f8bSJeremy L Thompson CeedContextFieldType field_type, size_t field_size, size_t num_values) { 60cdf32b93SJeremy L Thompson // Check for duplicate 61cdf32b93SJeremy L Thompson CeedInt field_index = -1; 62*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index)); 63*2b730f8bSJeremy L Thompson if (field_index != -1) { 64cdf32b93SJeremy L Thompson // LCOV_EXCL_START 65*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" already registered", field_name); 66cdf32b93SJeremy L Thompson // LCOV_EXCL_STOP 67*2b730f8bSJeremy L Thompson } 68cdf32b93SJeremy L Thompson 69cdf32b93SJeremy L Thompson // Allocate space for field data 70cdf32b93SJeremy L Thompson if (ctx->num_fields == 0) { 71*2b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &ctx->field_labels)); 72cdf32b93SJeremy L Thompson ctx->max_fields = 1; 73cdf32b93SJeremy L Thompson } else if (ctx->num_fields == ctx->max_fields) { 74*2b730f8bSJeremy L Thompson CeedCall(CeedRealloc(2 * ctx->max_fields, &ctx->field_labels)); 75cdf32b93SJeremy L Thompson ctx->max_fields *= 2; 76cdf32b93SJeremy L Thompson } 77*2b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &ctx->field_labels[ctx->num_fields])); 78cdf32b93SJeremy L Thompson 79cdf32b93SJeremy L Thompson // Copy field data 80*2b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_name, (char **)&ctx->field_labels[ctx->num_fields]->name)); 81*2b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_description, (char **)&ctx->field_labels[ctx->num_fields]->description)); 823668ca4bSJeremy L Thompson ctx->field_labels[ctx->num_fields]->type = field_type; 833668ca4bSJeremy L Thompson ctx->field_labels[ctx->num_fields]->offset = field_offset; 847bfe0f0eSJeremy L Thompson ctx->field_labels[ctx->num_fields]->size = field_size * num_values; 857bfe0f0eSJeremy L Thompson ctx->field_labels[ctx->num_fields]->num_values = num_values; 86cdf32b93SJeremy L Thompson ctx->num_fields++; 87cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 88cdf32b93SJeremy L Thompson } 89cdf32b93SJeremy L Thompson 903b190ab8SJeremy L Thompson /** 913b190ab8SJeremy L Thompson @brief Destroy user data held by CeedQFunctionContext, using function set by 923b190ab8SJeremy L Thompson CeedQFunctionContextSetDataDestroy, if applicable 933b190ab8SJeremy L Thompson 943b190ab8SJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to destroy user data 953b190ab8SJeremy L Thompson 963b190ab8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 973b190ab8SJeremy L Thompson 983b190ab8SJeremy L Thompson @ref Developer 993b190ab8SJeremy L Thompson **/ 1003b190ab8SJeremy L Thompson static int CeedQFunctionContextDestroyData(CeedQFunctionContext ctx) { 1013b190ab8SJeremy L Thompson if (ctx->DataDestroy) { 102*2b730f8bSJeremy L Thompson CeedCall(ctx->DataDestroy(ctx)); 1033b190ab8SJeremy L Thompson } else { 1043b190ab8SJeremy L Thompson CeedQFunctionContextDataDestroyUser data_destroy_function; 1053b190ab8SJeremy L Thompson CeedMemType data_destroy_mem_type; 1063b190ab8SJeremy L Thompson 107*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function)); 1083b190ab8SJeremy L Thompson if (data_destroy_function) { 1093b190ab8SJeremy L Thompson void *data; 1103b190ab8SJeremy L Thompson 111*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, data_destroy_mem_type, &data)); 112*2b730f8bSJeremy L Thompson CeedCall(data_destroy_function(data)); 113*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, &data)); 1143b190ab8SJeremy L Thompson } 1153b190ab8SJeremy L Thompson } 1163b190ab8SJeremy L Thompson 1173b190ab8SJeremy L Thompson return CEED_ERROR_SUCCESS; 1183b190ab8SJeremy L Thompson } 1193b190ab8SJeremy L Thompson 120cdf32b93SJeremy L Thompson /// @} 121cdf32b93SJeremy L Thompson 122cdf32b93SJeremy L Thompson /// ---------------------------------------------------------------------------- 123777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API 124777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 125777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend 126777ff853SJeremy L Thompson /// @{ 127777ff853SJeremy L Thompson 128777ff853SJeremy L Thompson /** 129777ff853SJeremy L Thompson @brief Get the Ceed associated with a CeedQFunctionContext 130777ff853SJeremy L Thompson 131777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 132777ff853SJeremy L Thompson @param[out] ceed Variable to store Ceed 133777ff853SJeremy L Thompson 134777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 135777ff853SJeremy L Thompson 136777ff853SJeremy L Thompson @ref Backend 137777ff853SJeremy L Thompson **/ 138777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) { 139777ff853SJeremy L Thompson *ceed = ctx->ceed; 140e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 141777ff853SJeremy L Thompson } 142777ff853SJeremy L Thompson 143777ff853SJeremy L Thompson /** 1449c774eddSJeremy L Thompson @brief Check for valid data in a CeedQFunctionContext 1459c774eddSJeremy L Thompson 1469c774eddSJeremy L Thompson @param ctx CeedQFunctionContext to check validity 1479c774eddSJeremy L Thompson @param[out] has_valid_data Variable to store validity 1489c774eddSJeremy L Thompson 1499c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1509c774eddSJeremy L Thompson 1519c774eddSJeremy L Thompson @ref Backend 1529c774eddSJeremy L Thompson **/ 153*2b730f8bSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx, bool *has_valid_data) { 154*2b730f8bSJeremy L Thompson if (!ctx->HasValidData) { 1559c774eddSJeremy L Thompson // LCOV_EXCL_START 156*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support HasValidData"); 1579c774eddSJeremy L Thompson // LCOV_EXCL_STOP 158*2b730f8bSJeremy L Thompson } 1599c774eddSJeremy L Thompson 160*2b730f8bSJeremy L Thompson CeedCall(ctx->HasValidData(ctx, has_valid_data)); 1619c774eddSJeremy L Thompson 1629c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 1639c774eddSJeremy L Thompson } 1649c774eddSJeremy L Thompson 1659c774eddSJeremy L Thompson /** 1669c774eddSJeremy L Thompson @brief Check for borrowed data of a specific CeedMemType in a 1679c774eddSJeremy L Thompson CeedQFunctionContext 1689c774eddSJeremy L Thompson 1699c774eddSJeremy L Thompson @param ctx CeedQFunctionContext to check 1709c774eddSJeremy L Thompson @param mem_type Memory type to check 1719c774eddSJeremy L Thompson @param[out] has_borrowed_data_of_type Variable to store result 1729c774eddSJeremy L Thompson 1739c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1749c774eddSJeremy L Thompson 1759c774eddSJeremy L Thompson @ref Backend 1769c774eddSJeremy L Thompson **/ 177*2b730f8bSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx, CeedMemType mem_type, bool *has_borrowed_data_of_type) { 178*2b730f8bSJeremy L Thompson if (!ctx->HasBorrowedDataOfType) { 1799c774eddSJeremy L Thompson // LCOV_EXCL_START 180*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support HasBorrowedDataOfType"); 1819c774eddSJeremy L Thompson // LCOV_EXCL_STOP 182*2b730f8bSJeremy L Thompson } 1839c774eddSJeremy L Thompson 184*2b730f8bSJeremy L Thompson CeedCall(ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type)); 1859c774eddSJeremy L Thompson 1869c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 1879c774eddSJeremy L Thompson } 1889c774eddSJeremy L Thompson 1899c774eddSJeremy L Thompson /** 190777ff853SJeremy L Thompson @brief Get the state of a CeedQFunctionContext 191777ff853SJeremy L Thompson 192777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to retrieve state 193777ff853SJeremy L Thompson @param[out] state Variable to store state 194777ff853SJeremy L Thompson 195777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 196777ff853SJeremy L Thompson 197777ff853SJeremy L Thompson @ref Backend 198777ff853SJeremy L Thompson **/ 199777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) { 200777ff853SJeremy L Thompson *state = ctx->state; 201e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 202777ff853SJeremy L Thompson } 203777ff853SJeremy L Thompson 204777ff853SJeremy L Thompson /** 205777ff853SJeremy L Thompson @brief Get backend data of a CeedQFunctionContext 206777ff853SJeremy L Thompson 207777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 208777ff853SJeremy L Thompson @param[out] data Variable to store data 209777ff853SJeremy L Thompson 210777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 211777ff853SJeremy L Thompson 212777ff853SJeremy L Thompson @ref Backend 213777ff853SJeremy L Thompson **/ 214777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) { 215777ff853SJeremy L Thompson *(void **)data = ctx->data; 216e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 217777ff853SJeremy L Thompson } 218777ff853SJeremy L Thompson 219777ff853SJeremy L Thompson /** 220777ff853SJeremy L Thompson @brief Set backend data of a CeedQFunctionContext 221777ff853SJeremy L Thompson 222777ff853SJeremy L Thompson @param[out] ctx CeedQFunctionContext 223777ff853SJeremy L Thompson @param data Data to set 224777ff853SJeremy L Thompson 225777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 226777ff853SJeremy L Thompson 227777ff853SJeremy L Thompson @ref Backend 228777ff853SJeremy L Thompson **/ 229777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) { 230777ff853SJeremy L Thompson ctx->data = data; 231e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 232777ff853SJeremy L Thompson } 233777ff853SJeremy L Thompson 23434359f16Sjeremylt /** 235e6a0ab89SJeremy L Thompson @brief Get label for a registered QFunctionContext field, or `NULL` if no 236e6a0ab89SJeremy L Thompson field has been registered with this `field_name` 237e6a0ab89SJeremy L Thompson 238e6a0ab89SJeremy L Thompson @param[in] ctx CeedQFunctionContext 239e6a0ab89SJeremy L Thompson @param[in] field_name Name of field to retrieve label 240e6a0ab89SJeremy L Thompson @param[out] field_label Variable to field label 241e6a0ab89SJeremy L Thompson 242e6a0ab89SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 243e6a0ab89SJeremy L Thompson 2443e1e85abSJeremy L Thompson @ref Backend 245e6a0ab89SJeremy L Thompson **/ 246*2b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx, const char *field_name, CeedContextFieldLabel *field_label) { 247e6a0ab89SJeremy L Thompson CeedInt field_index; 248*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index)); 249e6a0ab89SJeremy L Thompson 250e6a0ab89SJeremy L Thompson if (field_index != -1) { 251e6a0ab89SJeremy L Thompson *field_label = ctx->field_labels[field_index]; 252e6a0ab89SJeremy L Thompson } else { 253e6a0ab89SJeremy L Thompson *field_label = NULL; 254e6a0ab89SJeremy L Thompson } 255e6a0ab89SJeremy L Thompson 256e6a0ab89SJeremy L Thompson return CEED_ERROR_SUCCESS; 257e6a0ab89SJeremy L Thompson } 258e6a0ab89SJeremy L Thompson 259e6a0ab89SJeremy L Thompson /** 260d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field 261d8dd9a91SJeremy L Thompson 262d8dd9a91SJeremy L Thompson @param ctx CeedQFunctionContext 2633668ca4bSJeremy L Thompson @param field_label Label of field to set 264d8dd9a91SJeremy L Thompson @param field_type Type of field to set 265d8dd9a91SJeremy L Thompson @param value Value to set 266d8dd9a91SJeremy L Thompson 267d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 268d8dd9a91SJeremy L Thompson 2693e1e85abSJeremy L Thompson @ref Backend 270d8dd9a91SJeremy L Thompson **/ 271*2b730f8bSJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *value) { 2723668ca4bSJeremy L Thompson // Check field type 273*2b730f8bSJeremy L Thompson if (field_label->type != field_type) { 274d8dd9a91SJeremy L Thompson // LCOV_EXCL_START 275*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", 276*2b730f8bSJeremy L Thompson field_label->name, CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 277d8dd9a91SJeremy L Thompson // LCOV_EXCL_STOP 278*2b730f8bSJeremy L Thompson } 279d8dd9a91SJeremy L Thompson 280d8dd9a91SJeremy L Thompson char *data; 281*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data)); 2823668ca4bSJeremy L Thompson memcpy(&data[field_label->offset], value, field_label->size); 283*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, &data)); 284d8dd9a91SJeremy L Thompson 285d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 286d8dd9a91SJeremy L Thompson } 287d8dd9a91SJeremy L Thompson 288d8dd9a91SJeremy L Thompson /** 289bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value 290bfacc300SJeremy L Thompson 291bfacc300SJeremy L Thompson @param ctx CeedQFunctionContext 292bfacc300SJeremy L Thompson @param field_label Label for field to register 293bfacc300SJeremy L Thompson @param values Values to set 294bfacc300SJeremy L Thompson 295bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 296bfacc300SJeremy L Thompson 2973e1e85abSJeremy L Thompson @ref Backend 298bfacc300SJeremy L Thompson **/ 299*2b730f8bSJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, double *values) { 300*2b730f8bSJeremy L Thompson if (!field_label) { 301bfacc300SJeremy L Thompson // LCOV_EXCL_START 302*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 303bfacc300SJeremy L Thompson // LCOV_EXCL_STOP 304*2b730f8bSJeremy L Thompson } 305bfacc300SJeremy L Thompson 306*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values)); 307bfacc300SJeremy L Thompson 308bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 309bfacc300SJeremy L Thompson } 310bfacc300SJeremy L Thompson 311bfacc300SJeremy L Thompson /** 312bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding an int32 value 313bfacc300SJeremy L Thompson 314bfacc300SJeremy L Thompson @param ctx CeedQFunctionContext 315bfacc300SJeremy L Thompson @param field_label Label for field to register 316bfacc300SJeremy L Thompson @param values Values to set 317bfacc300SJeremy L Thompson 318bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 319bfacc300SJeremy L Thompson 3203e1e85abSJeremy L Thompson @ref Backend 321bfacc300SJeremy L Thompson **/ 322*2b730f8bSJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, int *values) { 323*2b730f8bSJeremy L Thompson if (!field_label) { 324bfacc300SJeremy L Thompson // LCOV_EXCL_START 325*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 326bfacc300SJeremy L Thompson // LCOV_EXCL_STOP 327*2b730f8bSJeremy L Thompson } 328bfacc300SJeremy L Thompson 329*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values)); 330bfacc300SJeremy L Thompson 331bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 332bfacc300SJeremy L Thompson } 333bfacc300SJeremy L Thompson 334bfacc300SJeremy L Thompson /** 3352e64a2b9SJeremy L Thompson @brief Get additional destroy routine for CeedQFunctionContext user data 3362e64a2b9SJeremy L Thompson 3372e64a2b9SJeremy L Thompson @param[in] ctx CeedQFunctionContext to get user destroy function 3382e64a2b9SJeremy L Thompson @param[out] f_mem_type Memory type to use when passing data into `f` 3392e64a2b9SJeremy L Thompson @param[out] f Additional routine to use to destroy user data 3402e64a2b9SJeremy L Thompson 3412e64a2b9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3422e64a2b9SJeremy L Thompson 3432e64a2b9SJeremy L Thompson @ref Backend 3442e64a2b9SJeremy L Thompson **/ 345*2b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx, CeedMemType *f_mem_type, CeedQFunctionContextDataDestroyUser *f) { 3462e64a2b9SJeremy L Thompson if (f_mem_type) *f_mem_type = ctx->data_destroy_mem_type; 3472e64a2b9SJeremy L Thompson if (f) *f = ctx->data_destroy_function; 3482e64a2b9SJeremy L Thompson return CEED_ERROR_SUCCESS; 3492e64a2b9SJeremy L Thompson } 3502e64a2b9SJeremy L Thompson 3512e64a2b9SJeremy L Thompson /** 35234359f16Sjeremylt @brief Increment the reference counter for a CeedQFunctionContext 35334359f16Sjeremylt 35434359f16Sjeremylt @param ctx CeedQFunctionContext to increment the reference counter 35534359f16Sjeremylt 35634359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 35734359f16Sjeremylt 35834359f16Sjeremylt @ref Backend 35934359f16Sjeremylt **/ 3609560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) { 36134359f16Sjeremylt ctx->ref_count++; 36234359f16Sjeremylt return CEED_ERROR_SUCCESS; 36334359f16Sjeremylt } 36434359f16Sjeremylt 365777ff853SJeremy L Thompson /// @} 366777ff853SJeremy L Thompson 367777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 368777ff853SJeremy L Thompson /// CeedQFunctionContext Public API 369777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 370777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser 371777ff853SJeremy L Thompson /// @{ 372777ff853SJeremy L Thompson 373777ff853SJeremy L Thompson /** 374777ff853SJeremy L Thompson @brief Create a CeedQFunctionContext for storing CeedQFunction user context data 375777ff853SJeremy L Thompson 376777ff853SJeremy L Thompson @param ceed A Ceed object where the CeedQFunctionContext will be created 377777ff853SJeremy L Thompson @param[out] ctx Address of the variable where the newly created 378777ff853SJeremy L Thompson CeedQFunctionContext will be stored 379777ff853SJeremy L Thompson 380777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 381777ff853SJeremy L Thompson 382777ff853SJeremy L Thompson @ref User 383777ff853SJeremy L Thompson **/ 384777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) { 385777ff853SJeremy L Thompson if (!ceed->QFunctionContextCreate) { 386777ff853SJeremy L Thompson Ceed delegate; 387*2b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Context")); 388777ff853SJeremy L Thompson 389*2b730f8bSJeremy L Thompson if (!delegate) { 390777ff853SJeremy L Thompson // LCOV_EXCL_START 391*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextCreate"); 392777ff853SJeremy L Thompson // LCOV_EXCL_STOP 393*2b730f8bSJeremy L Thompson } 394777ff853SJeremy L Thompson 395*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextCreate(delegate, ctx)); 396e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 397777ff853SJeremy L Thompson } 398777ff853SJeremy L Thompson 399*2b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, ctx)); 400777ff853SJeremy L Thompson (*ctx)->ceed = ceed; 401*2b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 402d1d35e2fSjeremylt (*ctx)->ref_count = 1; 403*2b730f8bSJeremy L Thompson CeedCall(ceed->QFunctionContextCreate(*ctx)); 404e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 405777ff853SJeremy L Thompson } 406777ff853SJeremy L Thompson 407777ff853SJeremy L Thompson /** 4089560d06aSjeremylt @brief Copy the pointer to a CeedQFunctionContext. Both pointers should 4099560d06aSjeremylt be destroyed with `CeedQFunctionContextDestroy()`; 4109560d06aSjeremylt Note: If `*ctx_copy` is non-NULL, then it is assumed that 4119560d06aSjeremylt `*ctx_copy` is a pointer to a CeedQFunctionContext. This 4129560d06aSjeremylt CeedQFunctionContext will be destroyed if `*ctx_copy` is the 4139560d06aSjeremylt only reference to this CeedQFunctionContext. 4149560d06aSjeremylt 4159560d06aSjeremylt @param ctx CeedQFunctionContext to copy reference to 4169560d06aSjeremylt @param[out] ctx_copy Variable to store copied reference 4179560d06aSjeremylt 4189560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 4199560d06aSjeremylt 4209560d06aSjeremylt @ref User 4219560d06aSjeremylt **/ 422*2b730f8bSJeremy L Thompson int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, CeedQFunctionContext *ctx_copy) { 423*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextReference(ctx)); 424*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(ctx_copy)); 4259560d06aSjeremylt *ctx_copy = ctx; 4269560d06aSjeremylt return CEED_ERROR_SUCCESS; 4279560d06aSjeremylt } 4289560d06aSjeremylt 4299560d06aSjeremylt /** 430777ff853SJeremy L Thompson @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated 431777ff853SJeremy L Thompson data if applicable. The backend may copy values to a different 432777ff853SJeremy L Thompson memtype, such as during @ref CeedQFunctionApply(). 433777ff853SJeremy L Thompson See also @ref CeedQFunctionContextTakeData(). 434777ff853SJeremy L Thompson 435777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 436d1d35e2fSjeremylt @param mem_type Memory type of the data being passed 437d1d35e2fSjeremylt @param copy_mode Copy mode for the data 438891038deSjeremylt @param size Size of data, in bytes 439777ff853SJeremy L Thompson @param data Data to be used 440777ff853SJeremy L Thompson 441777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 442777ff853SJeremy L Thompson 443777ff853SJeremy L Thompson @ref User 444777ff853SJeremy L Thompson **/ 445*2b730f8bSJeremy L Thompson int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, size_t size, void *data) { 446*2b730f8bSJeremy L Thompson if (!ctx->SetData) { 447777ff853SJeremy L Thompson // LCOV_EXCL_START 448*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextSetData"); 449777ff853SJeremy L Thompson // LCOV_EXCL_STOP 450*2b730f8bSJeremy L Thompson } 451*2b730f8bSJeremy L Thompson if (ctx->state % 2 == 1) { 452777ff853SJeremy L Thompson // LCOV_EXCL_START 453*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 454777ff853SJeremy L Thompson // LCOV_EXCL_STOP 455*2b730f8bSJeremy L Thompson } 456777ff853SJeremy L Thompson 457*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroyData(ctx)); 458d1d35e2fSjeremylt ctx->ctx_size = size; 459*2b730f8bSJeremy L Thompson CeedCall(ctx->SetData(ctx, mem_type, copy_mode, data)); 460777ff853SJeremy L Thompson ctx->state += 2; 461e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 462777ff853SJeremy L Thompson } 463777ff853SJeremy L Thompson 464777ff853SJeremy L Thompson /** 465891038deSjeremylt @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type. 466891038deSjeremylt The caller is responsible for managing and freeing the memory. 467891038deSjeremylt 468891038deSjeremylt @param ctx CeedQFunctionContext to access 469891038deSjeremylt @param mem_type Memory type on which to access the data. If the backend 470891038deSjeremylt uses a different memory type, this will perform a copy. 471891038deSjeremylt @param[out] data Data on memory type mem_type 472891038deSjeremylt 473891038deSjeremylt @return An error code: 0 - success, otherwise - failure 474891038deSjeremylt 475891038deSjeremylt @ref User 476891038deSjeremylt **/ 477*2b730f8bSJeremy L Thompson int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 4789c774eddSJeremy L Thompson bool has_valid_data = true; 479*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 480*2b730f8bSJeremy L Thompson if (!has_valid_data) { 4819c774eddSJeremy L Thompson // LCOV_EXCL_START 482*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to take, must set data"); 4839c774eddSJeremy L Thompson // LCOV_EXCL_STOP 484*2b730f8bSJeremy L Thompson } 4859c774eddSJeremy L Thompson 486*2b730f8bSJeremy L Thompson if (!ctx->TakeData) { 487891038deSjeremylt // LCOV_EXCL_START 488*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support TakeData"); 489891038deSjeremylt // LCOV_EXCL_STOP 490*2b730f8bSJeremy L Thompson } 491*2b730f8bSJeremy L Thompson if (ctx->state % 2 == 1) { 492891038deSjeremylt // LCOV_EXCL_START 493*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 494891038deSjeremylt // LCOV_EXCL_STOP 495*2b730f8bSJeremy L Thompson } 496891038deSjeremylt 4979c774eddSJeremy L Thompson bool has_borrowed_data_of_type = true; 498*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, &has_borrowed_data_of_type)); 499*2b730f8bSJeremy L Thompson if (!has_borrowed_data_of_type) { 5009c774eddSJeremy L Thompson // LCOV_EXCL_START 501*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no borowed %s data, must set data with CeedQFunctionContextSetData", 5029c774eddSJeremy L Thompson CeedMemTypes[mem_type]); 5039c774eddSJeremy L Thompson // LCOV_EXCL_STOP 504*2b730f8bSJeremy L Thompson } 5059c774eddSJeremy L Thompson 506891038deSjeremylt void *temp_data = NULL; 507*2b730f8bSJeremy L Thompson CeedCall(ctx->TakeData(ctx, mem_type, &temp_data)); 508891038deSjeremylt if (data) (*(void **)data) = temp_data; 509891038deSjeremylt return CEED_ERROR_SUCCESS; 510891038deSjeremylt } 511891038deSjeremylt 512891038deSjeremylt /** 513777ff853SJeremy L Thompson @brief Get read/write access to a CeedQFunctionContext via the specified memory type. 514777ff853SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 515777ff853SJeremy L Thompson 516777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to access 517d1d35e2fSjeremylt @param mem_type Memory type on which to access the data. If the backend 518777ff853SJeremy L Thompson uses a different memory type, this will perform a copy. 519d1d35e2fSjeremylt @param[out] data Data on memory type mem_type 520777ff853SJeremy L Thompson 521777ff853SJeremy L Thompson @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions 522777ff853SJeremy L Thompson provide access to array pointers in the desired memory space. Pairing 523777ff853SJeremy L Thompson get/restore allows the Context to track access. 524777ff853SJeremy L Thompson 525777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 526777ff853SJeremy L Thompson 527777ff853SJeremy L Thompson @ref User 528777ff853SJeremy L Thompson **/ 529*2b730f8bSJeremy L Thompson int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 530*2b730f8bSJeremy L Thompson if (!ctx->GetData) { 531777ff853SJeremy L Thompson // LCOV_EXCL_START 532*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetData"); 533777ff853SJeremy L Thompson // LCOV_EXCL_STOP 534*2b730f8bSJeremy L Thompson } 535*2b730f8bSJeremy L Thompson if (ctx->state % 2 == 1) { 536777ff853SJeremy L Thompson // LCOV_EXCL_START 537*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 538777ff853SJeremy L Thompson // LCOV_EXCL_STOP 539*2b730f8bSJeremy L Thompson } 540*2b730f8bSJeremy L Thompson if (ctx->num_readers > 0) { 54128bfd0b7SJeremy L Thompson // LCOV_EXCL_START 542*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, a process has read access"); 54328bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 544*2b730f8bSJeremy L Thompson } 54528bfd0b7SJeremy L Thompson 5469c774eddSJeremy L Thompson bool has_valid_data = true; 547*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 548*2b730f8bSJeremy L Thompson if (!has_valid_data) { 5499c774eddSJeremy L Thompson // LCOV_EXCL_START 550*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data"); 5519c774eddSJeremy L Thompson // LCOV_EXCL_STOP 552*2b730f8bSJeremy L Thompson } 5539c774eddSJeremy L Thompson 554*2b730f8bSJeremy L Thompson CeedCall(ctx->GetData(ctx, mem_type, data)); 55528bfd0b7SJeremy L Thompson ctx->state++; 55628bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 55728bfd0b7SJeremy L Thompson } 55828bfd0b7SJeremy L Thompson 55928bfd0b7SJeremy L Thompson /** 56028bfd0b7SJeremy L Thompson @brief Get read only access to a CeedQFunctionContext via the specified memory type. 56128bfd0b7SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 56228bfd0b7SJeremy L Thompson 56328bfd0b7SJeremy L Thompson @param ctx CeedQFunctionContext to access 56428bfd0b7SJeremy L Thompson @param mem_type Memory type on which to access the data. If the backend 56528bfd0b7SJeremy L Thompson uses a different memory type, this will perform a copy. 56628bfd0b7SJeremy L Thompson @param[out] data Data on memory type mem_type 56728bfd0b7SJeremy L Thompson 56828bfd0b7SJeremy L Thompson @note The CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead() 56928bfd0b7SJeremy L Thompson functions provide access to array pointers in the desired memory space. Pairing 57028bfd0b7SJeremy L Thompson get/restore allows the Context to track access. 57128bfd0b7SJeremy L Thompson 57228bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 57328bfd0b7SJeremy L Thompson 57428bfd0b7SJeremy L Thompson @ref User 57528bfd0b7SJeremy L Thompson **/ 576*2b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 577*2b730f8bSJeremy L Thompson if (!ctx->GetDataRead) { 57828bfd0b7SJeremy L Thompson // LCOV_EXCL_START 579*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetDataRead"); 58028bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 581*2b730f8bSJeremy L Thompson } 582*2b730f8bSJeremy L Thompson if (ctx->state % 2 == 1) { 58328bfd0b7SJeremy L Thompson // LCOV_EXCL_START 584*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 58528bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 586*2b730f8bSJeremy L Thompson } 58728bfd0b7SJeremy L Thompson 58828bfd0b7SJeremy L Thompson bool has_valid_data = true; 589*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 590*2b730f8bSJeremy L Thompson if (!has_valid_data) { 59128bfd0b7SJeremy L Thompson // LCOV_EXCL_START 592*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data"); 59328bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 594*2b730f8bSJeremy L Thompson } 59528bfd0b7SJeremy L Thompson 596*2b730f8bSJeremy L Thompson CeedCall(ctx->GetDataRead(ctx, mem_type, data)); 59728bfd0b7SJeremy L Thompson ctx->num_readers++; 598e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 599777ff853SJeremy L Thompson } 600777ff853SJeremy L Thompson 601777ff853SJeremy L Thompson /** 602777ff853SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetData() 603777ff853SJeremy L Thompson 604777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to restore 605777ff853SJeremy L Thompson @param data Data to restore 606777ff853SJeremy L Thompson 607777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 608777ff853SJeremy L Thompson 609777ff853SJeremy L Thompson @ref User 610777ff853SJeremy L Thompson **/ 611777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) { 612*2b730f8bSJeremy L Thompson if (ctx->state % 2 != 1) { 613777ff853SJeremy L Thompson // LCOV_EXCL_START 614*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted"); 615777ff853SJeremy L Thompson // LCOV_EXCL_STOP 616*2b730f8bSJeremy L Thompson } 617777ff853SJeremy L Thompson 618706efda3SJeremy L Thompson if (ctx->RestoreData) { 619*2b730f8bSJeremy L Thompson CeedCall(ctx->RestoreData(ctx)); 620706efda3SJeremy L Thompson } 621777ff853SJeremy L Thompson *(void **)data = NULL; 62228bfd0b7SJeremy L Thompson ctx->state++; 62328bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 62428bfd0b7SJeremy L Thompson } 62528bfd0b7SJeremy L Thompson 62628bfd0b7SJeremy L Thompson /** 62728bfd0b7SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead() 62828bfd0b7SJeremy L Thompson 62928bfd0b7SJeremy L Thompson @param ctx CeedQFunctionContext to restore 63028bfd0b7SJeremy L Thompson @param data Data to restore 63128bfd0b7SJeremy L Thompson 63228bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 63328bfd0b7SJeremy L Thompson 63428bfd0b7SJeremy L Thompson @ref User 63528bfd0b7SJeremy L Thompson **/ 63628bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) { 637*2b730f8bSJeremy L Thompson if (ctx->num_readers == 0) { 63828bfd0b7SJeremy L Thompson // LCOV_EXCL_START 639*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted"); 64028bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 641*2b730f8bSJeremy L Thompson } 64228bfd0b7SJeremy L Thompson 64375a19770SJeremy L Thompson ctx->num_readers--; 64475a19770SJeremy L Thompson if (ctx->num_readers == 0 && ctx->RestoreDataRead) { 645*2b730f8bSJeremy L Thompson CeedCall(ctx->RestoreDataRead(ctx)); 64628bfd0b7SJeremy L Thompson } 64728bfd0b7SJeremy L Thompson *(void **)data = NULL; 64875a19770SJeremy L Thompson 649e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 650777ff853SJeremy L Thompson } 651777ff853SJeremy L Thompson 652777ff853SJeremy L Thompson /** 653cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a double precision value 654cdf32b93SJeremy L Thompson 655cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 656cdf32b93SJeremy L Thompson @param field_name Name of field to register 657cdf32b93SJeremy L Thompson @param field_offset Offset of field to register 6587bfe0f0eSJeremy L Thompson @param num_values Number of values to register, must be contiguous in memory 659cdf32b93SJeremy L Thompson @param field_description Description of field, or NULL for none 660cdf32b93SJeremy L Thompson 661cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 662cdf32b93SJeremy L Thompson 663cdf32b93SJeremy L Thompson @ref User 664cdf32b93SJeremy L Thompson **/ 665*2b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 666cdf32b93SJeremy L Thompson const char *field_description) { 667*2b730f8bSJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double), num_values); 668cdf32b93SJeremy L Thompson } 669cdf32b93SJeremy L Thompson 670cdf32b93SJeremy L Thompson /** 671cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a int32 value 672cdf32b93SJeremy L Thompson 673cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 674cdf32b93SJeremy L Thompson @param field_name Name of field to register 675cdf32b93SJeremy L Thompson @param field_offset Offset of field to register 6767bfe0f0eSJeremy L Thompson @param num_values Number of values to register, must be contiguous in memory 677cdf32b93SJeremy L Thompson @param field_description Description of field, or NULL for none 678cdf32b93SJeremy L Thompson 679cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 680cdf32b93SJeremy L Thompson 681cdf32b93SJeremy L Thompson @ref User 682cdf32b93SJeremy L Thompson **/ 683*2b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 684cdf32b93SJeremy L Thompson const char *field_description) { 685*2b730f8bSJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int), num_values); 686cdf32b93SJeremy L Thompson } 687cdf32b93SJeremy L Thompson 688cdf32b93SJeremy L Thompson /** 6893668ca4bSJeremy L Thompson @brief Get labels for all registered QFunctionContext fields 690cdf32b93SJeremy L Thompson 691cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 6923668ca4bSJeremy L Thompson @param[out] field_labels Variable to hold array of field labels 693cdf32b93SJeremy L Thompson @param[out] num_fields Length of field descriptions array 694cdf32b93SJeremy L Thompson 695cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 696cdf32b93SJeremy L Thompson 697cdf32b93SJeremy L Thompson @ref User 698cdf32b93SJeremy L Thompson **/ 699*2b730f8bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, const CeedContextFieldLabel **field_labels, CeedInt *num_fields) { 7003668ca4bSJeremy L Thompson *field_labels = ctx->field_labels; 701cdf32b93SJeremy L Thompson *num_fields = ctx->num_fields; 702cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 703cdf32b93SJeremy L Thompson } 704cdf32b93SJeremy L Thompson 705cdf32b93SJeremy L Thompson /** 7060f86cbe7SJeremy L Thompson @brief Get the descriptive information about a CeedContextFieldLabel 7070f86cbe7SJeremy L Thompson 7080f86cbe7SJeremy L Thompson @param[in] label CeedContextFieldLabel 7090f86cbe7SJeremy L Thompson @param[out] field_name Name of labeled field 7100f86cbe7SJeremy L Thompson @param[out] field_description Description of field, or NULL for none 7117bfe0f0eSJeremy L Thompson @param[out] num_values Number of values registered 7120f86cbe7SJeremy L Thompson @param[out] field_type CeedContextFieldType 7130f86cbe7SJeremy L Thompson 7140f86cbe7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7150f86cbe7SJeremy L Thompson 7160f86cbe7SJeremy L Thompson @ref User 7170f86cbe7SJeremy L Thompson **/ 718*2b730f8bSJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, const char **field_name, const char **field_description, size_t *num_values, 7190f86cbe7SJeremy L Thompson CeedContextFieldType *field_type) { 7200f86cbe7SJeremy L Thompson if (field_name) *field_name = label->name; 7210f86cbe7SJeremy L Thompson if (field_description) *field_description = label->description; 7227bfe0f0eSJeremy L Thompson if (num_values) *num_values = label->num_values; 7230f86cbe7SJeremy L Thompson if (field_type) *field_type = label->type; 7240f86cbe7SJeremy L Thompson return CEED_ERROR_SUCCESS; 7250f86cbe7SJeremy L Thompson } 7260f86cbe7SJeremy L Thompson 7270f86cbe7SJeremy L Thompson /** 72880a9ef05SNatalie Beams @brief Get data size for a Context 72980a9ef05SNatalie Beams 73080a9ef05SNatalie Beams @param ctx CeedQFunctionContext 73180a9ef05SNatalie Beams @param[out] ctx_size Variable to store size of context data values 73280a9ef05SNatalie Beams 73380a9ef05SNatalie Beams @return An error code: 0 - success, otherwise - failure 73480a9ef05SNatalie Beams 73580a9ef05SNatalie Beams @ref User 73680a9ef05SNatalie Beams **/ 737*2b730f8bSJeremy L Thompson int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, size_t *ctx_size) { 73880a9ef05SNatalie Beams *ctx_size = ctx->ctx_size; 73980a9ef05SNatalie Beams return CEED_ERROR_SUCCESS; 74080a9ef05SNatalie Beams } 74180a9ef05SNatalie Beams 74280a9ef05SNatalie Beams /** 743777ff853SJeremy L Thompson @brief View a CeedQFunctionContext 744777ff853SJeremy L Thompson 745777ff853SJeremy L Thompson @param[in] ctx CeedQFunctionContext to view 746777ff853SJeremy L Thompson @param[in] stream Filestream to write to 747777ff853SJeremy L Thompson 748777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 749777ff853SJeremy L Thompson 750777ff853SJeremy L Thompson @ref User 751777ff853SJeremy L Thompson **/ 752777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) { 753777ff853SJeremy L Thompson fprintf(stream, "CeedQFunctionContext\n"); 754d1d35e2fSjeremylt fprintf(stream, " Context Data Size: %ld\n", ctx->ctx_size); 7553668ca4bSJeremy L Thompson for (CeedInt i = 0; i < ctx->num_fields; i++) { 7563668ca4bSJeremy L Thompson // LCOV_EXCL_START 757*2b730f8bSJeremy L Thompson fprintf(stream, " Labeled %s field: %s\n", CeedContextFieldTypes[ctx->field_labels[i]->type], ctx->field_labels[i]->name); 7583668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 7593668ca4bSJeremy L Thompson } 760e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 761777ff853SJeremy L Thompson } 762777ff853SJeremy L Thompson 763777ff853SJeremy L Thompson /** 7642790b72bSJeremy L Thompson @brief Set additional destroy routine for CeedQFunctionContext user data 7652790b72bSJeremy L Thompson 7662e64a2b9SJeremy L Thompson @param[in] ctx CeedQFunctionContext to set user destroy function 7672e64a2b9SJeremy L Thompson @param[in] f_mem_type Memory type to use when passing data into `f` 7682e64a2b9SJeremy L Thompson @param[in] f Additional routine to use to destroy user data 7692790b72bSJeremy L Thompson 7702790b72bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7712790b72bSJeremy L Thompson 7722790b72bSJeremy L Thompson @ref User 7732790b72bSJeremy L Thompson **/ 774*2b730f8bSJeremy L Thompson int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) { 775*2b730f8bSJeremy L Thompson if (!f) { 7762790b72bSJeremy L Thompson // LCOV_EXCL_START 777*2b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Must provide valid callback function for destroying user data"); 7782790b72bSJeremy L Thompson // LCOV_EXCL_STOP 779*2b730f8bSJeremy L Thompson } 7802790b72bSJeremy L Thompson ctx->data_destroy_mem_type = f_mem_type; 7812790b72bSJeremy L Thompson ctx->data_destroy_function = f; 7822790b72bSJeremy L Thompson return CEED_ERROR_SUCCESS; 7832790b72bSJeremy L Thompson } 7842790b72bSJeremy L Thompson 7852790b72bSJeremy L Thompson /** 786777ff853SJeremy L Thompson @brief Destroy a CeedQFunctionContext 787777ff853SJeremy L Thompson 788777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to destroy 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 CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) { 795*2b730f8bSJeremy L Thompson if (!*ctx || --(*ctx)->ref_count > 0) return CEED_ERROR_SUCCESS; 796777ff853SJeremy L Thompson 797*2b730f8bSJeremy L Thompson if ((*ctx) && ((*ctx)->state % 2) == 1) { 798777ff853SJeremy L Thompson // LCOV_EXCL_START 799*2b730f8bSJeremy L Thompson return CeedError((*ctx)->ceed, 1, "Cannot destroy CeedQFunctionContext, the access lock is in use"); 800777ff853SJeremy L Thompson // LCOV_EXCL_STOP 801*2b730f8bSJeremy L Thompson } 802777ff853SJeremy L Thompson 803*2b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroyData(*ctx)); 804*2b730f8bSJeremy L Thompson if ((*ctx)->Destroy) CeedCall((*ctx)->Destroy(*ctx)); 805cdf32b93SJeremy L Thompson for (CeedInt i = 0; i < (*ctx)->num_fields; i++) { 806*2b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i]->name)); 807*2b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i]->description)); 808*2b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i])); 809cdf32b93SJeremy L Thompson } 810*2b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels)); 811*2b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*ctx)->ceed)); 812*2b730f8bSJeremy L Thompson CeedCall(CeedFree(ctx)); 813cdf32b93SJeremy L Thompson 814e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 815777ff853SJeremy L Thompson } 816777ff853SJeremy L Thompson 817777ff853SJeremy L Thompson /// @} 818