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> 949aac155SJeremy L Thompson #include <ceed.h> 102b730f8bSJeremy L Thompson #include <ceed/backend.h> 1149aac155SJeremy L Thompson #include <stdbool.h> 123d576824SJeremy L Thompson #include <stdint.h> 133d576824SJeremy L Thompson #include <stdio.h> 14cdf32b93SJeremy L Thompson #include <string.h> 15777ff853SJeremy L Thompson 16777ff853SJeremy L Thompson /// @file 17777ff853SJeremy L Thompson /// Implementation of public CeedQFunctionContext interfaces 18777ff853SJeremy L Thompson 19777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 20cdf32b93SJeremy L Thompson /// CeedQFunctionContext Library Internal Functions 21cdf32b93SJeremy L Thompson /// ---------------------------------------------------------------------------- 22cdf32b93SJeremy L Thompson /// @addtogroup CeedQFunctionDeveloper 23cdf32b93SJeremy L Thompson /// @{ 24cdf32b93SJeremy L Thompson 25cdf32b93SJeremy L Thompson /** 26cdf32b93SJeremy L Thompson @brief Get index for QFunctionContext field 27cdf32b93SJeremy L Thompson 28ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 29ea61e9acSJeremy L Thompson @param[in] field_name Name of field 30ea61e9acSJeremy L Thompson @param[out] field_index Index of field, or -1 if field is not registered 31cdf32b93SJeremy L Thompson 32cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 33cdf32b93SJeremy L Thompson 34cdf32b93SJeremy L Thompson @ref Developer 35cdf32b93SJeremy L Thompson **/ 362b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx, const char *field_name, CeedInt *field_index) { 37cdf32b93SJeremy L Thompson *field_index = -1; 382b730f8bSJeremy L Thompson for (CeedInt i = 0; i < ctx->num_fields; i++) { 392b730f8bSJeremy L Thompson if (!strcmp(ctx->field_labels[i]->name, field_name)) *field_index = i; 402b730f8bSJeremy L Thompson } 41cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 42cdf32b93SJeremy L Thompson } 43cdf32b93SJeremy L Thompson 44cdf32b93SJeremy L Thompson /** 45cdf32b93SJeremy L Thompson @brief Common function for registering QFunctionContext fields 46cdf32b93SJeremy L Thompson 47ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 48ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 49ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 50ea61e9acSJeremy L Thompson @param[in] field_description Description of field, or NULL for none 51ea61e9acSJeremy L Thompson @param[in] field_type Field data type, such as double or int32 52ea61e9acSJeremy L Thompson @param[in] field_size Size of field, in bytes 53ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 54cdf32b93SJeremy L Thompson 55cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 56cdf32b93SJeremy L Thompson 57cdf32b93SJeremy L Thompson @ref Developer 58cdf32b93SJeremy L Thompson **/ 592b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, const char *field_description, 602b730f8bSJeremy L Thompson CeedContextFieldType field_type, size_t field_size, size_t num_values) { 61cdf32b93SJeremy L Thompson // Check for duplicate 62cdf32b93SJeremy L Thompson CeedInt field_index = -1; 632b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index)); 64*6574a04fSJeremy L Thompson CeedCheck(field_index == -1, ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" already registered", field_name); 65cdf32b93SJeremy L Thompson 66cdf32b93SJeremy L Thompson // Allocate space for field data 67cdf32b93SJeremy L Thompson if (ctx->num_fields == 0) { 682b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &ctx->field_labels)); 69cdf32b93SJeremy L Thompson ctx->max_fields = 1; 70cdf32b93SJeremy L Thompson } else if (ctx->num_fields == ctx->max_fields) { 712b730f8bSJeremy L Thompson CeedCall(CeedRealloc(2 * ctx->max_fields, &ctx->field_labels)); 72cdf32b93SJeremy L Thompson ctx->max_fields *= 2; 73cdf32b93SJeremy L Thompson } 742b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &ctx->field_labels[ctx->num_fields])); 75cdf32b93SJeremy L Thompson 76cdf32b93SJeremy L Thompson // Copy field data 772b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_name, (char **)&ctx->field_labels[ctx->num_fields]->name)); 782b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_description, (char **)&ctx->field_labels[ctx->num_fields]->description)); 793668ca4bSJeremy L Thompson ctx->field_labels[ctx->num_fields]->type = field_type; 803668ca4bSJeremy L Thompson ctx->field_labels[ctx->num_fields]->offset = field_offset; 817bfe0f0eSJeremy L Thompson ctx->field_labels[ctx->num_fields]->size = field_size * num_values; 827bfe0f0eSJeremy L Thompson ctx->field_labels[ctx->num_fields]->num_values = num_values; 83cdf32b93SJeremy L Thompson ctx->num_fields++; 84cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 85cdf32b93SJeremy L Thompson } 86cdf32b93SJeremy L Thompson 873b190ab8SJeremy L Thompson /** 88ea61e9acSJeremy L Thompson @brief Destroy user data held by CeedQFunctionContext, using function set by CeedQFunctionContextSetDataDestroy, if applicable 893b190ab8SJeremy L Thompson 903b190ab8SJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to destroy user data 913b190ab8SJeremy L Thompson 923b190ab8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 933b190ab8SJeremy L Thompson 943b190ab8SJeremy L Thompson @ref Developer 953b190ab8SJeremy L Thompson **/ 963b190ab8SJeremy L Thompson static int CeedQFunctionContextDestroyData(CeedQFunctionContext ctx) { 973b190ab8SJeremy L Thompson if (ctx->DataDestroy) { 982b730f8bSJeremy L Thompson CeedCall(ctx->DataDestroy(ctx)); 993b190ab8SJeremy L Thompson } else { 1003b190ab8SJeremy L Thompson CeedQFunctionContextDataDestroyUser data_destroy_function; 1013b190ab8SJeremy L Thompson CeedMemType data_destroy_mem_type; 1023b190ab8SJeremy L Thompson 1032b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function)); 1043b190ab8SJeremy L Thompson if (data_destroy_function) { 1053b190ab8SJeremy L Thompson void *data; 1063b190ab8SJeremy L Thompson 1072b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, data_destroy_mem_type, &data)); 1082b730f8bSJeremy L Thompson CeedCall(data_destroy_function(data)); 1092b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, &data)); 1103b190ab8SJeremy L Thompson } 1113b190ab8SJeremy L Thompson } 1123b190ab8SJeremy L Thompson 1133b190ab8SJeremy L Thompson return CEED_ERROR_SUCCESS; 1143b190ab8SJeremy L Thompson } 1153b190ab8SJeremy L Thompson 116cdf32b93SJeremy L Thompson /// @} 117cdf32b93SJeremy L Thompson 118cdf32b93SJeremy L Thompson /// ---------------------------------------------------------------------------- 119777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API 120777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 121777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend 122777ff853SJeremy L Thompson /// @{ 123777ff853SJeremy L Thompson 124777ff853SJeremy L Thompson /** 125777ff853SJeremy L Thompson @brief Get the Ceed associated with a CeedQFunctionContext 126777ff853SJeremy L Thompson 127ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 128777ff853SJeremy L Thompson @param[out] ceed Variable to store Ceed 129777ff853SJeremy L Thompson 130777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 131777ff853SJeremy L Thompson 132777ff853SJeremy L Thompson @ref Backend 133777ff853SJeremy L Thompson **/ 134777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) { 135777ff853SJeremy L Thompson *ceed = ctx->ceed; 136e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 137777ff853SJeremy L Thompson } 138777ff853SJeremy L Thompson 139777ff853SJeremy L Thompson /** 1409c774eddSJeremy L Thompson @brief Check for valid data in a CeedQFunctionContext 1419c774eddSJeremy L Thompson 142ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to check validity 1439c774eddSJeremy L Thompson @param[out] has_valid_data Variable to store validity 1449c774eddSJeremy L Thompson 1459c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1469c774eddSJeremy L Thompson 1479c774eddSJeremy L Thompson @ref Backend 1489c774eddSJeremy L Thompson **/ 1492b730f8bSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx, bool *has_valid_data) { 150*6574a04fSJeremy L Thompson CeedCheck(ctx->HasValidData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support HasValidData"); 1512b730f8bSJeremy L Thompson CeedCall(ctx->HasValidData(ctx, has_valid_data)); 1529c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 1539c774eddSJeremy L Thompson } 1549c774eddSJeremy L Thompson 1559c774eddSJeremy L Thompson /** 156ea61e9acSJeremy L Thompson @brief Check for borrowed data of a specific CeedMemType in a CeedQFunctionContext 1579c774eddSJeremy L Thompson 158ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to check 159ea61e9acSJeremy L Thompson @param[in] mem_type Memory type to check 1609c774eddSJeremy L Thompson @param[out] has_borrowed_data_of_type Variable to store result 1619c774eddSJeremy L Thompson 1629c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1639c774eddSJeremy L Thompson 1649c774eddSJeremy L Thompson @ref Backend 1659c774eddSJeremy L Thompson **/ 1662b730f8bSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx, CeedMemType mem_type, bool *has_borrowed_data_of_type) { 167*6574a04fSJeremy L Thompson CeedCheck(ctx->HasBorrowedDataOfType, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support HasBorrowedDataOfType"); 1682b730f8bSJeremy L Thompson CeedCall(ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type)); 1699c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 1709c774eddSJeremy L Thompson } 1719c774eddSJeremy L Thompson 1729c774eddSJeremy L Thompson /** 173777ff853SJeremy L Thompson @brief Get the state of a CeedQFunctionContext 174777ff853SJeremy L Thompson 175ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to retrieve state 176777ff853SJeremy L Thompson @param[out] state Variable to store state 177777ff853SJeremy L Thompson 178777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 179777ff853SJeremy L Thompson 180777ff853SJeremy L Thompson @ref Backend 181777ff853SJeremy L Thompson **/ 182777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) { 183777ff853SJeremy L Thompson *state = ctx->state; 184e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 185777ff853SJeremy L Thompson } 186777ff853SJeremy L Thompson 187777ff853SJeremy L Thompson /** 188777ff853SJeremy L Thompson @brief Get backend data of a CeedQFunctionContext 189777ff853SJeremy L Thompson 190ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 191777ff853SJeremy L Thompson @param[out] data Variable to store data 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 CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) { 198777ff853SJeremy L Thompson *(void **)data = ctx->data; 199e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 200777ff853SJeremy L Thompson } 201777ff853SJeremy L Thompson 202777ff853SJeremy L Thompson /** 203777ff853SJeremy L Thompson @brief Set backend data of a CeedQFunctionContext 204777ff853SJeremy L Thompson 205ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 206ea61e9acSJeremy L Thompson @param[in] data Data to set 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 CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) { 213777ff853SJeremy L Thompson ctx->data = data; 214e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 215777ff853SJeremy L Thompson } 216777ff853SJeremy L Thompson 21734359f16Sjeremylt /** 218ea61e9acSJeremy L Thompson @brief Get label for a registered QFunctionContext field, or `NULL` if no field has been registered with this `field_name` 219e6a0ab89SJeremy L Thompson 220e6a0ab89SJeremy L Thompson @param[in] ctx CeedQFunctionContext 221e6a0ab89SJeremy L Thompson @param[in] field_name Name of field to retrieve label 222e6a0ab89SJeremy L Thompson @param[out] field_label Variable to field label 223e6a0ab89SJeremy L Thompson 224e6a0ab89SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 225e6a0ab89SJeremy L Thompson 2263e1e85abSJeremy L Thompson @ref Backend 227e6a0ab89SJeremy L Thompson **/ 2282b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx, const char *field_name, CeedContextFieldLabel *field_label) { 229e6a0ab89SJeremy L Thompson CeedInt field_index; 2302b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index)); 231e6a0ab89SJeremy L Thompson 232e6a0ab89SJeremy L Thompson if (field_index != -1) { 233e6a0ab89SJeremy L Thompson *field_label = ctx->field_labels[field_index]; 234e6a0ab89SJeremy L Thompson } else { 235e6a0ab89SJeremy L Thompson *field_label = NULL; 236e6a0ab89SJeremy L Thompson } 237e6a0ab89SJeremy L Thompson 238e6a0ab89SJeremy L Thompson return CEED_ERROR_SUCCESS; 239e6a0ab89SJeremy L Thompson } 240e6a0ab89SJeremy L Thompson 241e6a0ab89SJeremy L Thompson /** 242d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field 243d8dd9a91SJeremy L Thompson 244ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 245ea61e9acSJeremy L Thompson @param[in] field_label Label of field to set 246ea61e9acSJeremy L Thompson @param[in] field_type Type of field to set 2472788fa27SJeremy L Thompson @param[in] values Value to set 248d8dd9a91SJeremy L Thompson 249d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 250d8dd9a91SJeremy L Thompson 2513e1e85abSJeremy L Thompson @ref Backend 252d8dd9a91SJeremy L Thompson **/ 2532788fa27SJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *values) { 2543668ca4bSJeremy L Thompson // Check field type 255*6574a04fSJeremy L Thompson CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED, 256*6574a04fSJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name, 257*6574a04fSJeremy L Thompson CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 258d8dd9a91SJeremy L Thompson 259d8dd9a91SJeremy L Thompson char *data; 2602b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data)); 2612788fa27SJeremy L Thompson memcpy(&data[field_label->offset], values, field_label->size); 2622b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, &data)); 263d8dd9a91SJeremy L Thompson 264d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 265d8dd9a91SJeremy L Thompson } 266d8dd9a91SJeremy L Thompson 267d8dd9a91SJeremy L Thompson /** 2682788fa27SJeremy L Thompson @brief Get QFunctionContext field data, read-only 2692788fa27SJeremy L Thompson 2702788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 2712788fa27SJeremy L Thompson @param[in] field_label Label of field to read 2722788fa27SJeremy L Thompson @param[in] field_type Type of field to read 2732788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 2742788fa27SJeremy L Thompson @param[out] values Pointer to context values 2752788fa27SJeremy L Thompson 2762788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2772788fa27SJeremy L Thompson 2782788fa27SJeremy L Thompson @ref Backend 2792788fa27SJeremy L Thompson **/ 2802788fa27SJeremy L Thompson int CeedQFunctionContextGetGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, 2812788fa27SJeremy L Thompson size_t *num_values, void *values) { 2822788fa27SJeremy L Thompson // Check field type 283*6574a04fSJeremy L Thompson CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED, 284*6574a04fSJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name, 285*6574a04fSJeremy L Thompson CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 2862788fa27SJeremy L Thompson 2872788fa27SJeremy L Thompson char *data; 2882788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data)); 2892788fa27SJeremy L Thompson *(void **)values = &data[field_label->offset]; 2902788fa27SJeremy L Thompson switch (field_type) { 2912788fa27SJeremy L Thompson case CEED_CONTEXT_FIELD_INT32: 2922788fa27SJeremy L Thompson *num_values = field_label->size / sizeof(int); 2932788fa27SJeremy L Thompson break; 2942788fa27SJeremy L Thompson case CEED_CONTEXT_FIELD_DOUBLE: 2952788fa27SJeremy L Thompson *num_values = field_label->size / sizeof(double); 2962788fa27SJeremy L Thompson break; 2972788fa27SJeremy L Thompson } 2982788fa27SJeremy L Thompson 2992788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3002788fa27SJeremy L Thompson } 3012788fa27SJeremy L Thompson 3022788fa27SJeremy L Thompson /** 3032788fa27SJeremy L Thompson @brief Restore QFunctionContext field data, read-only 3042788fa27SJeremy L Thompson 3052788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 3062788fa27SJeremy L Thompson @param[in] field_label Label of field to restore 3072788fa27SJeremy L Thompson @param[in] field_type Type of field to restore 3082788fa27SJeremy L Thompson @param[out] values Pointer to context values 3092788fa27SJeremy L Thompson 3102788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3112788fa27SJeremy L Thompson 3122788fa27SJeremy L Thompson @ref Backend 3132788fa27SJeremy L Thompson **/ 3142788fa27SJeremy L Thompson int CeedQFunctionContextRestoreGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, 3152788fa27SJeremy L Thompson void *values) { 3162788fa27SJeremy L Thompson // Check field type 317*6574a04fSJeremy L Thompson CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED, 318*6574a04fSJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name, 319*6574a04fSJeremy L Thompson CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 3202788fa27SJeremy L Thompson 3212788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, values)); 3222788fa27SJeremy L Thompson 3232788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3242788fa27SJeremy L Thompson } 3252788fa27SJeremy L Thompson 3262788fa27SJeremy L Thompson /** 327bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value 328bfacc300SJeremy L Thompson 329ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 3302788fa27SJeremy L Thompson @param[in] field_label Label for field to set 331ea61e9acSJeremy L Thompson @param[in] values Values to set 332bfacc300SJeremy L Thompson 333bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 334bfacc300SJeremy L Thompson 3353e1e85abSJeremy L Thompson @ref Backend 336bfacc300SJeremy L Thompson **/ 3372b730f8bSJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, double *values) { 338*6574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3392b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values)); 340bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 341bfacc300SJeremy L Thompson } 342bfacc300SJeremy L Thompson 343bfacc300SJeremy L Thompson /** 3442788fa27SJeremy L Thompson @brief Get QFunctionContext field holding a double precision value, read-only 3452788fa27SJeremy L Thompson 3462788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 3472788fa27SJeremy L Thompson @param[in] field_label Label for field to get 3482788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 3492788fa27SJeremy L Thompson @param[out] values Pointer to context values 3502788fa27SJeremy L Thompson 3512788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3522788fa27SJeremy L Thompson 3532788fa27SJeremy L Thompson @ref Backend 3542788fa27SJeremy L Thompson **/ 3552788fa27SJeremy L Thompson int CeedQFunctionContextGetDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const double **values) { 356*6574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3572788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values)); 3582788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3592788fa27SJeremy L Thompson } 3602788fa27SJeremy L Thompson 3612788fa27SJeremy L Thompson /** 3622788fa27SJeremy L Thompson @brief Restore QFunctionContext field holding a double precision value, read-only 3632788fa27SJeremy L Thompson 3642788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 3652788fa27SJeremy L Thompson @param[in] field_label Label for field to restore 3662788fa27SJeremy L Thompson @param[out] values Pointer to context values 3672788fa27SJeremy L Thompson 3682788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3692788fa27SJeremy L Thompson 3702788fa27SJeremy L Thompson @ref Backend 3712788fa27SJeremy L Thompson **/ 3722788fa27SJeremy L Thompson int CeedQFunctionContextRestoreDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const double **values) { 373*6574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3742788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values)); 3752788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3762788fa27SJeremy L Thompson } 3772788fa27SJeremy L Thompson 3782788fa27SJeremy L Thompson /** 379bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding an int32 value 380bfacc300SJeremy L Thompson 381ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 3822788fa27SJeremy L Thompson @param[in] field_label Label for field to set 383ea61e9acSJeremy L Thompson @param[in] values Values to set 384bfacc300SJeremy L Thompson 385bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 386bfacc300SJeremy L Thompson 3873e1e85abSJeremy L Thompson @ref Backend 388bfacc300SJeremy L Thompson **/ 3892b730f8bSJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, int *values) { 390*6574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3912b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values)); 392bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 393bfacc300SJeremy L Thompson } 394bfacc300SJeremy L Thompson 395bfacc300SJeremy L Thompson /** 3962788fa27SJeremy L Thompson @brief Get QFunctionContext field holding a int32 value, read-only 3972788fa27SJeremy L Thompson 3982788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 3992788fa27SJeremy L Thompson @param[in] field_label Label for field to get 4002788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 4012788fa27SJeremy L Thompson @param[out] values Pointer to context values 4022788fa27SJeremy L Thompson 4032788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4042788fa27SJeremy L Thompson 4052788fa27SJeremy L Thompson @ref Backend 4062788fa27SJeremy L Thompson **/ 4072788fa27SJeremy L Thompson int CeedQFunctionContextGetInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const int **values) { 408*6574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4092788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values)); 4102788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4112788fa27SJeremy L Thompson } 4122788fa27SJeremy L Thompson 4132788fa27SJeremy L Thompson /** 4142788fa27SJeremy L Thompson @brief Restore QFunctionContext field holding a int32 value, read-only 4152788fa27SJeremy L Thompson 4162788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 4172788fa27SJeremy L Thompson @param[in] field_label Label for field to restore 4182788fa27SJeremy L Thompson @param[out] values Pointer to context values 4192788fa27SJeremy L Thompson 4202788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4212788fa27SJeremy L Thompson 4222788fa27SJeremy L Thompson @ref Backend 4232788fa27SJeremy L Thompson **/ 4242788fa27SJeremy L Thompson int CeedQFunctionContextRestoreInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const int **values) { 425*6574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4262788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values)); 4272788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4282788fa27SJeremy L Thompson } 4292788fa27SJeremy L Thompson 4302788fa27SJeremy L Thompson /** 4312e64a2b9SJeremy L Thompson @brief Get additional destroy routine for CeedQFunctionContext user data 4322e64a2b9SJeremy L Thompson 4332e64a2b9SJeremy L Thompson @param[in] ctx CeedQFunctionContext to get user destroy function 4342e64a2b9SJeremy L Thompson @param[out] f_mem_type Memory type to use when passing data into `f` 4352e64a2b9SJeremy L Thompson @param[out] f Additional routine to use to destroy user data 4362e64a2b9SJeremy L Thompson 4372e64a2b9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4382e64a2b9SJeremy L Thompson 4392e64a2b9SJeremy L Thompson @ref Backend 4402e64a2b9SJeremy L Thompson **/ 4412b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx, CeedMemType *f_mem_type, CeedQFunctionContextDataDestroyUser *f) { 4422e64a2b9SJeremy L Thompson if (f_mem_type) *f_mem_type = ctx->data_destroy_mem_type; 4432e64a2b9SJeremy L Thompson if (f) *f = ctx->data_destroy_function; 4442e64a2b9SJeremy L Thompson return CEED_ERROR_SUCCESS; 4452e64a2b9SJeremy L Thompson } 4462e64a2b9SJeremy L Thompson 4472e64a2b9SJeremy L Thompson /** 44834359f16Sjeremylt @brief Increment the reference counter for a CeedQFunctionContext 44934359f16Sjeremylt 450ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to increment the reference counter 45134359f16Sjeremylt 45234359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 45334359f16Sjeremylt 45434359f16Sjeremylt @ref Backend 45534359f16Sjeremylt **/ 4569560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) { 45734359f16Sjeremylt ctx->ref_count++; 45834359f16Sjeremylt return CEED_ERROR_SUCCESS; 45934359f16Sjeremylt } 46034359f16Sjeremylt 461777ff853SJeremy L Thompson /// @} 462777ff853SJeremy L Thompson 463777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 464777ff853SJeremy L Thompson /// CeedQFunctionContext Public API 465777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 466777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser 467777ff853SJeremy L Thompson /// @{ 468777ff853SJeremy L Thompson 469777ff853SJeremy L Thompson /** 470777ff853SJeremy L Thompson @brief Create a CeedQFunctionContext for storing CeedQFunction user context data 471777ff853SJeremy L Thompson 472ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedQFunctionContext will be created 473ea61e9acSJeremy L Thompson @param[out] ctx Address of the variable where the newly created CeedQFunctionContext will be stored 474777ff853SJeremy L Thompson 475777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 476777ff853SJeremy L Thompson 477777ff853SJeremy L Thompson @ref User 478777ff853SJeremy L Thompson **/ 479777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) { 480777ff853SJeremy L Thompson if (!ceed->QFunctionContextCreate) { 481777ff853SJeremy L Thompson Ceed delegate; 482*6574a04fSJeremy L Thompson 4832b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Context")); 484*6574a04fSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextCreate"); 4852b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextCreate(delegate, ctx)); 486e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 487777ff853SJeremy L Thompson } 488777ff853SJeremy L Thompson 4892b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, ctx)); 490777ff853SJeremy L Thompson (*ctx)->ceed = ceed; 4912b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 492d1d35e2fSjeremylt (*ctx)->ref_count = 1; 4932b730f8bSJeremy L Thompson CeedCall(ceed->QFunctionContextCreate(*ctx)); 494e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 495777ff853SJeremy L Thompson } 496777ff853SJeremy L Thompson 497777ff853SJeremy L Thompson /** 498ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedQFunctionContext. 499ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedQFunctionContextDestroy()`. 500512bb800SJeremy L Thompson 501512bb800SJeremy L Thompson Note: If the value of `ctx_copy` passed to this function is non-NULL, then it is assumed that `ctx_copy` is a pointer to a 502512bb800SJeremy L Thompson CeedQFunctionContext. This CeedQFunctionContext will be destroyed if `ctx_copy` is the only reference to this CeedQFunctionContext. 5039560d06aSjeremylt 504ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to copy reference to 505ea61e9acSJeremy L Thompson @param[in,out] ctx_copy Variable to store copied reference 5069560d06aSjeremylt 5079560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 5089560d06aSjeremylt 5099560d06aSjeremylt @ref User 5109560d06aSjeremylt **/ 5112b730f8bSJeremy L Thompson int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, CeedQFunctionContext *ctx_copy) { 5122b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextReference(ctx)); 5132b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(ctx_copy)); 5149560d06aSjeremylt *ctx_copy = ctx; 5159560d06aSjeremylt return CEED_ERROR_SUCCESS; 5169560d06aSjeremylt } 5179560d06aSjeremylt 5189560d06aSjeremylt /** 519ea61e9acSJeremy L Thompson @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated data if applicable. 520ea61e9acSJeremy L Thompson The backend may copy values to a different memtype, such as during @ref CeedQFunctionApply(). 521777ff853SJeremy L Thompson See also @ref CeedQFunctionContextTakeData(). 522777ff853SJeremy L Thompson 523ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 524ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the data being passed 525ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the data 526ea61e9acSJeremy L Thompson @param[in] size Size of data, in bytes 527ea61e9acSJeremy L Thompson @param[in] data Data to be used 528777ff853SJeremy L Thompson 529777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 530777ff853SJeremy L Thompson 531777ff853SJeremy L Thompson @ref User 532777ff853SJeremy L Thompson **/ 5332b730f8bSJeremy L Thompson int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, size_t size, void *data) { 534*6574a04fSJeremy L Thompson CeedCheck(ctx->SetData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextSetData"); 535*6574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 536777ff853SJeremy L Thompson 5372b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroyData(ctx)); 538d1d35e2fSjeremylt ctx->ctx_size = size; 5392b730f8bSJeremy L Thompson CeedCall(ctx->SetData(ctx, mem_type, copy_mode, data)); 540777ff853SJeremy L Thompson ctx->state += 2; 541e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 542777ff853SJeremy L Thompson } 543777ff853SJeremy L Thompson 544777ff853SJeremy L Thompson /** 545891038deSjeremylt @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type. 546891038deSjeremylt The caller is responsible for managing and freeing the memory. 547891038deSjeremylt 548ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 549ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 550ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 551891038deSjeremylt @param[out] data Data on memory type mem_type 552891038deSjeremylt 553891038deSjeremylt @return An error code: 0 - success, otherwise - failure 554891038deSjeremylt 555891038deSjeremylt @ref User 556891038deSjeremylt **/ 5572b730f8bSJeremy L Thompson int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 5589c774eddSJeremy L Thompson bool has_valid_data = true; 5592b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 560*6574a04fSJeremy L Thompson CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to take, must set data"); 5619c774eddSJeremy L Thompson 562*6574a04fSJeremy L Thompson CeedCheck(ctx->TakeData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support TakeData"); 563*6574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 564891038deSjeremylt 5659c774eddSJeremy L Thompson bool has_borrowed_data_of_type = true; 5662b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, &has_borrowed_data_of_type)); 567*6574a04fSJeremy L Thompson CeedCheck(has_borrowed_data_of_type, ctx->ceed, CEED_ERROR_BACKEND, 568*6574a04fSJeremy L Thompson "CeedQFunctionContext has no borrowed %s data, must set data with CeedQFunctionContextSetData", CeedMemTypes[mem_type]); 5699c774eddSJeremy L Thompson 570891038deSjeremylt void *temp_data = NULL; 5712b730f8bSJeremy L Thompson CeedCall(ctx->TakeData(ctx, mem_type, &temp_data)); 572891038deSjeremylt if (data) (*(void **)data) = temp_data; 573891038deSjeremylt return CEED_ERROR_SUCCESS; 574891038deSjeremylt } 575891038deSjeremylt 576891038deSjeremylt /** 577777ff853SJeremy L Thompson @brief Get read/write access to a CeedQFunctionContext via the specified memory type. 578777ff853SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 579777ff853SJeremy L Thompson 580ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 581ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 582ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 583d1d35e2fSjeremylt @param[out] data Data on memory type mem_type 584777ff853SJeremy L Thompson 585ea61e9acSJeremy L Thompson @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions provide access to array pointers in the desired memory 586ea61e9acSJeremy L Thompson space. Pairing get/restore allows the Context to track access. 587777ff853SJeremy L Thompson 588777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 589777ff853SJeremy L Thompson 590777ff853SJeremy L Thompson @ref User 591777ff853SJeremy L Thompson **/ 5922b730f8bSJeremy L Thompson int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 593*6574a04fSJeremy L Thompson CeedCheck(ctx->GetData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetData"); 594*6574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 595*6574a04fSJeremy L Thompson CeedCheck(ctx->num_readers == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, a process has read access"); 59628bfd0b7SJeremy L Thompson 5979c774eddSJeremy L Thompson bool has_valid_data = true; 5982b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 599*6574a04fSJeremy L Thompson CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data"); 6009c774eddSJeremy L Thompson 6012b730f8bSJeremy L Thompson CeedCall(ctx->GetData(ctx, mem_type, data)); 60228bfd0b7SJeremy L Thompson ctx->state++; 60328bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 60428bfd0b7SJeremy L Thompson } 60528bfd0b7SJeremy L Thompson 60628bfd0b7SJeremy L Thompson /** 60728bfd0b7SJeremy L Thompson @brief Get read only access to a CeedQFunctionContext via the specified memory type. 60828bfd0b7SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 60928bfd0b7SJeremy L Thompson 610ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 611ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 612ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 61328bfd0b7SJeremy L Thompson @param[out] data Data on memory type mem_type 61428bfd0b7SJeremy L Thompson 615ea61e9acSJeremy L Thompson @note The CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead() functions provide access to array pointers in the desired 616ea61e9acSJeremy L Thompson memory space. Pairing get/restore allows the Context to track access. 61728bfd0b7SJeremy L Thompson 61828bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 61928bfd0b7SJeremy L Thompson 62028bfd0b7SJeremy L Thompson @ref User 62128bfd0b7SJeremy L Thompson **/ 6222b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 623*6574a04fSJeremy L Thompson CeedCheck(ctx->GetDataRead, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetDataRead"); 624*6574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 62528bfd0b7SJeremy L Thompson 62628bfd0b7SJeremy L Thompson bool has_valid_data = true; 6272b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 628*6574a04fSJeremy L Thompson CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data"); 62928bfd0b7SJeremy L Thompson 6302b730f8bSJeremy L Thompson CeedCall(ctx->GetDataRead(ctx, mem_type, data)); 63128bfd0b7SJeremy L Thompson ctx->num_readers++; 632e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 633777ff853SJeremy L Thompson } 634777ff853SJeremy L Thompson 635777ff853SJeremy L Thompson /** 636777ff853SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetData() 637777ff853SJeremy L Thompson 638ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to restore 639ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 640777ff853SJeremy L Thompson 641777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 642777ff853SJeremy L Thompson 643777ff853SJeremy L Thompson @ref User 644777ff853SJeremy L Thompson **/ 645777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) { 646*6574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 1, ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted"); 647777ff853SJeremy L Thompson 648*6574a04fSJeremy L Thompson if (ctx->RestoreData) CeedCall(ctx->RestoreData(ctx)); 649777ff853SJeremy L Thompson *(void **)data = NULL; 65028bfd0b7SJeremy L Thompson ctx->state++; 65128bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 65228bfd0b7SJeremy L Thompson } 65328bfd0b7SJeremy L Thompson 65428bfd0b7SJeremy L Thompson /** 65528bfd0b7SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead() 65628bfd0b7SJeremy L Thompson 657ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to restore 658ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 65928bfd0b7SJeremy L Thompson 66028bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 66128bfd0b7SJeremy L Thompson 66228bfd0b7SJeremy L Thompson @ref User 66328bfd0b7SJeremy L Thompson **/ 66428bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) { 665*6574a04fSJeremy L Thompson CeedCheck(ctx->num_readers > 0, ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted"); 66628bfd0b7SJeremy L Thompson 66775a19770SJeremy L Thompson ctx->num_readers--; 668*6574a04fSJeremy L Thompson if (ctx->num_readers == 0 && ctx->RestoreDataRead) CeedCall(ctx->RestoreDataRead(ctx)); 66928bfd0b7SJeremy L Thompson *(void **)data = NULL; 67075a19770SJeremy L Thompson 671e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 672777ff853SJeremy L Thompson } 673777ff853SJeremy L Thompson 674777ff853SJeremy L Thompson /** 675cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a double precision value 676cdf32b93SJeremy L Thompson 677ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 678ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 679ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 680ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 681ea61e9acSJeremy L Thompson @param[in] field_description Description of field, or NULL for none 682cdf32b93SJeremy L Thompson 683cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 684cdf32b93SJeremy L Thompson 685cdf32b93SJeremy L Thompson @ref User 686cdf32b93SJeremy L Thompson **/ 6872b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 688cdf32b93SJeremy L Thompson const char *field_description) { 6892b730f8bSJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double), num_values); 690cdf32b93SJeremy L Thompson } 691cdf32b93SJeremy L Thompson 692cdf32b93SJeremy L Thompson /** 693cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a int32 value 694cdf32b93SJeremy L Thompson 695ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 696ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 697ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 698ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 699ea61e9acSJeremy L Thompson @param[in] field_description Description of field, or NULL for none 700cdf32b93SJeremy L Thompson 701cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 702cdf32b93SJeremy L Thompson 703cdf32b93SJeremy L Thompson @ref User 704cdf32b93SJeremy L Thompson **/ 7052b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 706cdf32b93SJeremy L Thompson const char *field_description) { 7072b730f8bSJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int), num_values); 708cdf32b93SJeremy L Thompson } 709cdf32b93SJeremy L Thompson 710cdf32b93SJeremy L Thompson /** 7113668ca4bSJeremy L Thompson @brief Get labels for all registered QFunctionContext fields 712cdf32b93SJeremy L Thompson 713ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 7143668ca4bSJeremy L Thompson @param[out] field_labels Variable to hold array of field labels 715cdf32b93SJeremy L Thompson @param[out] num_fields Length of field descriptions array 716cdf32b93SJeremy L Thompson 717cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 718cdf32b93SJeremy L Thompson 719cdf32b93SJeremy L Thompson @ref User 720cdf32b93SJeremy L Thompson **/ 7212b730f8bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, const CeedContextFieldLabel **field_labels, CeedInt *num_fields) { 7223668ca4bSJeremy L Thompson *field_labels = ctx->field_labels; 723cdf32b93SJeremy L Thompson *num_fields = ctx->num_fields; 724cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 725cdf32b93SJeremy L Thompson } 726cdf32b93SJeremy L Thompson 727cdf32b93SJeremy L Thompson /** 7280f86cbe7SJeremy L Thompson @brief Get the descriptive information about a CeedContextFieldLabel 7290f86cbe7SJeremy L Thompson 7300f86cbe7SJeremy L Thompson @param[in] label CeedContextFieldLabel 7310f86cbe7SJeremy L Thompson @param[out] field_name Name of labeled field 7320f86cbe7SJeremy L Thompson @param[out] field_description Description of field, or NULL for none 7337bfe0f0eSJeremy L Thompson @param[out] num_values Number of values registered 7340f86cbe7SJeremy L Thompson @param[out] field_type CeedContextFieldType 7350f86cbe7SJeremy L Thompson 7360f86cbe7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7370f86cbe7SJeremy L Thompson 7380f86cbe7SJeremy L Thompson @ref User 7390f86cbe7SJeremy L Thompson **/ 7402b730f8bSJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, const char **field_name, const char **field_description, size_t *num_values, 7410f86cbe7SJeremy L Thompson CeedContextFieldType *field_type) { 7420f86cbe7SJeremy L Thompson if (field_name) *field_name = label->name; 7430f86cbe7SJeremy L Thompson if (field_description) *field_description = label->description; 7447bfe0f0eSJeremy L Thompson if (num_values) *num_values = label->num_values; 7450f86cbe7SJeremy L Thompson if (field_type) *field_type = label->type; 7460f86cbe7SJeremy L Thompson return CEED_ERROR_SUCCESS; 7470f86cbe7SJeremy L Thompson } 7480f86cbe7SJeremy L Thompson 7490f86cbe7SJeremy L Thompson /** 75080a9ef05SNatalie Beams @brief Get data size for a Context 75180a9ef05SNatalie Beams 752ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 75380a9ef05SNatalie Beams @param[out] ctx_size Variable to store size of context data values 75480a9ef05SNatalie Beams 75580a9ef05SNatalie Beams @return An error code: 0 - success, otherwise - failure 75680a9ef05SNatalie Beams 75780a9ef05SNatalie Beams @ref User 75880a9ef05SNatalie Beams **/ 7592b730f8bSJeremy L Thompson int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, size_t *ctx_size) { 76080a9ef05SNatalie Beams *ctx_size = ctx->ctx_size; 76180a9ef05SNatalie Beams return CEED_ERROR_SUCCESS; 76280a9ef05SNatalie Beams } 76380a9ef05SNatalie Beams 76480a9ef05SNatalie Beams /** 765777ff853SJeremy L Thompson @brief View a CeedQFunctionContext 766777ff853SJeremy L Thompson 767777ff853SJeremy L Thompson @param[in] ctx CeedQFunctionContext to view 768777ff853SJeremy L Thompson @param[in] stream Filestream to write to 769777ff853SJeremy L Thompson 770777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 771777ff853SJeremy L Thompson 772777ff853SJeremy L Thompson @ref User 773777ff853SJeremy L Thompson **/ 774777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) { 775777ff853SJeremy L Thompson fprintf(stream, "CeedQFunctionContext\n"); 776d1d35e2fSjeremylt fprintf(stream, " Context Data Size: %ld\n", ctx->ctx_size); 7773668ca4bSJeremy L Thompson for (CeedInt i = 0; i < ctx->num_fields; i++) { 7783668ca4bSJeremy L Thompson // LCOV_EXCL_START 7792b730f8bSJeremy L Thompson fprintf(stream, " Labeled %s field: %s\n", CeedContextFieldTypes[ctx->field_labels[i]->type], ctx->field_labels[i]->name); 7803668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 7813668ca4bSJeremy L Thompson } 782e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 783777ff853SJeremy L Thompson } 784777ff853SJeremy L Thompson 785777ff853SJeremy L Thompson /** 7862790b72bSJeremy L Thompson @brief Set additional destroy routine for CeedQFunctionContext user data 7872790b72bSJeremy L Thompson 788ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to set user destroy function 7892e64a2b9SJeremy L Thompson @param[in] f_mem_type Memory type to use when passing data into `f` 7902e64a2b9SJeremy L Thompson @param[in] f Additional routine to use to destroy user data 7912790b72bSJeremy L Thompson 7922790b72bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7932790b72bSJeremy L Thompson 7942790b72bSJeremy L Thompson @ref User 7952790b72bSJeremy L Thompson **/ 7962b730f8bSJeremy L Thompson int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) { 797*6574a04fSJeremy L Thompson CeedCheck(f, ctx->ceed, 1, "Must provide valid callback function for destroying user data"); 7982790b72bSJeremy L Thompson ctx->data_destroy_mem_type = f_mem_type; 7992790b72bSJeremy L Thompson ctx->data_destroy_function = f; 8002790b72bSJeremy L Thompson return CEED_ERROR_SUCCESS; 8012790b72bSJeremy L Thompson } 8022790b72bSJeremy L Thompson 8032790b72bSJeremy L Thompson /** 804777ff853SJeremy L Thompson @brief Destroy a CeedQFunctionContext 805777ff853SJeremy L Thompson 806ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to destroy 807777ff853SJeremy L Thompson 808777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 809777ff853SJeremy L Thompson 810777ff853SJeremy L Thompson @ref User 811777ff853SJeremy L Thompson **/ 812777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) { 813ad6481ceSJeremy L Thompson if (!*ctx || --(*ctx)->ref_count > 0) { 814ad6481ceSJeremy L Thompson *ctx = NULL; 815ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 816ad6481ceSJeremy L Thompson } 817*6574a04fSJeremy L Thompson CeedCheck(((*ctx)->state % 2) == 0, (*ctx)->ceed, 1, "Cannot destroy CeedQFunctionContext, the access lock is in use"); 818777ff853SJeremy L Thompson 8192b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroyData(*ctx)); 8202b730f8bSJeremy L Thompson if ((*ctx)->Destroy) CeedCall((*ctx)->Destroy(*ctx)); 821cdf32b93SJeremy L Thompson for (CeedInt i = 0; i < (*ctx)->num_fields; i++) { 8222b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i]->name)); 8232b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i]->description)); 8242b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i])); 825cdf32b93SJeremy L Thompson } 8262b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels)); 8272b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*ctx)->ceed)); 8282b730f8bSJeremy L Thompson CeedCall(CeedFree(ctx)); 829cdf32b93SJeremy L Thompson 830e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 831777ff853SJeremy L Thompson } 832777ff853SJeremy L Thompson 833777ff853SJeremy L Thompson /// @} 834