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> 92b730f8bSJeremy L Thompson #include <ceed/backend.h> 102b730f8bSJeremy 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 27*ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 28*ea61e9acSJeremy L Thompson @param[in] field_name Name of field 29*ea61e9acSJeremy L Thompson @param[out] 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 **/ 352b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx, const char *field_name, CeedInt *field_index) { 36cdf32b93SJeremy L Thompson *field_index = -1; 372b730f8bSJeremy L Thompson for (CeedInt i = 0; i < ctx->num_fields; i++) { 382b730f8bSJeremy L Thompson if (!strcmp(ctx->field_labels[i]->name, field_name)) *field_index = i; 392b730f8bSJeremy 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 46*ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 47*ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 48*ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 49*ea61e9acSJeremy L Thompson @param[in] field_description Description of field, or NULL for none 50*ea61e9acSJeremy L Thompson @param[in] field_type Field data type, such as double or int32 51*ea61e9acSJeremy L Thompson @param[in] field_size Size of field, in bytes 52*ea61e9acSJeremy L Thompson @param[in] 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 **/ 582b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, const char *field_description, 592b730f8bSJeremy 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; 622b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index)); 632b730f8bSJeremy L Thompson if (field_index != -1) { 64cdf32b93SJeremy L Thompson // LCOV_EXCL_START 652b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" already registered", field_name); 66cdf32b93SJeremy L Thompson // LCOV_EXCL_STOP 672b730f8bSJeremy L Thompson } 68cdf32b93SJeremy L Thompson 69cdf32b93SJeremy L Thompson // Allocate space for field data 70cdf32b93SJeremy L Thompson if (ctx->num_fields == 0) { 712b730f8bSJeremy 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) { 742b730f8bSJeremy L Thompson CeedCall(CeedRealloc(2 * ctx->max_fields, &ctx->field_labels)); 75cdf32b93SJeremy L Thompson ctx->max_fields *= 2; 76cdf32b93SJeremy L Thompson } 772b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &ctx->field_labels[ctx->num_fields])); 78cdf32b93SJeremy L Thompson 79cdf32b93SJeremy L Thompson // Copy field data 802b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_name, (char **)&ctx->field_labels[ctx->num_fields]->name)); 812b730f8bSJeremy 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 /** 91*ea61e9acSJeremy L Thompson @brief Destroy user data held by CeedQFunctionContext, using function set by CeedQFunctionContextSetDataDestroy, if applicable 923b190ab8SJeremy L Thompson 933b190ab8SJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to destroy user data 943b190ab8SJeremy L Thompson 953b190ab8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 963b190ab8SJeremy L Thompson 973b190ab8SJeremy L Thompson @ref Developer 983b190ab8SJeremy L Thompson **/ 993b190ab8SJeremy L Thompson static int CeedQFunctionContextDestroyData(CeedQFunctionContext ctx) { 1003b190ab8SJeremy L Thompson if (ctx->DataDestroy) { 1012b730f8bSJeremy L Thompson CeedCall(ctx->DataDestroy(ctx)); 1023b190ab8SJeremy L Thompson } else { 1033b190ab8SJeremy L Thompson CeedQFunctionContextDataDestroyUser data_destroy_function; 1043b190ab8SJeremy L Thompson CeedMemType data_destroy_mem_type; 1053b190ab8SJeremy L Thompson 1062b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function)); 1073b190ab8SJeremy L Thompson if (data_destroy_function) { 1083b190ab8SJeremy L Thompson void *data; 1093b190ab8SJeremy L Thompson 1102b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, data_destroy_mem_type, &data)); 1112b730f8bSJeremy L Thompson CeedCall(data_destroy_function(data)); 1122b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, &data)); 1133b190ab8SJeremy L Thompson } 1143b190ab8SJeremy L Thompson } 1153b190ab8SJeremy L Thompson 1163b190ab8SJeremy L Thompson return CEED_ERROR_SUCCESS; 1173b190ab8SJeremy L Thompson } 1183b190ab8SJeremy L Thompson 119cdf32b93SJeremy L Thompson /// @} 120cdf32b93SJeremy L Thompson 121cdf32b93SJeremy L Thompson /// ---------------------------------------------------------------------------- 122777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API 123777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 124777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend 125777ff853SJeremy L Thompson /// @{ 126777ff853SJeremy L Thompson 127777ff853SJeremy L Thompson /** 128777ff853SJeremy L Thompson @brief Get the Ceed associated with a CeedQFunctionContext 129777ff853SJeremy L Thompson 130*ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 131777ff853SJeremy L Thompson @param[out] ceed Variable to store Ceed 132777ff853SJeremy L Thompson 133777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 134777ff853SJeremy L Thompson 135777ff853SJeremy L Thompson @ref Backend 136777ff853SJeremy L Thompson **/ 137777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) { 138777ff853SJeremy L Thompson *ceed = ctx->ceed; 139e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 140777ff853SJeremy L Thompson } 141777ff853SJeremy L Thompson 142777ff853SJeremy L Thompson /** 1439c774eddSJeremy L Thompson @brief Check for valid data in a CeedQFunctionContext 1449c774eddSJeremy L Thompson 145*ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to check validity 1469c774eddSJeremy L Thompson @param[out] has_valid_data Variable to store validity 1479c774eddSJeremy L Thompson 1489c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1499c774eddSJeremy L Thompson 1509c774eddSJeremy L Thompson @ref Backend 1519c774eddSJeremy L Thompson **/ 1522b730f8bSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx, bool *has_valid_data) { 1532b730f8bSJeremy L Thompson if (!ctx->HasValidData) { 1549c774eddSJeremy L Thompson // LCOV_EXCL_START 1552b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support HasValidData"); 1569c774eddSJeremy L Thompson // LCOV_EXCL_STOP 1572b730f8bSJeremy L Thompson } 1589c774eddSJeremy L Thompson 1592b730f8bSJeremy L Thompson CeedCall(ctx->HasValidData(ctx, has_valid_data)); 1609c774eddSJeremy L Thompson 1619c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 1629c774eddSJeremy L Thompson } 1639c774eddSJeremy L Thompson 1649c774eddSJeremy L Thompson /** 165*ea61e9acSJeremy L Thompson @brief Check for borrowed data of a specific CeedMemType in a CeedQFunctionContext 1669c774eddSJeremy L Thompson 167*ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to check 168*ea61e9acSJeremy L Thompson @param[in] mem_type Memory type to check 1699c774eddSJeremy L Thompson @param[out] has_borrowed_data_of_type Variable to store result 1709c774eddSJeremy L Thompson 1719c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1729c774eddSJeremy L Thompson 1739c774eddSJeremy L Thompson @ref Backend 1749c774eddSJeremy L Thompson **/ 1752b730f8bSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx, CeedMemType mem_type, bool *has_borrowed_data_of_type) { 1762b730f8bSJeremy L Thompson if (!ctx->HasBorrowedDataOfType) { 1779c774eddSJeremy L Thompson // LCOV_EXCL_START 1782b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support HasBorrowedDataOfType"); 1799c774eddSJeremy L Thompson // LCOV_EXCL_STOP 1802b730f8bSJeremy L Thompson } 1819c774eddSJeremy L Thompson 1822b730f8bSJeremy L Thompson CeedCall(ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type)); 1839c774eddSJeremy L Thompson 1849c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 1859c774eddSJeremy L Thompson } 1869c774eddSJeremy L Thompson 1879c774eddSJeremy L Thompson /** 188777ff853SJeremy L Thompson @brief Get the state of a CeedQFunctionContext 189777ff853SJeremy L Thompson 190*ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to retrieve state 191777ff853SJeremy L Thompson @param[out] state Variable to store state 192777ff853SJeremy L Thompson 193777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 194777ff853SJeremy L Thompson 195777ff853SJeremy L Thompson @ref Backend 196777ff853SJeremy L Thompson **/ 197777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) { 198777ff853SJeremy L Thompson *state = ctx->state; 199e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 200777ff853SJeremy L Thompson } 201777ff853SJeremy L Thompson 202777ff853SJeremy L Thompson /** 203777ff853SJeremy L Thompson @brief Get backend data of a CeedQFunctionContext 204777ff853SJeremy L Thompson 205*ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 206777ff853SJeremy L Thompson @param[out] data Variable to store data 207777ff853SJeremy L Thompson 208777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 209777ff853SJeremy L Thompson 210777ff853SJeremy L Thompson @ref Backend 211777ff853SJeremy L Thompson **/ 212777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) { 213777ff853SJeremy L Thompson *(void **)data = ctx->data; 214e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 215777ff853SJeremy L Thompson } 216777ff853SJeremy L Thompson 217777ff853SJeremy L Thompson /** 218777ff853SJeremy L Thompson @brief Set backend data of a CeedQFunctionContext 219777ff853SJeremy L Thompson 220*ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 221*ea61e9acSJeremy L Thompson @param[in] data Data to set 222777ff853SJeremy L Thompson 223777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 224777ff853SJeremy L Thompson 225777ff853SJeremy L Thompson @ref Backend 226777ff853SJeremy L Thompson **/ 227777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) { 228777ff853SJeremy L Thompson ctx->data = data; 229e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 230777ff853SJeremy L Thompson } 231777ff853SJeremy L Thompson 23234359f16Sjeremylt /** 233*ea61e9acSJeremy L Thompson @brief Get label for a registered QFunctionContext field, or `NULL` if no field has been registered with this `field_name` 234e6a0ab89SJeremy L Thompson 235e6a0ab89SJeremy L Thompson @param[in] ctx CeedQFunctionContext 236e6a0ab89SJeremy L Thompson @param[in] field_name Name of field to retrieve label 237e6a0ab89SJeremy L Thompson @param[out] field_label Variable to field label 238e6a0ab89SJeremy L Thompson 239e6a0ab89SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 240e6a0ab89SJeremy L Thompson 2413e1e85abSJeremy L Thompson @ref Backend 242e6a0ab89SJeremy L Thompson **/ 2432b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx, const char *field_name, CeedContextFieldLabel *field_label) { 244e6a0ab89SJeremy L Thompson CeedInt field_index; 2452b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index)); 246e6a0ab89SJeremy L Thompson 247e6a0ab89SJeremy L Thompson if (field_index != -1) { 248e6a0ab89SJeremy L Thompson *field_label = ctx->field_labels[field_index]; 249e6a0ab89SJeremy L Thompson } else { 250e6a0ab89SJeremy L Thompson *field_label = NULL; 251e6a0ab89SJeremy L Thompson } 252e6a0ab89SJeremy L Thompson 253e6a0ab89SJeremy L Thompson return CEED_ERROR_SUCCESS; 254e6a0ab89SJeremy L Thompson } 255e6a0ab89SJeremy L Thompson 256e6a0ab89SJeremy L Thompson /** 257d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field 258d8dd9a91SJeremy L Thompson 259*ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 260*ea61e9acSJeremy L Thompson @param[in] field_label Label of field to set 261*ea61e9acSJeremy L Thompson @param[in] field_type Type of field to set 262*ea61e9acSJeremy L Thompson @param[in] value Value to set 263d8dd9a91SJeremy L Thompson 264d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 265d8dd9a91SJeremy L Thompson 2663e1e85abSJeremy L Thompson @ref Backend 267d8dd9a91SJeremy L Thompson **/ 2682b730f8bSJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *value) { 2693668ca4bSJeremy L Thompson // Check field type 2702b730f8bSJeremy L Thompson if (field_label->type != field_type) { 271d8dd9a91SJeremy L Thompson // LCOV_EXCL_START 2722b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", 2732b730f8bSJeremy L Thompson field_label->name, CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 274d8dd9a91SJeremy L Thompson // LCOV_EXCL_STOP 2752b730f8bSJeremy L Thompson } 276d8dd9a91SJeremy L Thompson 277d8dd9a91SJeremy L Thompson char *data; 2782b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data)); 2793668ca4bSJeremy L Thompson memcpy(&data[field_label->offset], value, field_label->size); 2802b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, &data)); 281d8dd9a91SJeremy L Thompson 282d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 283d8dd9a91SJeremy L Thompson } 284d8dd9a91SJeremy L Thompson 285d8dd9a91SJeremy L Thompson /** 286bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value 287bfacc300SJeremy L Thompson 288*ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 289*ea61e9acSJeremy L Thompson @param[in] field_label Label for field to register 290*ea61e9acSJeremy L Thompson @param[in] values Values to set 291bfacc300SJeremy L Thompson 292bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 293bfacc300SJeremy L Thompson 2943e1e85abSJeremy L Thompson @ref Backend 295bfacc300SJeremy L Thompson **/ 2962b730f8bSJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, double *values) { 2972b730f8bSJeremy L Thompson if (!field_label) { 298bfacc300SJeremy L Thompson // LCOV_EXCL_START 2992b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 300bfacc300SJeremy L Thompson // LCOV_EXCL_STOP 3012b730f8bSJeremy L Thompson } 302bfacc300SJeremy L Thompson 3032b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values)); 304bfacc300SJeremy L Thompson 305bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 306bfacc300SJeremy L Thompson } 307bfacc300SJeremy L Thompson 308bfacc300SJeremy L Thompson /** 309bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding an int32 value 310bfacc300SJeremy L Thompson 311*ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 312*ea61e9acSJeremy L Thompson @param[in] field_label Label for field to register 313*ea61e9acSJeremy L Thompson @param[in] values Values to set 314bfacc300SJeremy L Thompson 315bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 316bfacc300SJeremy L Thompson 3173e1e85abSJeremy L Thompson @ref Backend 318bfacc300SJeremy L Thompson **/ 3192b730f8bSJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, int *values) { 3202b730f8bSJeremy L Thompson if (!field_label) { 321bfacc300SJeremy L Thompson // LCOV_EXCL_START 3222b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 323bfacc300SJeremy L Thompson // LCOV_EXCL_STOP 3242b730f8bSJeremy L Thompson } 325bfacc300SJeremy L Thompson 3262b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values)); 327bfacc300SJeremy L Thompson 328bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 329bfacc300SJeremy L Thompson } 330bfacc300SJeremy L Thompson 331bfacc300SJeremy L Thompson /** 3322e64a2b9SJeremy L Thompson @brief Get additional destroy routine for CeedQFunctionContext user data 3332e64a2b9SJeremy L Thompson 3342e64a2b9SJeremy L Thompson @param[in] ctx CeedQFunctionContext to get user destroy function 3352e64a2b9SJeremy L Thompson @param[out] f_mem_type Memory type to use when passing data into `f` 3362e64a2b9SJeremy L Thompson @param[out] f Additional routine to use to destroy user data 3372e64a2b9SJeremy L Thompson 3382e64a2b9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3392e64a2b9SJeremy L Thompson 3402e64a2b9SJeremy L Thompson @ref Backend 3412e64a2b9SJeremy L Thompson **/ 3422b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx, CeedMemType *f_mem_type, CeedQFunctionContextDataDestroyUser *f) { 3432e64a2b9SJeremy L Thompson if (f_mem_type) *f_mem_type = ctx->data_destroy_mem_type; 3442e64a2b9SJeremy L Thompson if (f) *f = ctx->data_destroy_function; 3452e64a2b9SJeremy L Thompson return CEED_ERROR_SUCCESS; 3462e64a2b9SJeremy L Thompson } 3472e64a2b9SJeremy L Thompson 3482e64a2b9SJeremy L Thompson /** 34934359f16Sjeremylt @brief Increment the reference counter for a CeedQFunctionContext 35034359f16Sjeremylt 351*ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to increment the reference counter 35234359f16Sjeremylt 35334359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 35434359f16Sjeremylt 35534359f16Sjeremylt @ref Backend 35634359f16Sjeremylt **/ 3579560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) { 35834359f16Sjeremylt ctx->ref_count++; 35934359f16Sjeremylt return CEED_ERROR_SUCCESS; 36034359f16Sjeremylt } 36134359f16Sjeremylt 362777ff853SJeremy L Thompson /// @} 363777ff853SJeremy L Thompson 364777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 365777ff853SJeremy L Thompson /// CeedQFunctionContext Public API 366777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 367777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser 368777ff853SJeremy L Thompson /// @{ 369777ff853SJeremy L Thompson 370777ff853SJeremy L Thompson /** 371777ff853SJeremy L Thompson @brief Create a CeedQFunctionContext for storing CeedQFunction user context data 372777ff853SJeremy L Thompson 373*ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedQFunctionContext will be created 374*ea61e9acSJeremy L Thompson @param[out] ctx Address of the variable where the newly created CeedQFunctionContext will be stored 375777ff853SJeremy L Thompson 376777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 377777ff853SJeremy L Thompson 378777ff853SJeremy L Thompson @ref User 379777ff853SJeremy L Thompson **/ 380777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) { 381777ff853SJeremy L Thompson if (!ceed->QFunctionContextCreate) { 382777ff853SJeremy L Thompson Ceed delegate; 3832b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Context")); 384777ff853SJeremy L Thompson 3852b730f8bSJeremy L Thompson if (!delegate) { 386777ff853SJeremy L Thompson // LCOV_EXCL_START 3872b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextCreate"); 388777ff853SJeremy L Thompson // LCOV_EXCL_STOP 3892b730f8bSJeremy L Thompson } 390777ff853SJeremy L Thompson 3912b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextCreate(delegate, ctx)); 392e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 393777ff853SJeremy L Thompson } 394777ff853SJeremy L Thompson 3952b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, ctx)); 396777ff853SJeremy L Thompson (*ctx)->ceed = ceed; 3972b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 398d1d35e2fSjeremylt (*ctx)->ref_count = 1; 3992b730f8bSJeremy L Thompson CeedCall(ceed->QFunctionContextCreate(*ctx)); 400e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 401777ff853SJeremy L Thompson } 402777ff853SJeremy L Thompson 403777ff853SJeremy L Thompson /** 404*ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedQFunctionContext. 405*ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedQFunctionContextDestroy()`. 406*ea61e9acSJeremy L Thompson Note: If `*ctx_copy` is non-NULL, then it is assumed that `*ctx_copy` is a pointer to a CeedQFunctionContext. 407*ea61e9acSJeremy L Thompson This CeedQFunctionContext will be destroyed if `*ctx_copy` is the only reference to this CeedQFunctionContext. 4089560d06aSjeremylt 409*ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to copy reference to 410*ea61e9acSJeremy L Thompson @param[in,out] ctx_copy Variable to store copied reference 4119560d06aSjeremylt 4129560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 4139560d06aSjeremylt 4149560d06aSjeremylt @ref User 4159560d06aSjeremylt **/ 4162b730f8bSJeremy L Thompson int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, CeedQFunctionContext *ctx_copy) { 4172b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextReference(ctx)); 4182b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(ctx_copy)); 4199560d06aSjeremylt *ctx_copy = ctx; 4209560d06aSjeremylt return CEED_ERROR_SUCCESS; 4219560d06aSjeremylt } 4229560d06aSjeremylt 4239560d06aSjeremylt /** 424*ea61e9acSJeremy L Thompson @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated data if applicable. 425*ea61e9acSJeremy L Thompson The backend may copy values to a different memtype, such as during @ref CeedQFunctionApply(). 426777ff853SJeremy L Thompson See also @ref CeedQFunctionContextTakeData(). 427777ff853SJeremy L Thompson 428*ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 429*ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the data being passed 430*ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the data 431*ea61e9acSJeremy L Thompson @param[in] size Size of data, in bytes 432*ea61e9acSJeremy L Thompson @param[in] data Data to be used 433777ff853SJeremy L Thompson 434777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 435777ff853SJeremy L Thompson 436777ff853SJeremy L Thompson @ref User 437777ff853SJeremy L Thompson **/ 4382b730f8bSJeremy L Thompson int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, size_t size, void *data) { 4392b730f8bSJeremy L Thompson if (!ctx->SetData) { 440777ff853SJeremy L Thompson // LCOV_EXCL_START 4412b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextSetData"); 442777ff853SJeremy L Thompson // LCOV_EXCL_STOP 4432b730f8bSJeremy L Thompson } 4442b730f8bSJeremy L Thompson if (ctx->state % 2 == 1) { 445777ff853SJeremy L Thompson // LCOV_EXCL_START 4462b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 447777ff853SJeremy L Thompson // LCOV_EXCL_STOP 4482b730f8bSJeremy L Thompson } 449777ff853SJeremy L Thompson 4502b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroyData(ctx)); 451d1d35e2fSjeremylt ctx->ctx_size = size; 4522b730f8bSJeremy L Thompson CeedCall(ctx->SetData(ctx, mem_type, copy_mode, data)); 453777ff853SJeremy L Thompson ctx->state += 2; 454e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 455777ff853SJeremy L Thompson } 456777ff853SJeremy L Thompson 457777ff853SJeremy L Thompson /** 458891038deSjeremylt @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type. 459891038deSjeremylt The caller is responsible for managing and freeing the memory. 460891038deSjeremylt 461*ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 462*ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 463*ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 464891038deSjeremylt @param[out] data Data on memory type mem_type 465891038deSjeremylt 466891038deSjeremylt @return An error code: 0 - success, otherwise - failure 467891038deSjeremylt 468891038deSjeremylt @ref User 469891038deSjeremylt **/ 4702b730f8bSJeremy L Thompson int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 4719c774eddSJeremy L Thompson bool has_valid_data = true; 4722b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 4732b730f8bSJeremy L Thompson if (!has_valid_data) { 4749c774eddSJeremy L Thompson // LCOV_EXCL_START 4752b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to take, must set data"); 4769c774eddSJeremy L Thompson // LCOV_EXCL_STOP 4772b730f8bSJeremy L Thompson } 4789c774eddSJeremy L Thompson 4792b730f8bSJeremy L Thompson if (!ctx->TakeData) { 480891038deSjeremylt // LCOV_EXCL_START 4812b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support TakeData"); 482891038deSjeremylt // LCOV_EXCL_STOP 4832b730f8bSJeremy L Thompson } 4842b730f8bSJeremy L Thompson if (ctx->state % 2 == 1) { 485891038deSjeremylt // LCOV_EXCL_START 4862b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 487891038deSjeremylt // LCOV_EXCL_STOP 4882b730f8bSJeremy L Thompson } 489891038deSjeremylt 4909c774eddSJeremy L Thompson bool has_borrowed_data_of_type = true; 4912b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, &has_borrowed_data_of_type)); 4922b730f8bSJeremy L Thompson if (!has_borrowed_data_of_type) { 4939c774eddSJeremy L Thompson // LCOV_EXCL_START 4942b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no borowed %s data, must set data with CeedQFunctionContextSetData", 4959c774eddSJeremy L Thompson CeedMemTypes[mem_type]); 4969c774eddSJeremy L Thompson // LCOV_EXCL_STOP 4972b730f8bSJeremy L Thompson } 4989c774eddSJeremy L Thompson 499891038deSjeremylt void *temp_data = NULL; 5002b730f8bSJeremy L Thompson CeedCall(ctx->TakeData(ctx, mem_type, &temp_data)); 501891038deSjeremylt if (data) (*(void **)data) = temp_data; 502891038deSjeremylt return CEED_ERROR_SUCCESS; 503891038deSjeremylt } 504891038deSjeremylt 505891038deSjeremylt /** 506777ff853SJeremy L Thompson @brief Get read/write access to a CeedQFunctionContext via the specified memory type. 507777ff853SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 508777ff853SJeremy L Thompson 509*ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 510*ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 511*ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 512d1d35e2fSjeremylt @param[out] data Data on memory type mem_type 513777ff853SJeremy L Thompson 514*ea61e9acSJeremy L Thompson @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions provide access to array pointers in the desired memory 515*ea61e9acSJeremy L Thompson space. Pairing get/restore allows the Context to track access. 516777ff853SJeremy L Thompson 517777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 518777ff853SJeremy L Thompson 519777ff853SJeremy L Thompson @ref User 520777ff853SJeremy L Thompson **/ 5212b730f8bSJeremy L Thompson int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 5222b730f8bSJeremy L Thompson if (!ctx->GetData) { 523777ff853SJeremy L Thompson // LCOV_EXCL_START 5242b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetData"); 525777ff853SJeremy L Thompson // LCOV_EXCL_STOP 5262b730f8bSJeremy L Thompson } 5272b730f8bSJeremy L Thompson if (ctx->state % 2 == 1) { 528777ff853SJeremy L Thompson // LCOV_EXCL_START 5292b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 530777ff853SJeremy L Thompson // LCOV_EXCL_STOP 5312b730f8bSJeremy L Thompson } 5322b730f8bSJeremy L Thompson if (ctx->num_readers > 0) { 53328bfd0b7SJeremy L Thompson // LCOV_EXCL_START 5342b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, a process has read access"); 53528bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 5362b730f8bSJeremy L Thompson } 53728bfd0b7SJeremy L Thompson 5389c774eddSJeremy L Thompson bool has_valid_data = true; 5392b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 5402b730f8bSJeremy L Thompson if (!has_valid_data) { 5419c774eddSJeremy L Thompson // LCOV_EXCL_START 5422b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data"); 5439c774eddSJeremy L Thompson // LCOV_EXCL_STOP 5442b730f8bSJeremy L Thompson } 5459c774eddSJeremy L Thompson 5462b730f8bSJeremy L Thompson CeedCall(ctx->GetData(ctx, mem_type, data)); 54728bfd0b7SJeremy L Thompson ctx->state++; 54828bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 54928bfd0b7SJeremy L Thompson } 55028bfd0b7SJeremy L Thompson 55128bfd0b7SJeremy L Thompson /** 55228bfd0b7SJeremy L Thompson @brief Get read only access to a CeedQFunctionContext via the specified memory type. 55328bfd0b7SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 55428bfd0b7SJeremy L Thompson 555*ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 556*ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 557*ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 55828bfd0b7SJeremy L Thompson @param[out] data Data on memory type mem_type 55928bfd0b7SJeremy L Thompson 560*ea61e9acSJeremy L Thompson @note The CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead() functions provide access to array pointers in the desired 561*ea61e9acSJeremy L Thompson memory space. Pairing get/restore allows the Context to track access. 56228bfd0b7SJeremy L Thompson 56328bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 56428bfd0b7SJeremy L Thompson 56528bfd0b7SJeremy L Thompson @ref User 56628bfd0b7SJeremy L Thompson **/ 5672b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 5682b730f8bSJeremy L Thompson if (!ctx->GetDataRead) { 56928bfd0b7SJeremy L Thompson // LCOV_EXCL_START 5702b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetDataRead"); 57128bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 5722b730f8bSJeremy L Thompson } 5732b730f8bSJeremy L Thompson if (ctx->state % 2 == 1) { 57428bfd0b7SJeremy L Thompson // LCOV_EXCL_START 5752b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 57628bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 5772b730f8bSJeremy L Thompson } 57828bfd0b7SJeremy L Thompson 57928bfd0b7SJeremy L Thompson bool has_valid_data = true; 5802b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 5812b730f8bSJeremy L Thompson if (!has_valid_data) { 58228bfd0b7SJeremy L Thompson // LCOV_EXCL_START 5832b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data"); 58428bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 5852b730f8bSJeremy L Thompson } 58628bfd0b7SJeremy L Thompson 5872b730f8bSJeremy L Thompson CeedCall(ctx->GetDataRead(ctx, mem_type, data)); 58828bfd0b7SJeremy L Thompson ctx->num_readers++; 589e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 590777ff853SJeremy L Thompson } 591777ff853SJeremy L Thompson 592777ff853SJeremy L Thompson /** 593777ff853SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetData() 594777ff853SJeremy L Thompson 595*ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to restore 596*ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 597777ff853SJeremy L Thompson 598777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 599777ff853SJeremy L Thompson 600777ff853SJeremy L Thompson @ref User 601777ff853SJeremy L Thompson **/ 602777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) { 6032b730f8bSJeremy L Thompson if (ctx->state % 2 != 1) { 604777ff853SJeremy L Thompson // LCOV_EXCL_START 6052b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted"); 606777ff853SJeremy L Thompson // LCOV_EXCL_STOP 6072b730f8bSJeremy L Thompson } 608777ff853SJeremy L Thompson 609706efda3SJeremy L Thompson if (ctx->RestoreData) { 6102b730f8bSJeremy L Thompson CeedCall(ctx->RestoreData(ctx)); 611706efda3SJeremy L Thompson } 612777ff853SJeremy L Thompson *(void **)data = NULL; 61328bfd0b7SJeremy L Thompson ctx->state++; 61428bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 61528bfd0b7SJeremy L Thompson } 61628bfd0b7SJeremy L Thompson 61728bfd0b7SJeremy L Thompson /** 61828bfd0b7SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead() 61928bfd0b7SJeremy L Thompson 620*ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to restore 621*ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 62228bfd0b7SJeremy L Thompson 62328bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 62428bfd0b7SJeremy L Thompson 62528bfd0b7SJeremy L Thompson @ref User 62628bfd0b7SJeremy L Thompson **/ 62728bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) { 6282b730f8bSJeremy L Thompson if (ctx->num_readers == 0) { 62928bfd0b7SJeremy L Thompson // LCOV_EXCL_START 6302b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted"); 63128bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 6322b730f8bSJeremy L Thompson } 63328bfd0b7SJeremy L Thompson 63475a19770SJeremy L Thompson ctx->num_readers--; 63575a19770SJeremy L Thompson if (ctx->num_readers == 0 && ctx->RestoreDataRead) { 6362b730f8bSJeremy L Thompson CeedCall(ctx->RestoreDataRead(ctx)); 63728bfd0b7SJeremy L Thompson } 63828bfd0b7SJeremy L Thompson *(void **)data = NULL; 63975a19770SJeremy L Thompson 640e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 641777ff853SJeremy L Thompson } 642777ff853SJeremy L Thompson 643777ff853SJeremy L Thompson /** 644cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a double precision value 645cdf32b93SJeremy L Thompson 646*ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 647*ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 648*ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 649*ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 650*ea61e9acSJeremy L Thompson @param[in] field_description Description of field, or NULL for none 651cdf32b93SJeremy L Thompson 652cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 653cdf32b93SJeremy L Thompson 654cdf32b93SJeremy L Thompson @ref User 655cdf32b93SJeremy L Thompson **/ 6562b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 657cdf32b93SJeremy L Thompson const char *field_description) { 6582b730f8bSJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double), num_values); 659cdf32b93SJeremy L Thompson } 660cdf32b93SJeremy L Thompson 661cdf32b93SJeremy L Thompson /** 662cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a int32 value 663cdf32b93SJeremy L Thompson 664*ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 665*ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 666*ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 667*ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 668*ea61e9acSJeremy L Thompson @param[in] field_description Description of field, or NULL for none 669cdf32b93SJeremy L Thompson 670cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 671cdf32b93SJeremy L Thompson 672cdf32b93SJeremy L Thompson @ref User 673cdf32b93SJeremy L Thompson **/ 6742b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 675cdf32b93SJeremy L Thompson const char *field_description) { 6762b730f8bSJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int), num_values); 677cdf32b93SJeremy L Thompson } 678cdf32b93SJeremy L Thompson 679cdf32b93SJeremy L Thompson /** 6803668ca4bSJeremy L Thompson @brief Get labels for all registered QFunctionContext fields 681cdf32b93SJeremy L Thompson 682*ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 6833668ca4bSJeremy L Thompson @param[out] field_labels Variable to hold array of field labels 684cdf32b93SJeremy L Thompson @param[out] num_fields Length of field descriptions array 685cdf32b93SJeremy L Thompson 686cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 687cdf32b93SJeremy L Thompson 688cdf32b93SJeremy L Thompson @ref User 689cdf32b93SJeremy L Thompson **/ 6902b730f8bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, const CeedContextFieldLabel **field_labels, CeedInt *num_fields) { 6913668ca4bSJeremy L Thompson *field_labels = ctx->field_labels; 692cdf32b93SJeremy L Thompson *num_fields = ctx->num_fields; 693cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 694cdf32b93SJeremy L Thompson } 695cdf32b93SJeremy L Thompson 696cdf32b93SJeremy L Thompson /** 6970f86cbe7SJeremy L Thompson @brief Get the descriptive information about a CeedContextFieldLabel 6980f86cbe7SJeremy L Thompson 6990f86cbe7SJeremy L Thompson @param[in] label CeedContextFieldLabel 7000f86cbe7SJeremy L Thompson @param[out] field_name Name of labeled field 7010f86cbe7SJeremy L Thompson @param[out] field_description Description of field, or NULL for none 7027bfe0f0eSJeremy L Thompson @param[out] num_values Number of values registered 7030f86cbe7SJeremy L Thompson @param[out] field_type CeedContextFieldType 7040f86cbe7SJeremy L Thompson 7050f86cbe7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7060f86cbe7SJeremy L Thompson 7070f86cbe7SJeremy L Thompson @ref User 7080f86cbe7SJeremy L Thompson **/ 7092b730f8bSJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, const char **field_name, const char **field_description, size_t *num_values, 7100f86cbe7SJeremy L Thompson CeedContextFieldType *field_type) { 7110f86cbe7SJeremy L Thompson if (field_name) *field_name = label->name; 7120f86cbe7SJeremy L Thompson if (field_description) *field_description = label->description; 7137bfe0f0eSJeremy L Thompson if (num_values) *num_values = label->num_values; 7140f86cbe7SJeremy L Thompson if (field_type) *field_type = label->type; 7150f86cbe7SJeremy L Thompson return CEED_ERROR_SUCCESS; 7160f86cbe7SJeremy L Thompson } 7170f86cbe7SJeremy L Thompson 7180f86cbe7SJeremy L Thompson /** 71980a9ef05SNatalie Beams @brief Get data size for a Context 72080a9ef05SNatalie Beams 721*ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 72280a9ef05SNatalie Beams @param[out] ctx_size Variable to store size of context data values 72380a9ef05SNatalie Beams 72480a9ef05SNatalie Beams @return An error code: 0 - success, otherwise - failure 72580a9ef05SNatalie Beams 72680a9ef05SNatalie Beams @ref User 72780a9ef05SNatalie Beams **/ 7282b730f8bSJeremy L Thompson int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, size_t *ctx_size) { 72980a9ef05SNatalie Beams *ctx_size = ctx->ctx_size; 73080a9ef05SNatalie Beams return CEED_ERROR_SUCCESS; 73180a9ef05SNatalie Beams } 73280a9ef05SNatalie Beams 73380a9ef05SNatalie Beams /** 734777ff853SJeremy L Thompson @brief View a CeedQFunctionContext 735777ff853SJeremy L Thompson 736777ff853SJeremy L Thompson @param[in] ctx CeedQFunctionContext to view 737777ff853SJeremy L Thompson @param[in] stream Filestream to write to 738777ff853SJeremy L Thompson 739777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 740777ff853SJeremy L Thompson 741777ff853SJeremy L Thompson @ref User 742777ff853SJeremy L Thompson **/ 743777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) { 744777ff853SJeremy L Thompson fprintf(stream, "CeedQFunctionContext\n"); 745d1d35e2fSjeremylt fprintf(stream, " Context Data Size: %ld\n", ctx->ctx_size); 7463668ca4bSJeremy L Thompson for (CeedInt i = 0; i < ctx->num_fields; i++) { 7473668ca4bSJeremy L Thompson // LCOV_EXCL_START 7482b730f8bSJeremy L Thompson fprintf(stream, " Labeled %s field: %s\n", CeedContextFieldTypes[ctx->field_labels[i]->type], ctx->field_labels[i]->name); 7493668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 7503668ca4bSJeremy L Thompson } 751e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 752777ff853SJeremy L Thompson } 753777ff853SJeremy L Thompson 754777ff853SJeremy L Thompson /** 7552790b72bSJeremy L Thompson @brief Set additional destroy routine for CeedQFunctionContext user data 7562790b72bSJeremy L Thompson 757*ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to set user destroy function 7582e64a2b9SJeremy L Thompson @param[in] f_mem_type Memory type to use when passing data into `f` 7592e64a2b9SJeremy L Thompson @param[in] f Additional routine to use to destroy user data 7602790b72bSJeremy L Thompson 7612790b72bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7622790b72bSJeremy L Thompson 7632790b72bSJeremy L Thompson @ref User 7642790b72bSJeremy L Thompson **/ 7652b730f8bSJeremy L Thompson int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) { 7662b730f8bSJeremy L Thompson if (!f) { 7672790b72bSJeremy L Thompson // LCOV_EXCL_START 7682b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Must provide valid callback function for destroying user data"); 7692790b72bSJeremy L Thompson // LCOV_EXCL_STOP 7702b730f8bSJeremy L Thompson } 7712790b72bSJeremy L Thompson ctx->data_destroy_mem_type = f_mem_type; 7722790b72bSJeremy L Thompson ctx->data_destroy_function = f; 7732790b72bSJeremy L Thompson return CEED_ERROR_SUCCESS; 7742790b72bSJeremy L Thompson } 7752790b72bSJeremy L Thompson 7762790b72bSJeremy L Thompson /** 777777ff853SJeremy L Thompson @brief Destroy a CeedQFunctionContext 778777ff853SJeremy L Thompson 779*ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to destroy 780777ff853SJeremy L Thompson 781777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 782777ff853SJeremy L Thompson 783777ff853SJeremy L Thompson @ref User 784777ff853SJeremy L Thompson **/ 785777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) { 7862b730f8bSJeremy L Thompson if (!*ctx || --(*ctx)->ref_count > 0) return CEED_ERROR_SUCCESS; 787777ff853SJeremy L Thompson 7882b730f8bSJeremy L Thompson if ((*ctx) && ((*ctx)->state % 2) == 1) { 789777ff853SJeremy L Thompson // LCOV_EXCL_START 7902b730f8bSJeremy L Thompson return CeedError((*ctx)->ceed, 1, "Cannot destroy CeedQFunctionContext, the access lock is in use"); 791777ff853SJeremy L Thompson // LCOV_EXCL_STOP 7922b730f8bSJeremy L Thompson } 793777ff853SJeremy L Thompson 7942b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroyData(*ctx)); 7952b730f8bSJeremy L Thompson if ((*ctx)->Destroy) CeedCall((*ctx)->Destroy(*ctx)); 796cdf32b93SJeremy L Thompson for (CeedInt i = 0; i < (*ctx)->num_fields; i++) { 7972b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i]->name)); 7982b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i]->description)); 7992b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i])); 800cdf32b93SJeremy L Thompson } 8012b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels)); 8022b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*ctx)->ceed)); 8032b730f8bSJeremy L Thompson CeedCall(CeedFree(ctx)); 804cdf32b93SJeremy L Thompson 805e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 806777ff853SJeremy L Thompson } 807777ff853SJeremy L Thompson 808777ff853SJeremy L Thompson /// @} 809