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; 621c66c397SJeremy L Thompson 631c66c397SJeremy 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; 1021c66c397SJeremy 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; 2301c66c397SJeremy 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) { 2541a34d7dcSJeremy L Thompson bool is_different; 2551c66c397SJeremy L Thompson char *data; 2561c66c397SJeremy L Thompson 2573668ca4bSJeremy L Thompson // Check field type 2586574a04fSJeremy L Thompson CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED, 2596574a04fSJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name, 2606574a04fSJeremy L Thompson CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 261d8dd9a91SJeremy L Thompson 2621a34d7dcSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data)); 2631a34d7dcSJeremy L Thompson is_different = memcmp(&data[field_label->offset], values, field_label->size); 2641a34d7dcSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, &data)); 2651a34d7dcSJeremy L Thompson if (is_different) { 2662b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data)); 2672788fa27SJeremy L Thompson memcpy(&data[field_label->offset], values, field_label->size); 2682b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, &data)); 2691a34d7dcSJeremy L Thompson } 270d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 271d8dd9a91SJeremy L Thompson } 272d8dd9a91SJeremy L Thompson 273d8dd9a91SJeremy L Thompson /** 2742788fa27SJeremy L Thompson @brief Get QFunctionContext field data, read-only 2752788fa27SJeremy L Thompson 2762788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 2772788fa27SJeremy L Thompson @param[in] field_label Label of field to read 2782788fa27SJeremy L Thompson @param[in] field_type Type of field to read 2792788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 2802788fa27SJeremy L Thompson @param[out] values Pointer to context values 2812788fa27SJeremy L Thompson 2822788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2832788fa27SJeremy L Thompson 2842788fa27SJeremy L Thompson @ref Backend 2852788fa27SJeremy L Thompson **/ 2862788fa27SJeremy L Thompson int CeedQFunctionContextGetGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, 2872788fa27SJeremy L Thompson size_t *num_values, void *values) { 2881c66c397SJeremy L Thompson char *data; 2891c66c397SJeremy L Thompson 2902788fa27SJeremy L Thompson // Check field type 2916574a04fSJeremy L Thompson CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED, 2926574a04fSJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name, 2936574a04fSJeremy L Thompson CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 2942788fa27SJeremy L Thompson 2952788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data)); 2962788fa27SJeremy L Thompson *(void **)values = &data[field_label->offset]; 2972788fa27SJeremy L Thompson switch (field_type) { 2982788fa27SJeremy L Thompson case CEED_CONTEXT_FIELD_INT32: 2992788fa27SJeremy L Thompson *num_values = field_label->size / sizeof(int); 3002788fa27SJeremy L Thompson break; 3012788fa27SJeremy L Thompson case CEED_CONTEXT_FIELD_DOUBLE: 3022788fa27SJeremy L Thompson *num_values = field_label->size / sizeof(double); 3032788fa27SJeremy L Thompson break; 3042788fa27SJeremy L Thompson } 3052788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3062788fa27SJeremy L Thompson } 3072788fa27SJeremy L Thompson 3082788fa27SJeremy L Thompson /** 3092788fa27SJeremy L Thompson @brief Restore QFunctionContext field data, read-only 3102788fa27SJeremy L Thompson 3112788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 3122788fa27SJeremy L Thompson @param[in] field_label Label of field to restore 3132788fa27SJeremy L Thompson @param[in] field_type Type of field to restore 3142788fa27SJeremy L Thompson @param[out] values Pointer to context values 3152788fa27SJeremy L Thompson 3162788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3172788fa27SJeremy L Thompson 3182788fa27SJeremy L Thompson @ref Backend 3192788fa27SJeremy L Thompson **/ 3202788fa27SJeremy L Thompson int CeedQFunctionContextRestoreGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, 3212788fa27SJeremy L Thompson void *values) { 3222788fa27SJeremy L Thompson // Check field type 3236574a04fSJeremy L Thompson CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED, 3246574a04fSJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name, 3256574a04fSJeremy L Thompson CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 3262788fa27SJeremy L Thompson 3272788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, values)); 3282788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3292788fa27SJeremy L Thompson } 3302788fa27SJeremy L Thompson 3312788fa27SJeremy L Thompson /** 332bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value 333bfacc300SJeremy L Thompson 334ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 3352788fa27SJeremy L Thompson @param[in] field_label Label for field to set 336ea61e9acSJeremy L Thompson @param[in] values Values to set 337bfacc300SJeremy L Thompson 338bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 339bfacc300SJeremy L Thompson 3403e1e85abSJeremy L Thompson @ref Backend 341bfacc300SJeremy L Thompson **/ 3422b730f8bSJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, double *values) { 3436574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3442b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values)); 345bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 346bfacc300SJeremy L Thompson } 347bfacc300SJeremy L Thompson 348bfacc300SJeremy L Thompson /** 3492788fa27SJeremy L Thompson @brief Get QFunctionContext field holding a double precision value, read-only 3502788fa27SJeremy L Thompson 3512788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 3522788fa27SJeremy L Thompson @param[in] field_label Label for field to get 3532788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 3542788fa27SJeremy L Thompson @param[out] values Pointer to context values 3552788fa27SJeremy L Thompson 3562788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3572788fa27SJeremy L Thompson 3582788fa27SJeremy L Thompson @ref Backend 3592788fa27SJeremy L Thompson **/ 3602788fa27SJeremy L Thompson int CeedQFunctionContextGetDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const double **values) { 3616574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3622788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values)); 3632788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3642788fa27SJeremy L Thompson } 3652788fa27SJeremy L Thompson 3662788fa27SJeremy L Thompson /** 3672788fa27SJeremy L Thompson @brief Restore QFunctionContext field holding a double precision value, read-only 3682788fa27SJeremy L Thompson 3692788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 3702788fa27SJeremy L Thompson @param[in] field_label Label for field to restore 3712788fa27SJeremy L Thompson @param[out] values Pointer to context values 3722788fa27SJeremy L Thompson 3732788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3742788fa27SJeremy L Thompson 3752788fa27SJeremy L Thompson @ref Backend 3762788fa27SJeremy L Thompson **/ 3772788fa27SJeremy L Thompson int CeedQFunctionContextRestoreDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const double **values) { 3786574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3792788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values)); 3802788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3812788fa27SJeremy L Thompson } 3822788fa27SJeremy L Thompson 3832788fa27SJeremy L Thompson /** 384bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding an int32 value 385bfacc300SJeremy L Thompson 386ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 3872788fa27SJeremy L Thompson @param[in] field_label Label for field to set 388ea61e9acSJeremy L Thompson @param[in] values Values to set 389bfacc300SJeremy L Thompson 390bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 391bfacc300SJeremy L Thompson 3923e1e85abSJeremy L Thompson @ref Backend 393bfacc300SJeremy L Thompson **/ 3942b730f8bSJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, int *values) { 3956574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3962b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values)); 397bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 398bfacc300SJeremy L Thompson } 399bfacc300SJeremy L Thompson 400bfacc300SJeremy L Thompson /** 4012788fa27SJeremy L Thompson @brief Get QFunctionContext field holding a int32 value, read-only 4022788fa27SJeremy L Thompson 4032788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 4042788fa27SJeremy L Thompson @param[in] field_label Label for field to get 4052788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 4062788fa27SJeremy L Thompson @param[out] values Pointer to context values 4072788fa27SJeremy L Thompson 4082788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4092788fa27SJeremy L Thompson 4102788fa27SJeremy L Thompson @ref Backend 4112788fa27SJeremy L Thompson **/ 4122788fa27SJeremy L Thompson int CeedQFunctionContextGetInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const int **values) { 4136574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4142788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values)); 4152788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4162788fa27SJeremy L Thompson } 4172788fa27SJeremy L Thompson 4182788fa27SJeremy L Thompson /** 4192788fa27SJeremy L Thompson @brief Restore QFunctionContext field holding a int32 value, read-only 4202788fa27SJeremy L Thompson 4212788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 4222788fa27SJeremy L Thompson @param[in] field_label Label for field to restore 4232788fa27SJeremy L Thompson @param[out] values Pointer to context values 4242788fa27SJeremy L Thompson 4252788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4262788fa27SJeremy L Thompson 4272788fa27SJeremy L Thompson @ref Backend 4282788fa27SJeremy L Thompson **/ 4292788fa27SJeremy L Thompson int CeedQFunctionContextRestoreInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const int **values) { 4306574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4312788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values)); 4322788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4332788fa27SJeremy L Thompson } 4342788fa27SJeremy L Thompson 4352788fa27SJeremy L Thompson /** 4362e64a2b9SJeremy L Thompson @brief Get additional destroy routine for CeedQFunctionContext user data 4372e64a2b9SJeremy L Thompson 4382e64a2b9SJeremy L Thompson @param[in] ctx CeedQFunctionContext to get user destroy function 4392e64a2b9SJeremy L Thompson @param[out] f_mem_type Memory type to use when passing data into `f` 4402e64a2b9SJeremy L Thompson @param[out] f Additional routine to use to destroy user data 4412e64a2b9SJeremy L Thompson 4422e64a2b9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4432e64a2b9SJeremy L Thompson 4442e64a2b9SJeremy L Thompson @ref Backend 4452e64a2b9SJeremy L Thompson **/ 4462b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx, CeedMemType *f_mem_type, CeedQFunctionContextDataDestroyUser *f) { 4472e64a2b9SJeremy L Thompson if (f_mem_type) *f_mem_type = ctx->data_destroy_mem_type; 4482e64a2b9SJeremy L Thompson if (f) *f = ctx->data_destroy_function; 4492e64a2b9SJeremy L Thompson return CEED_ERROR_SUCCESS; 4502e64a2b9SJeremy L Thompson } 4512e64a2b9SJeremy L Thompson 4522e64a2b9SJeremy L Thompson /** 45334359f16Sjeremylt @brief Increment the reference counter for a CeedQFunctionContext 45434359f16Sjeremylt 455ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to increment the reference counter 45634359f16Sjeremylt 45734359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 45834359f16Sjeremylt 45934359f16Sjeremylt @ref Backend 46034359f16Sjeremylt **/ 4619560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) { 46234359f16Sjeremylt ctx->ref_count++; 46334359f16Sjeremylt return CEED_ERROR_SUCCESS; 46434359f16Sjeremylt } 46534359f16Sjeremylt 466777ff853SJeremy L Thompson /// @} 467777ff853SJeremy L Thompson 468777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 469777ff853SJeremy L Thompson /// CeedQFunctionContext Public API 470777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 471777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser 472777ff853SJeremy L Thompson /// @{ 473777ff853SJeremy L Thompson 474777ff853SJeremy L Thompson /** 475777ff853SJeremy L Thompson @brief Create a CeedQFunctionContext for storing CeedQFunction user context data 476777ff853SJeremy L Thompson 477ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedQFunctionContext will be created 478ea61e9acSJeremy L Thompson @param[out] ctx Address of the variable where the newly created CeedQFunctionContext will be stored 479777ff853SJeremy L Thompson 480777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 481777ff853SJeremy L Thompson 482777ff853SJeremy L Thompson @ref User 483777ff853SJeremy L Thompson **/ 484777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) { 485777ff853SJeremy L Thompson if (!ceed->QFunctionContextCreate) { 486777ff853SJeremy L Thompson Ceed delegate; 4876574a04fSJeremy L Thompson 4882b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Context")); 4896574a04fSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextCreate"); 4902b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextCreate(delegate, ctx)); 491e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 492777ff853SJeremy L Thompson } 493777ff853SJeremy L Thompson 4942b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, ctx)); 495db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*ctx)->ceed)); 496d1d35e2fSjeremylt (*ctx)->ref_count = 1; 4972b730f8bSJeremy L Thompson CeedCall(ceed->QFunctionContextCreate(*ctx)); 498e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 499777ff853SJeremy L Thompson } 500777ff853SJeremy L Thompson 501777ff853SJeremy L Thompson /** 502ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedQFunctionContext. 5034385fb7fSSebastian Grimberg 504ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedQFunctionContextDestroy()`. 505512bb800SJeremy L Thompson 506512bb800SJeremy 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 507512bb800SJeremy L Thompson CeedQFunctionContext. This CeedQFunctionContext will be destroyed if `ctx_copy` is the only reference to this CeedQFunctionContext. 5089560d06aSjeremylt 509ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to copy reference to 510ea61e9acSJeremy L Thompson @param[in,out] ctx_copy Variable to store copied reference 5119560d06aSjeremylt 5129560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 5139560d06aSjeremylt 5149560d06aSjeremylt @ref User 5159560d06aSjeremylt **/ 5162b730f8bSJeremy L Thompson int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, CeedQFunctionContext *ctx_copy) { 5172b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextReference(ctx)); 5182b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(ctx_copy)); 5199560d06aSjeremylt *ctx_copy = ctx; 5209560d06aSjeremylt return CEED_ERROR_SUCCESS; 5219560d06aSjeremylt } 5229560d06aSjeremylt 5239560d06aSjeremylt /** 524ea61e9acSJeremy L Thompson @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated data if applicable. 5254385fb7fSSebastian Grimberg 526ea61e9acSJeremy L Thompson The backend may copy values to a different memtype, such as during @ref CeedQFunctionApply(). 527777ff853SJeremy L Thompson See also @ref CeedQFunctionContextTakeData(). 528777ff853SJeremy L Thompson 529ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 530ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the data being passed 531ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the data 532ea61e9acSJeremy L Thompson @param[in] size Size of data, in bytes 533ea61e9acSJeremy L Thompson @param[in] data Data to be used 534777ff853SJeremy L Thompson 535777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 536777ff853SJeremy L Thompson 537777ff853SJeremy L Thompson @ref User 538777ff853SJeremy L Thompson **/ 5392b730f8bSJeremy L Thompson int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, size_t size, void *data) { 5406574a04fSJeremy L Thompson CeedCheck(ctx->SetData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextSetData"); 5416574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 542777ff853SJeremy L Thompson 5432b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroyData(ctx)); 544d1d35e2fSjeremylt ctx->ctx_size = size; 5452b730f8bSJeremy L Thompson CeedCall(ctx->SetData(ctx, mem_type, copy_mode, data)); 546777ff853SJeremy L Thompson ctx->state += 2; 547e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 548777ff853SJeremy L Thompson } 549777ff853SJeremy L Thompson 550777ff853SJeremy L Thompson /** 551891038deSjeremylt @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type. 5524385fb7fSSebastian Grimberg 553891038deSjeremylt The caller is responsible for managing and freeing the memory. 554891038deSjeremylt 555ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 556ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 557ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 558891038deSjeremylt @param[out] data Data on memory type mem_type 559891038deSjeremylt 560891038deSjeremylt @return An error code: 0 - success, otherwise - failure 561891038deSjeremylt 562891038deSjeremylt @ref User 563891038deSjeremylt **/ 5642b730f8bSJeremy L Thompson int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 5651c66c397SJeremy L Thompson void *temp_data = NULL; 5661c66c397SJeremy L Thompson bool has_valid_data = true, has_borrowed_data_of_type = true; 5671c66c397SJeremy L Thompson 5682b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 5696574a04fSJeremy L Thompson CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to take, must set data"); 5709c774eddSJeremy L Thompson 5716574a04fSJeremy L Thompson CeedCheck(ctx->TakeData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support TakeData"); 5726574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 573891038deSjeremylt 5742b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, &has_borrowed_data_of_type)); 5756574a04fSJeremy L Thompson CeedCheck(has_borrowed_data_of_type, ctx->ceed, CEED_ERROR_BACKEND, 5766574a04fSJeremy L Thompson "CeedQFunctionContext has no borrowed %s data, must set data with CeedQFunctionContextSetData", CeedMemTypes[mem_type]); 5779c774eddSJeremy L Thompson 5782b730f8bSJeremy L Thompson CeedCall(ctx->TakeData(ctx, mem_type, &temp_data)); 579891038deSjeremylt if (data) (*(void **)data) = temp_data; 580891038deSjeremylt return CEED_ERROR_SUCCESS; 581891038deSjeremylt } 582891038deSjeremylt 583891038deSjeremylt /** 584777ff853SJeremy L Thompson @brief Get read/write access to a CeedQFunctionContext via the specified memory type. 5854385fb7fSSebastian Grimberg 586777ff853SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 587777ff853SJeremy L Thompson 588ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 589ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 590ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 591d1d35e2fSjeremylt @param[out] data Data on memory type mem_type 592777ff853SJeremy L Thompson 593ea61e9acSJeremy L Thompson @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions provide access to array pointers in the desired memory 5949fd66db6SSebastian Grimberg space. 5959fd66db6SSebastian Grimberg Pairing get/restore allows the Context to track access. 596777ff853SJeremy L Thompson 597777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 598777ff853SJeremy L Thompson 599777ff853SJeremy L Thompson @ref User 600777ff853SJeremy L Thompson **/ 6012b730f8bSJeremy L Thompson int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 6021c66c397SJeremy L Thompson bool has_valid_data = true; 6031c66c397SJeremy L Thompson 6046574a04fSJeremy L Thompson CeedCheck(ctx->GetData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetData"); 6056574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 6066574a04fSJeremy L Thompson CeedCheck(ctx->num_readers == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, a process has read access"); 60728bfd0b7SJeremy L Thompson 6082b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 6096574a04fSJeremy L Thompson CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data"); 6109c774eddSJeremy L Thompson 6112b730f8bSJeremy L Thompson CeedCall(ctx->GetData(ctx, mem_type, data)); 61228bfd0b7SJeremy L Thompson ctx->state++; 61328bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 61428bfd0b7SJeremy L Thompson } 61528bfd0b7SJeremy L Thompson 61628bfd0b7SJeremy L Thompson /** 61728bfd0b7SJeremy L Thompson @brief Get read only access to a CeedQFunctionContext via the specified memory type. 6184385fb7fSSebastian Grimberg 61928bfd0b7SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 62028bfd0b7SJeremy L Thompson 621ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 622ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 623ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 62428bfd0b7SJeremy L Thompson @param[out] data Data on memory type mem_type 62528bfd0b7SJeremy L Thompson 626ea61e9acSJeremy L Thompson @note The CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead() functions provide access to array pointers in the desired 6279fd66db6SSebastian Grimberg memory space. 6289fd66db6SSebastian Grimberg Pairing get/restore allows the Context to track access. 62928bfd0b7SJeremy L Thompson 63028bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 63128bfd0b7SJeremy L Thompson 63228bfd0b7SJeremy L Thompson @ref User 63328bfd0b7SJeremy L Thompson **/ 6342b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 6351c66c397SJeremy L Thompson bool has_valid_data = true; 6361c66c397SJeremy L Thompson 6376574a04fSJeremy L Thompson CeedCheck(ctx->GetDataRead, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetDataRead"); 6386574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 63928bfd0b7SJeremy L Thompson 6402b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 6416574a04fSJeremy L Thompson CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data"); 64228bfd0b7SJeremy L Thompson 6432b730f8bSJeremy L Thompson CeedCall(ctx->GetDataRead(ctx, mem_type, data)); 64428bfd0b7SJeremy L Thompson ctx->num_readers++; 645e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 646777ff853SJeremy L Thompson } 647777ff853SJeremy L Thompson 648777ff853SJeremy L Thompson /** 649777ff853SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetData() 650777ff853SJeremy L Thompson 651ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to restore 652ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 653777ff853SJeremy L Thompson 654777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 655777ff853SJeremy L Thompson 656777ff853SJeremy L Thompson @ref User 657777ff853SJeremy L Thompson **/ 658777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) { 6596574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 1, ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted"); 660777ff853SJeremy L Thompson 6616574a04fSJeremy L Thompson if (ctx->RestoreData) CeedCall(ctx->RestoreData(ctx)); 662777ff853SJeremy L Thompson *(void **)data = NULL; 66328bfd0b7SJeremy L Thompson ctx->state++; 66428bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 66528bfd0b7SJeremy L Thompson } 66628bfd0b7SJeremy L Thompson 66728bfd0b7SJeremy L Thompson /** 66828bfd0b7SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead() 66928bfd0b7SJeremy L Thompson 670ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to restore 671ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 67228bfd0b7SJeremy L Thompson 67328bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 67428bfd0b7SJeremy L Thompson 67528bfd0b7SJeremy L Thompson @ref User 67628bfd0b7SJeremy L Thompson **/ 67728bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) { 6786574a04fSJeremy L Thompson CeedCheck(ctx->num_readers > 0, ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted"); 67928bfd0b7SJeremy L Thompson 68075a19770SJeremy L Thompson ctx->num_readers--; 6816574a04fSJeremy L Thompson if (ctx->num_readers == 0 && ctx->RestoreDataRead) CeedCall(ctx->RestoreDataRead(ctx)); 68228bfd0b7SJeremy L Thompson *(void **)data = NULL; 683e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 684777ff853SJeremy L Thompson } 685777ff853SJeremy L Thompson 686777ff853SJeremy L Thompson /** 687cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a double precision value 688cdf32b93SJeremy L Thompson 689ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 690ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 691ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 692ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 693ea61e9acSJeremy L Thompson @param[in] field_description Description of field, or NULL for none 694cdf32b93SJeremy L Thompson 695cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 696cdf32b93SJeremy L Thompson 697cdf32b93SJeremy L Thompson @ref User 698cdf32b93SJeremy L Thompson **/ 6992b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 700cdf32b93SJeremy L Thompson const char *field_description) { 7012b730f8bSJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double), num_values); 702cdf32b93SJeremy L Thompson } 703cdf32b93SJeremy L Thompson 704cdf32b93SJeremy L Thompson /** 705cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a int32 value 706cdf32b93SJeremy L Thompson 707ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 708ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 709ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 710ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 711ea61e9acSJeremy L Thompson @param[in] field_description Description of field, or NULL for none 712cdf32b93SJeremy L Thompson 713cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 714cdf32b93SJeremy L Thompson 715cdf32b93SJeremy L Thompson @ref User 716cdf32b93SJeremy L Thompson **/ 7172b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 718cdf32b93SJeremy L Thompson const char *field_description) { 7192b730f8bSJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int), num_values); 720cdf32b93SJeremy L Thompson } 721cdf32b93SJeremy L Thompson 722cdf32b93SJeremy L Thompson /** 7233668ca4bSJeremy L Thompson @brief Get labels for all registered QFunctionContext fields 724cdf32b93SJeremy L Thompson 725ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 7263668ca4bSJeremy L Thompson @param[out] field_labels Variable to hold array of field labels 727cdf32b93SJeremy L Thompson @param[out] num_fields Length of field descriptions array 728cdf32b93SJeremy L Thompson 729cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 730cdf32b93SJeremy L Thompson 731cdf32b93SJeremy L Thompson @ref User 732cdf32b93SJeremy L Thompson **/ 7332b730f8bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, const CeedContextFieldLabel **field_labels, CeedInt *num_fields) { 7343668ca4bSJeremy L Thompson *field_labels = ctx->field_labels; 735cdf32b93SJeremy L Thompson *num_fields = ctx->num_fields; 736cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 737cdf32b93SJeremy L Thompson } 738cdf32b93SJeremy L Thompson 739cdf32b93SJeremy L Thompson /** 7400f86cbe7SJeremy L Thompson @brief Get the descriptive information about a CeedContextFieldLabel 7410f86cbe7SJeremy L Thompson 7420f86cbe7SJeremy L Thompson @param[in] label CeedContextFieldLabel 7430f86cbe7SJeremy L Thompson @param[out] field_name Name of labeled field 744*1ff07f3dSJeremy L Thompson @param[out] field_offset Offset of field registered 7457bfe0f0eSJeremy L Thompson @param[out] num_values Number of values registered 746*1ff07f3dSJeremy L Thompson @param[out] field_description Description of field, or NULL for none 7470f86cbe7SJeremy L Thompson @param[out] field_type CeedContextFieldType 7480f86cbe7SJeremy L Thompson 7490f86cbe7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7500f86cbe7SJeremy L Thompson 7510f86cbe7SJeremy L Thompson @ref User 7520f86cbe7SJeremy L Thompson **/ 753*1ff07f3dSJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, const char **field_name, size_t *field_offset, size_t *num_values, 754*1ff07f3dSJeremy L Thompson const char **field_description, CeedContextFieldType *field_type) { 7550f86cbe7SJeremy L Thompson if (field_name) *field_name = label->name; 756*1ff07f3dSJeremy L Thompson if (field_offset) *field_offset = label->offset; 7577bfe0f0eSJeremy L Thompson if (num_values) *num_values = label->num_values; 758*1ff07f3dSJeremy L Thompson if (field_description) *field_description = label->description; 7590f86cbe7SJeremy L Thompson if (field_type) *field_type = label->type; 7600f86cbe7SJeremy L Thompson return CEED_ERROR_SUCCESS; 7610f86cbe7SJeremy L Thompson } 7620f86cbe7SJeremy L Thompson 7630f86cbe7SJeremy L Thompson /** 76480a9ef05SNatalie Beams @brief Get data size for a Context 76580a9ef05SNatalie Beams 766ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 76780a9ef05SNatalie Beams @param[out] ctx_size Variable to store size of context data values 76880a9ef05SNatalie Beams 76980a9ef05SNatalie Beams @return An error code: 0 - success, otherwise - failure 77080a9ef05SNatalie Beams 77180a9ef05SNatalie Beams @ref User 77280a9ef05SNatalie Beams **/ 7732b730f8bSJeremy L Thompson int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, size_t *ctx_size) { 77480a9ef05SNatalie Beams *ctx_size = ctx->ctx_size; 77580a9ef05SNatalie Beams return CEED_ERROR_SUCCESS; 77680a9ef05SNatalie Beams } 77780a9ef05SNatalie Beams 77880a9ef05SNatalie Beams /** 779777ff853SJeremy L Thompson @brief View a CeedQFunctionContext 780777ff853SJeremy L Thompson 781777ff853SJeremy L Thompson @param[in] ctx CeedQFunctionContext to view 782777ff853SJeremy L Thompson @param[in] stream Filestream to write to 783777ff853SJeremy L Thompson 784777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 785777ff853SJeremy L Thompson 786777ff853SJeremy L Thompson @ref User 787777ff853SJeremy L Thompson **/ 788777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) { 789777ff853SJeremy L Thompson fprintf(stream, "CeedQFunctionContext\n"); 790d1d35e2fSjeremylt fprintf(stream, " Context Data Size: %ld\n", ctx->ctx_size); 7913668ca4bSJeremy L Thompson for (CeedInt i = 0; i < ctx->num_fields; i++) { 7923668ca4bSJeremy L Thompson // LCOV_EXCL_START 7932b730f8bSJeremy L Thompson fprintf(stream, " Labeled %s field: %s\n", CeedContextFieldTypes[ctx->field_labels[i]->type], ctx->field_labels[i]->name); 7943668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 7953668ca4bSJeremy L Thompson } 796e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 797777ff853SJeremy L Thompson } 798777ff853SJeremy L Thompson 799777ff853SJeremy L Thompson /** 8002790b72bSJeremy L Thompson @brief Set additional destroy routine for CeedQFunctionContext user data 8012790b72bSJeremy L Thompson 802ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to set user destroy function 8032e64a2b9SJeremy L Thompson @param[in] f_mem_type Memory type to use when passing data into `f` 8042e64a2b9SJeremy L Thompson @param[in] f Additional routine to use to destroy user data 8052790b72bSJeremy L Thompson 8062790b72bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8072790b72bSJeremy L Thompson 8082790b72bSJeremy L Thompson @ref User 8092790b72bSJeremy L Thompson **/ 8102b730f8bSJeremy L Thompson int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) { 8116574a04fSJeremy L Thompson CeedCheck(f, ctx->ceed, 1, "Must provide valid callback function for destroying user data"); 8122790b72bSJeremy L Thompson ctx->data_destroy_mem_type = f_mem_type; 8132790b72bSJeremy L Thompson ctx->data_destroy_function = f; 8142790b72bSJeremy L Thompson return CEED_ERROR_SUCCESS; 8152790b72bSJeremy L Thompson } 8162790b72bSJeremy L Thompson 8172790b72bSJeremy L Thompson /** 818777ff853SJeremy L Thompson @brief Destroy a CeedQFunctionContext 819777ff853SJeremy L Thompson 820ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to destroy 821777ff853SJeremy L Thompson 822777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 823777ff853SJeremy L Thompson 824777ff853SJeremy L Thompson @ref User 825777ff853SJeremy L Thompson **/ 826777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) { 827ad6481ceSJeremy L Thompson if (!*ctx || --(*ctx)->ref_count > 0) { 828ad6481ceSJeremy L Thompson *ctx = NULL; 829ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 830ad6481ceSJeremy L Thompson } 8316574a04fSJeremy L Thompson CeedCheck(((*ctx)->state % 2) == 0, (*ctx)->ceed, 1, "Cannot destroy CeedQFunctionContext, the access lock is in use"); 832777ff853SJeremy L Thompson 8332b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroyData(*ctx)); 8342b730f8bSJeremy L Thompson if ((*ctx)->Destroy) CeedCall((*ctx)->Destroy(*ctx)); 835cdf32b93SJeremy L Thompson for (CeedInt i = 0; i < (*ctx)->num_fields; i++) { 8362b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i]->name)); 8372b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i]->description)); 8382b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i])); 839cdf32b93SJeremy L Thompson } 8402b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels)); 8412b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*ctx)->ceed)); 8422b730f8bSJeremy L Thompson CeedCall(CeedFree(ctx)); 843e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 844777ff853SJeremy L Thompson } 845777ff853SJeremy L Thompson 846777ff853SJeremy L Thompson /// @} 847