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 CeedInt field_index = -1; 62*1c66c397SJeremy L Thompson 63*1c66c397SJeremy L Thompson // Check for duplicate 642b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index)); 656574a04fSJeremy L Thompson CeedCheck(field_index == -1, ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" already registered", field_name); 66cdf32b93SJeremy L Thompson 67cdf32b93SJeremy L Thompson // Allocate space for field data 68cdf32b93SJeremy L Thompson if (ctx->num_fields == 0) { 692b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &ctx->field_labels)); 70cdf32b93SJeremy L Thompson ctx->max_fields = 1; 71cdf32b93SJeremy L Thompson } else if (ctx->num_fields == ctx->max_fields) { 722b730f8bSJeremy L Thompson CeedCall(CeedRealloc(2 * ctx->max_fields, &ctx->field_labels)); 73cdf32b93SJeremy L Thompson ctx->max_fields *= 2; 74cdf32b93SJeremy L Thompson } 752b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &ctx->field_labels[ctx->num_fields])); 76cdf32b93SJeremy L Thompson 77cdf32b93SJeremy L Thompson // Copy field data 782b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_name, (char **)&ctx->field_labels[ctx->num_fields]->name)); 792b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_description, (char **)&ctx->field_labels[ctx->num_fields]->description)); 803668ca4bSJeremy L Thompson ctx->field_labels[ctx->num_fields]->type = field_type; 813668ca4bSJeremy L Thompson ctx->field_labels[ctx->num_fields]->offset = field_offset; 827bfe0f0eSJeremy L Thompson ctx->field_labels[ctx->num_fields]->size = field_size * num_values; 837bfe0f0eSJeremy L Thompson ctx->field_labels[ctx->num_fields]->num_values = num_values; 84cdf32b93SJeremy L Thompson ctx->num_fields++; 85cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 86cdf32b93SJeremy L Thompson } 87cdf32b93SJeremy L Thompson 883b190ab8SJeremy L Thompson /** 89ea61e9acSJeremy L Thompson @brief Destroy user data held by CeedQFunctionContext, using function set by CeedQFunctionContextSetDataDestroy, if applicable 903b190ab8SJeremy L Thompson 913b190ab8SJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to destroy user data 923b190ab8SJeremy L Thompson 933b190ab8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 943b190ab8SJeremy L Thompson 953b190ab8SJeremy L Thompson @ref Developer 963b190ab8SJeremy L Thompson **/ 973b190ab8SJeremy L Thompson static int CeedQFunctionContextDestroyData(CeedQFunctionContext ctx) { 983b190ab8SJeremy L Thompson if (ctx->DataDestroy) { 992b730f8bSJeremy L Thompson CeedCall(ctx->DataDestroy(ctx)); 1003b190ab8SJeremy L Thompson } else { 1013b190ab8SJeremy L Thompson CeedMemType data_destroy_mem_type; 102*1c66c397SJeremy L Thompson CeedQFunctionContextDataDestroyUser data_destroy_function; 1033b190ab8SJeremy L Thompson 1042b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function)); 1053b190ab8SJeremy L Thompson if (data_destroy_function) { 1063b190ab8SJeremy L Thompson void *data; 1073b190ab8SJeremy L Thompson 1082b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, data_destroy_mem_type, &data)); 1092b730f8bSJeremy L Thompson CeedCall(data_destroy_function(data)); 1102b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, &data)); 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) { 1506574a04fSJeremy 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) { 1676574a04fSJeremy 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; 230*1c66c397SJeremy L Thompson 2312b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index)); 232e6a0ab89SJeremy L Thompson 233e6a0ab89SJeremy L Thompson if (field_index != -1) { 234e6a0ab89SJeremy L Thompson *field_label = ctx->field_labels[field_index]; 235e6a0ab89SJeremy L Thompson } else { 236e6a0ab89SJeremy L Thompson *field_label = NULL; 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) { 254*1c66c397SJeremy L Thompson char *data; 255*1c66c397SJeremy L Thompson 2563668ca4bSJeremy L Thompson // Check field type 2576574a04fSJeremy L Thompson CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED, 2586574a04fSJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name, 2596574a04fSJeremy L Thompson CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 260d8dd9a91SJeremy L Thompson 2612b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data)); 2622788fa27SJeremy L Thompson memcpy(&data[field_label->offset], values, field_label->size); 2632b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, &data)); 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) { 282*1c66c397SJeremy L Thompson char *data; 283*1c66c397SJeremy L Thompson 2842788fa27SJeremy L Thompson // Check field type 2856574a04fSJeremy L Thompson CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED, 2866574a04fSJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name, 2876574a04fSJeremy L Thompson CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 2882788fa27SJeremy L Thompson 2892788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data)); 2902788fa27SJeremy L Thompson *(void **)values = &data[field_label->offset]; 2912788fa27SJeremy L Thompson switch (field_type) { 2922788fa27SJeremy L Thompson case CEED_CONTEXT_FIELD_INT32: 2932788fa27SJeremy L Thompson *num_values = field_label->size / sizeof(int); 2942788fa27SJeremy L Thompson break; 2952788fa27SJeremy L Thompson case CEED_CONTEXT_FIELD_DOUBLE: 2962788fa27SJeremy L Thompson *num_values = field_label->size / sizeof(double); 2972788fa27SJeremy L Thompson break; 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 3176574a04fSJeremy L Thompson CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED, 3186574a04fSJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name, 3196574a04fSJeremy L Thompson CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 3202788fa27SJeremy L Thompson 3212788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, values)); 3222788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3232788fa27SJeremy L Thompson } 3242788fa27SJeremy L Thompson 3252788fa27SJeremy L Thompson /** 326bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value 327bfacc300SJeremy L Thompson 328ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 3292788fa27SJeremy L Thompson @param[in] field_label Label for field to set 330ea61e9acSJeremy L Thompson @param[in] values Values to set 331bfacc300SJeremy L Thompson 332bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 333bfacc300SJeremy L Thompson 3343e1e85abSJeremy L Thompson @ref Backend 335bfacc300SJeremy L Thompson **/ 3362b730f8bSJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, double *values) { 3376574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3382b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values)); 339bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 340bfacc300SJeremy L Thompson } 341bfacc300SJeremy L Thompson 342bfacc300SJeremy L Thompson /** 3432788fa27SJeremy L Thompson @brief Get QFunctionContext field holding a double precision value, read-only 3442788fa27SJeremy L Thompson 3452788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 3462788fa27SJeremy L Thompson @param[in] field_label Label for field to get 3472788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 3482788fa27SJeremy L Thompson @param[out] values Pointer to context values 3492788fa27SJeremy L Thompson 3502788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3512788fa27SJeremy L Thompson 3522788fa27SJeremy L Thompson @ref Backend 3532788fa27SJeremy L Thompson **/ 3542788fa27SJeremy L Thompson int CeedQFunctionContextGetDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const double **values) { 3556574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3562788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values)); 3572788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3582788fa27SJeremy L Thompson } 3592788fa27SJeremy L Thompson 3602788fa27SJeremy L Thompson /** 3612788fa27SJeremy L Thompson @brief Restore QFunctionContext field holding a double precision value, read-only 3622788fa27SJeremy L Thompson 3632788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 3642788fa27SJeremy L Thompson @param[in] field_label Label for field to restore 3652788fa27SJeremy L Thompson @param[out] values Pointer to context values 3662788fa27SJeremy L Thompson 3672788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3682788fa27SJeremy L Thompson 3692788fa27SJeremy L Thompson @ref Backend 3702788fa27SJeremy L Thompson **/ 3712788fa27SJeremy L Thompson int CeedQFunctionContextRestoreDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const double **values) { 3726574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3732788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values)); 3742788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3752788fa27SJeremy L Thompson } 3762788fa27SJeremy L Thompson 3772788fa27SJeremy L Thompson /** 378bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding an int32 value 379bfacc300SJeremy L Thompson 380ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 3812788fa27SJeremy L Thompson @param[in] field_label Label for field to set 382ea61e9acSJeremy L Thompson @param[in] values Values to set 383bfacc300SJeremy L Thompson 384bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 385bfacc300SJeremy L Thompson 3863e1e85abSJeremy L Thompson @ref Backend 387bfacc300SJeremy L Thompson **/ 3882b730f8bSJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, int *values) { 3896574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3902b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values)); 391bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 392bfacc300SJeremy L Thompson } 393bfacc300SJeremy L Thompson 394bfacc300SJeremy L Thompson /** 3952788fa27SJeremy L Thompson @brief Get QFunctionContext field holding a int32 value, read-only 3962788fa27SJeremy L Thompson 3972788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 3982788fa27SJeremy L Thompson @param[in] field_label Label for field to get 3992788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 4002788fa27SJeremy L Thompson @param[out] values Pointer to context values 4012788fa27SJeremy L Thompson 4022788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4032788fa27SJeremy L Thompson 4042788fa27SJeremy L Thompson @ref Backend 4052788fa27SJeremy L Thompson **/ 4062788fa27SJeremy L Thompson int CeedQFunctionContextGetInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const int **values) { 4076574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4082788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values)); 4092788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4102788fa27SJeremy L Thompson } 4112788fa27SJeremy L Thompson 4122788fa27SJeremy L Thompson /** 4132788fa27SJeremy L Thompson @brief Restore QFunctionContext field holding a int32 value, read-only 4142788fa27SJeremy L Thompson 4152788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 4162788fa27SJeremy L Thompson @param[in] field_label Label for field to restore 4172788fa27SJeremy L Thompson @param[out] values Pointer to context values 4182788fa27SJeremy L Thompson 4192788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4202788fa27SJeremy L Thompson 4212788fa27SJeremy L Thompson @ref Backend 4222788fa27SJeremy L Thompson **/ 4232788fa27SJeremy L Thompson int CeedQFunctionContextRestoreInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const int **values) { 4246574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4252788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values)); 4262788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4272788fa27SJeremy L Thompson } 4282788fa27SJeremy L Thompson 4292788fa27SJeremy L Thompson /** 4302e64a2b9SJeremy L Thompson @brief Get additional destroy routine for CeedQFunctionContext user data 4312e64a2b9SJeremy L Thompson 4322e64a2b9SJeremy L Thompson @param[in] ctx CeedQFunctionContext to get user destroy function 4332e64a2b9SJeremy L Thompson @param[out] f_mem_type Memory type to use when passing data into `f` 4342e64a2b9SJeremy L Thompson @param[out] f Additional routine to use to destroy user data 4352e64a2b9SJeremy L Thompson 4362e64a2b9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4372e64a2b9SJeremy L Thompson 4382e64a2b9SJeremy L Thompson @ref Backend 4392e64a2b9SJeremy L Thompson **/ 4402b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx, CeedMemType *f_mem_type, CeedQFunctionContextDataDestroyUser *f) { 4412e64a2b9SJeremy L Thompson if (f_mem_type) *f_mem_type = ctx->data_destroy_mem_type; 4422e64a2b9SJeremy L Thompson if (f) *f = ctx->data_destroy_function; 4432e64a2b9SJeremy L Thompson return CEED_ERROR_SUCCESS; 4442e64a2b9SJeremy L Thompson } 4452e64a2b9SJeremy L Thompson 4462e64a2b9SJeremy L Thompson /** 44734359f16Sjeremylt @brief Increment the reference counter for a CeedQFunctionContext 44834359f16Sjeremylt 449ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to increment the reference counter 45034359f16Sjeremylt 45134359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 45234359f16Sjeremylt 45334359f16Sjeremylt @ref Backend 45434359f16Sjeremylt **/ 4559560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) { 45634359f16Sjeremylt ctx->ref_count++; 45734359f16Sjeremylt return CEED_ERROR_SUCCESS; 45834359f16Sjeremylt } 45934359f16Sjeremylt 460777ff853SJeremy L Thompson /// @} 461777ff853SJeremy L Thompson 462777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 463777ff853SJeremy L Thompson /// CeedQFunctionContext Public API 464777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 465777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser 466777ff853SJeremy L Thompson /// @{ 467777ff853SJeremy L Thompson 468777ff853SJeremy L Thompson /** 469777ff853SJeremy L Thompson @brief Create a CeedQFunctionContext for storing CeedQFunction user context data 470777ff853SJeremy L Thompson 471ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedQFunctionContext will be created 472ea61e9acSJeremy L Thompson @param[out] ctx Address of the variable where the newly created CeedQFunctionContext will be stored 473777ff853SJeremy L Thompson 474777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 475777ff853SJeremy L Thompson 476777ff853SJeremy L Thompson @ref User 477777ff853SJeremy L Thompson **/ 478777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) { 479777ff853SJeremy L Thompson if (!ceed->QFunctionContextCreate) { 480777ff853SJeremy L Thompson Ceed delegate; 4816574a04fSJeremy L Thompson 4822b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Context")); 4836574a04fSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextCreate"); 4842b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextCreate(delegate, ctx)); 485e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 486777ff853SJeremy L Thompson } 487777ff853SJeremy L Thompson 4882b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, ctx)); 489db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*ctx)->ceed)); 490d1d35e2fSjeremylt (*ctx)->ref_count = 1; 4912b730f8bSJeremy L Thompson CeedCall(ceed->QFunctionContextCreate(*ctx)); 492e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 493777ff853SJeremy L Thompson } 494777ff853SJeremy L Thompson 495777ff853SJeremy L Thompson /** 496ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedQFunctionContext. 4974385fb7fSSebastian Grimberg 498ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedQFunctionContextDestroy()`. 499512bb800SJeremy L Thompson 500512bb800SJeremy 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 501512bb800SJeremy L Thompson CeedQFunctionContext. This CeedQFunctionContext will be destroyed if `ctx_copy` is the only reference to this CeedQFunctionContext. 5029560d06aSjeremylt 503ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to copy reference to 504ea61e9acSJeremy L Thompson @param[in,out] ctx_copy Variable to store copied reference 5059560d06aSjeremylt 5069560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 5079560d06aSjeremylt 5089560d06aSjeremylt @ref User 5099560d06aSjeremylt **/ 5102b730f8bSJeremy L Thompson int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, CeedQFunctionContext *ctx_copy) { 5112b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextReference(ctx)); 5122b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(ctx_copy)); 5139560d06aSjeremylt *ctx_copy = ctx; 5149560d06aSjeremylt return CEED_ERROR_SUCCESS; 5159560d06aSjeremylt } 5169560d06aSjeremylt 5179560d06aSjeremylt /** 518ea61e9acSJeremy L Thompson @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated data if applicable. 5194385fb7fSSebastian Grimberg 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) { 5346574a04fSJeremy L Thompson CeedCheck(ctx->SetData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextSetData"); 5356574a04fSJeremy 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. 5464385fb7fSSebastian Grimberg 547891038deSjeremylt The caller is responsible for managing and freeing the memory. 548891038deSjeremylt 549ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 550ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 551ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 552891038deSjeremylt @param[out] data Data on memory type mem_type 553891038deSjeremylt 554891038deSjeremylt @return An error code: 0 - success, otherwise - failure 555891038deSjeremylt 556891038deSjeremylt @ref User 557891038deSjeremylt **/ 5582b730f8bSJeremy L Thompson int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 559*1c66c397SJeremy L Thompson void *temp_data = NULL; 560*1c66c397SJeremy L Thompson bool has_valid_data = true, has_borrowed_data_of_type = true; 561*1c66c397SJeremy L Thompson 5622b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 5636574a04fSJeremy L Thompson CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to take, must set data"); 5649c774eddSJeremy L Thompson 5656574a04fSJeremy L Thompson CeedCheck(ctx->TakeData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support TakeData"); 5666574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 567891038deSjeremylt 5682b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, &has_borrowed_data_of_type)); 5696574a04fSJeremy L Thompson CeedCheck(has_borrowed_data_of_type, ctx->ceed, CEED_ERROR_BACKEND, 5706574a04fSJeremy L Thompson "CeedQFunctionContext has no borrowed %s data, must set data with CeedQFunctionContextSetData", CeedMemTypes[mem_type]); 5719c774eddSJeremy L Thompson 5722b730f8bSJeremy L Thompson CeedCall(ctx->TakeData(ctx, mem_type, &temp_data)); 573891038deSjeremylt if (data) (*(void **)data) = temp_data; 574891038deSjeremylt return CEED_ERROR_SUCCESS; 575891038deSjeremylt } 576891038deSjeremylt 577891038deSjeremylt /** 578777ff853SJeremy L Thompson @brief Get read/write access to a CeedQFunctionContext via the specified memory type. 5794385fb7fSSebastian Grimberg 580777ff853SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 581777ff853SJeremy L Thompson 582ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 583ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 584ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 585d1d35e2fSjeremylt @param[out] data Data on memory type mem_type 586777ff853SJeremy L Thompson 587ea61e9acSJeremy L Thompson @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions provide access to array pointers in the desired memory 5889fd66db6SSebastian Grimberg space. 5899fd66db6SSebastian Grimberg Pairing get/restore allows the Context to track access. 590777ff853SJeremy L Thompson 591777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 592777ff853SJeremy L Thompson 593777ff853SJeremy L Thompson @ref User 594777ff853SJeremy L Thompson **/ 5952b730f8bSJeremy L Thompson int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 596*1c66c397SJeremy L Thompson bool has_valid_data = true; 597*1c66c397SJeremy L Thompson 5986574a04fSJeremy L Thompson CeedCheck(ctx->GetData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetData"); 5996574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 6006574a04fSJeremy L Thompson CeedCheck(ctx->num_readers == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, a process has read access"); 60128bfd0b7SJeremy L Thompson 6022b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 6036574a04fSJeremy L Thompson CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data"); 6049c774eddSJeremy L Thompson 6052b730f8bSJeremy L Thompson CeedCall(ctx->GetData(ctx, mem_type, data)); 60628bfd0b7SJeremy L Thompson ctx->state++; 60728bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 60828bfd0b7SJeremy L Thompson } 60928bfd0b7SJeremy L Thompson 61028bfd0b7SJeremy L Thompson /** 61128bfd0b7SJeremy L Thompson @brief Get read only access to a CeedQFunctionContext via the specified memory type. 6124385fb7fSSebastian Grimberg 61328bfd0b7SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 61428bfd0b7SJeremy L Thompson 615ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 616ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 617ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 61828bfd0b7SJeremy L Thompson @param[out] data Data on memory type mem_type 61928bfd0b7SJeremy L Thompson 620ea61e9acSJeremy L Thompson @note The CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead() functions provide access to array pointers in the desired 6219fd66db6SSebastian Grimberg memory space. 6229fd66db6SSebastian Grimberg Pairing get/restore allows the Context to track access. 62328bfd0b7SJeremy L Thompson 62428bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 62528bfd0b7SJeremy L Thompson 62628bfd0b7SJeremy L Thompson @ref User 62728bfd0b7SJeremy L Thompson **/ 6282b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 629*1c66c397SJeremy L Thompson bool has_valid_data = true; 630*1c66c397SJeremy L Thompson 6316574a04fSJeremy L Thompson CeedCheck(ctx->GetDataRead, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetDataRead"); 6326574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 63328bfd0b7SJeremy L Thompson 6342b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 6356574a04fSJeremy L Thompson CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data"); 63628bfd0b7SJeremy L Thompson 6372b730f8bSJeremy L Thompson CeedCall(ctx->GetDataRead(ctx, mem_type, data)); 63828bfd0b7SJeremy L Thompson ctx->num_readers++; 639e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 640777ff853SJeremy L Thompson } 641777ff853SJeremy L Thompson 642777ff853SJeremy L Thompson /** 643777ff853SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetData() 644777ff853SJeremy L Thompson 645ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to restore 646ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 647777ff853SJeremy L Thompson 648777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 649777ff853SJeremy L Thompson 650777ff853SJeremy L Thompson @ref User 651777ff853SJeremy L Thompson **/ 652777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) { 6536574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 1, ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted"); 654777ff853SJeremy L Thompson 6556574a04fSJeremy L Thompson if (ctx->RestoreData) CeedCall(ctx->RestoreData(ctx)); 656777ff853SJeremy L Thompson *(void **)data = NULL; 65728bfd0b7SJeremy L Thompson ctx->state++; 65828bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 65928bfd0b7SJeremy L Thompson } 66028bfd0b7SJeremy L Thompson 66128bfd0b7SJeremy L Thompson /** 66228bfd0b7SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead() 66328bfd0b7SJeremy L Thompson 664ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to restore 665ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 66628bfd0b7SJeremy L Thompson 66728bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 66828bfd0b7SJeremy L Thompson 66928bfd0b7SJeremy L Thompson @ref User 67028bfd0b7SJeremy L Thompson **/ 67128bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) { 6726574a04fSJeremy L Thompson CeedCheck(ctx->num_readers > 0, ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted"); 67328bfd0b7SJeremy L Thompson 67475a19770SJeremy L Thompson ctx->num_readers--; 6756574a04fSJeremy L Thompson if (ctx->num_readers == 0 && ctx->RestoreDataRead) CeedCall(ctx->RestoreDataRead(ctx)); 67628bfd0b7SJeremy L Thompson *(void **)data = NULL; 677e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 678777ff853SJeremy L Thompson } 679777ff853SJeremy L Thompson 680777ff853SJeremy L Thompson /** 681cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a double precision value 682cdf32b93SJeremy L Thompson 683ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 684ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 685ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 686ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 687ea61e9acSJeremy L Thompson @param[in] field_description Description of field, or NULL for none 688cdf32b93SJeremy L Thompson 689cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 690cdf32b93SJeremy L Thompson 691cdf32b93SJeremy L Thompson @ref User 692cdf32b93SJeremy L Thompson **/ 6932b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 694cdf32b93SJeremy L Thompson const char *field_description) { 6952b730f8bSJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double), num_values); 696cdf32b93SJeremy L Thompson } 697cdf32b93SJeremy L Thompson 698cdf32b93SJeremy L Thompson /** 699cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a int32 value 700cdf32b93SJeremy L Thompson 701ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 702ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 703ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 704ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 705ea61e9acSJeremy L Thompson @param[in] field_description Description of field, or NULL for none 706cdf32b93SJeremy L Thompson 707cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 708cdf32b93SJeremy L Thompson 709cdf32b93SJeremy L Thompson @ref User 710cdf32b93SJeremy L Thompson **/ 7112b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 712cdf32b93SJeremy L Thompson const char *field_description) { 7132b730f8bSJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int), num_values); 714cdf32b93SJeremy L Thompson } 715cdf32b93SJeremy L Thompson 716cdf32b93SJeremy L Thompson /** 7173668ca4bSJeremy L Thompson @brief Get labels for all registered QFunctionContext fields 718cdf32b93SJeremy L Thompson 719ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 7203668ca4bSJeremy L Thompson @param[out] field_labels Variable to hold array of field labels 721cdf32b93SJeremy L Thompson @param[out] num_fields Length of field descriptions array 722cdf32b93SJeremy L Thompson 723cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 724cdf32b93SJeremy L Thompson 725cdf32b93SJeremy L Thompson @ref User 726cdf32b93SJeremy L Thompson **/ 7272b730f8bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, const CeedContextFieldLabel **field_labels, CeedInt *num_fields) { 7283668ca4bSJeremy L Thompson *field_labels = ctx->field_labels; 729cdf32b93SJeremy L Thompson *num_fields = ctx->num_fields; 730cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 731cdf32b93SJeremy L Thompson } 732cdf32b93SJeremy L Thompson 733cdf32b93SJeremy L Thompson /** 7340f86cbe7SJeremy L Thompson @brief Get the descriptive information about a CeedContextFieldLabel 7350f86cbe7SJeremy L Thompson 7360f86cbe7SJeremy L Thompson @param[in] label CeedContextFieldLabel 7370f86cbe7SJeremy L Thompson @param[out] field_name Name of labeled field 7380f86cbe7SJeremy L Thompson @param[out] field_description Description of field, or NULL for none 7397bfe0f0eSJeremy L Thompson @param[out] num_values Number of values registered 7400f86cbe7SJeremy L Thompson @param[out] field_type CeedContextFieldType 7410f86cbe7SJeremy L Thompson 7420f86cbe7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7430f86cbe7SJeremy L Thompson 7440f86cbe7SJeremy L Thompson @ref User 7450f86cbe7SJeremy L Thompson **/ 7462b730f8bSJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, const char **field_name, const char **field_description, size_t *num_values, 7470f86cbe7SJeremy L Thompson CeedContextFieldType *field_type) { 7480f86cbe7SJeremy L Thompson if (field_name) *field_name = label->name; 7490f86cbe7SJeremy L Thompson if (field_description) *field_description = label->description; 7507bfe0f0eSJeremy L Thompson if (num_values) *num_values = label->num_values; 7510f86cbe7SJeremy L Thompson if (field_type) *field_type = label->type; 7520f86cbe7SJeremy L Thompson return CEED_ERROR_SUCCESS; 7530f86cbe7SJeremy L Thompson } 7540f86cbe7SJeremy L Thompson 7550f86cbe7SJeremy L Thompson /** 75680a9ef05SNatalie Beams @brief Get data size for a Context 75780a9ef05SNatalie Beams 758ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 75980a9ef05SNatalie Beams @param[out] ctx_size Variable to store size of context data values 76080a9ef05SNatalie Beams 76180a9ef05SNatalie Beams @return An error code: 0 - success, otherwise - failure 76280a9ef05SNatalie Beams 76380a9ef05SNatalie Beams @ref User 76480a9ef05SNatalie Beams **/ 7652b730f8bSJeremy L Thompson int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, size_t *ctx_size) { 76680a9ef05SNatalie Beams *ctx_size = ctx->ctx_size; 76780a9ef05SNatalie Beams return CEED_ERROR_SUCCESS; 76880a9ef05SNatalie Beams } 76980a9ef05SNatalie Beams 77080a9ef05SNatalie Beams /** 771777ff853SJeremy L Thompson @brief View a CeedQFunctionContext 772777ff853SJeremy L Thompson 773777ff853SJeremy L Thompson @param[in] ctx CeedQFunctionContext to view 774777ff853SJeremy L Thompson @param[in] stream Filestream to write to 775777ff853SJeremy L Thompson 776777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 777777ff853SJeremy L Thompson 778777ff853SJeremy L Thompson @ref User 779777ff853SJeremy L Thompson **/ 780777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) { 781777ff853SJeremy L Thompson fprintf(stream, "CeedQFunctionContext\n"); 782d1d35e2fSjeremylt fprintf(stream, " Context Data Size: %ld\n", ctx->ctx_size); 7833668ca4bSJeremy L Thompson for (CeedInt i = 0; i < ctx->num_fields; i++) { 7843668ca4bSJeremy L Thompson // LCOV_EXCL_START 7852b730f8bSJeremy L Thompson fprintf(stream, " Labeled %s field: %s\n", CeedContextFieldTypes[ctx->field_labels[i]->type], ctx->field_labels[i]->name); 7863668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 7873668ca4bSJeremy L Thompson } 788e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 789777ff853SJeremy L Thompson } 790777ff853SJeremy L Thompson 791777ff853SJeremy L Thompson /** 7922790b72bSJeremy L Thompson @brief Set additional destroy routine for CeedQFunctionContext user data 7932790b72bSJeremy L Thompson 794ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to set user destroy function 7952e64a2b9SJeremy L Thompson @param[in] f_mem_type Memory type to use when passing data into `f` 7962e64a2b9SJeremy L Thompson @param[in] f Additional routine to use to destroy user data 7972790b72bSJeremy L Thompson 7982790b72bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7992790b72bSJeremy L Thompson 8002790b72bSJeremy L Thompson @ref User 8012790b72bSJeremy L Thompson **/ 8022b730f8bSJeremy L Thompson int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) { 8036574a04fSJeremy L Thompson CeedCheck(f, ctx->ceed, 1, "Must provide valid callback function for destroying user data"); 8042790b72bSJeremy L Thompson ctx->data_destroy_mem_type = f_mem_type; 8052790b72bSJeremy L Thompson ctx->data_destroy_function = f; 8062790b72bSJeremy L Thompson return CEED_ERROR_SUCCESS; 8072790b72bSJeremy L Thompson } 8082790b72bSJeremy L Thompson 8092790b72bSJeremy L Thompson /** 810777ff853SJeremy L Thompson @brief Destroy a CeedQFunctionContext 811777ff853SJeremy L Thompson 812ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to destroy 813777ff853SJeremy L Thompson 814777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 815777ff853SJeremy L Thompson 816777ff853SJeremy L Thompson @ref User 817777ff853SJeremy L Thompson **/ 818777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) { 819ad6481ceSJeremy L Thompson if (!*ctx || --(*ctx)->ref_count > 0) { 820ad6481ceSJeremy L Thompson *ctx = NULL; 821ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 822ad6481ceSJeremy L Thompson } 8236574a04fSJeremy L Thompson CeedCheck(((*ctx)->state % 2) == 0, (*ctx)->ceed, 1, "Cannot destroy CeedQFunctionContext, the access lock is in use"); 824777ff853SJeremy L Thompson 8252b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroyData(*ctx)); 8262b730f8bSJeremy L Thompson if ((*ctx)->Destroy) CeedCall((*ctx)->Destroy(*ctx)); 827cdf32b93SJeremy L Thompson for (CeedInt i = 0; i < (*ctx)->num_fields; i++) { 8282b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i]->name)); 8292b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i]->description)); 8302b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i])); 831cdf32b93SJeremy L Thompson } 8322b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels)); 8332b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*ctx)->ceed)); 8342b730f8bSJeremy L Thompson CeedCall(CeedFree(ctx)); 835cdf32b93SJeremy L Thompson 836e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 837777ff853SJeremy L Thompson } 838777ff853SJeremy L Thompson 839777ff853SJeremy L Thompson /// @} 840