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 /** 26ca94c3ddSJeremy L Thompson @brief Get index for `CeedQFunctionContext` field 27cdf32b93SJeremy L Thompson 28ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` 29ea61e9acSJeremy L Thompson @param[in] field_name Name of field 30ca94c3ddSJeremy 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 /** 45ca94c3ddSJeremy L Thompson @brief Common function for registering `CeedQFunctionContext` fields 46cdf32b93SJeremy L Thompson 47ca94c3ddSJeremy 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 50ca94c3ddSJeremy L Thompson @param[in] field_description Description of field, or `NULL` for none 51ca94c3ddSJeremy L Thompson @param[in] field_type @ref CeedContextFieldType 52ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 53cdf32b93SJeremy L Thompson 54cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 55cdf32b93SJeremy L Thompson 56cdf32b93SJeremy L Thompson @ref Developer 57cdf32b93SJeremy L Thompson **/ 582b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, const char *field_description, 595b6ec284SJeremy L Thompson CeedContextFieldType field_type, size_t num_values) { 605b6ec284SJeremy L Thompson size_t field_size = 0; 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 775b6ec284SJeremy L Thompson // Compute field size 785b6ec284SJeremy L Thompson switch (field_type) { 795b6ec284SJeremy L Thompson case CEED_CONTEXT_FIELD_DOUBLE: 805b6ec284SJeremy L Thompson field_size = sizeof(double); 815b6ec284SJeremy L Thompson break; 825b6ec284SJeremy L Thompson case CEED_CONTEXT_FIELD_INT32: 835b6ec284SJeremy L Thompson field_size = sizeof(int); 845b6ec284SJeremy L Thompson break; 855b6ec284SJeremy L Thompson case CEED_CONTEXT_FIELD_BOOL: 865b6ec284SJeremy L Thompson field_size = sizeof(bool); 875b6ec284SJeremy L Thompson break; 885b6ec284SJeremy L Thompson } 895b6ec284SJeremy L Thompson 90cdf32b93SJeremy L Thompson // Copy field data 912b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_name, (char **)&ctx->field_labels[ctx->num_fields]->name)); 922b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_description, (char **)&ctx->field_labels[ctx->num_fields]->description)); 933668ca4bSJeremy L Thompson ctx->field_labels[ctx->num_fields]->type = field_type; 943668ca4bSJeremy L Thompson ctx->field_labels[ctx->num_fields]->offset = field_offset; 957bfe0f0eSJeremy L Thompson ctx->field_labels[ctx->num_fields]->size = field_size * num_values; 967bfe0f0eSJeremy L Thompson ctx->field_labels[ctx->num_fields]->num_values = num_values; 97cdf32b93SJeremy L Thompson ctx->num_fields++; 98cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 99cdf32b93SJeremy L Thompson } 100cdf32b93SJeremy L Thompson 1013b190ab8SJeremy L Thompson /** 102ca94c3ddSJeremy L Thompson @brief Destroy user data held by `CeedQFunctionContext`, using function set by @ref CeedQFunctionContextSetDataDestroy(), if applicable 1033b190ab8SJeremy L Thompson 104ca94c3ddSJeremy L Thompson @param[in,out] ctx `CeedQFunctionContext` to destroy user data 1053b190ab8SJeremy L Thompson 1063b190ab8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1073b190ab8SJeremy L Thompson 1083b190ab8SJeremy L Thompson @ref Developer 1093b190ab8SJeremy L Thompson **/ 1103b190ab8SJeremy L Thompson static int CeedQFunctionContextDestroyData(CeedQFunctionContext ctx) { 1113b190ab8SJeremy L Thompson if (ctx->DataDestroy) { 1122b730f8bSJeremy L Thompson CeedCall(ctx->DataDestroy(ctx)); 1133b190ab8SJeremy L Thompson } else { 1143b190ab8SJeremy L Thompson CeedMemType data_destroy_mem_type; 1151c66c397SJeremy L Thompson CeedQFunctionContextDataDestroyUser data_destroy_function; 1163b190ab8SJeremy L Thompson 1172b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function)); 1183b190ab8SJeremy L Thompson if (data_destroy_function) { 1193b190ab8SJeremy L Thompson void *data; 1203b190ab8SJeremy L Thompson 1212b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, data_destroy_mem_type, &data)); 1222b730f8bSJeremy L Thompson CeedCall(data_destroy_function(data)); 1232b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, &data)); 1243b190ab8SJeremy L Thompson } 1253b190ab8SJeremy L Thompson } 1263b190ab8SJeremy L Thompson return CEED_ERROR_SUCCESS; 1273b190ab8SJeremy L Thompson } 1283b190ab8SJeremy L Thompson 129cdf32b93SJeremy L Thompson /// @} 130cdf32b93SJeremy L Thompson 131cdf32b93SJeremy L Thompson /// ---------------------------------------------------------------------------- 132777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API 133777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 134777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend 135777ff853SJeremy L Thompson /// @{ 136777ff853SJeremy L Thompson 137777ff853SJeremy L Thompson /** 138ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedQFunctionContext` 139777ff853SJeremy L Thompson 140ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` 141ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store `Ceed` 142777ff853SJeremy L Thompson 143777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 144777ff853SJeremy L Thompson 145777ff853SJeremy L Thompson @ref Backend 146777ff853SJeremy L Thompson **/ 147777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) { 148777ff853SJeremy L Thompson *ceed = ctx->ceed; 149e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 150777ff853SJeremy L Thompson } 151777ff853SJeremy L Thompson 152777ff853SJeremy L Thompson /** 153ca94c3ddSJeremy L Thompson @brief Check for valid data in a `CeedQFunctionContext` 1549c774eddSJeremy L Thompson 155ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` to check validity 1569c774eddSJeremy L Thompson @param[out] has_valid_data Variable to store validity 1579c774eddSJeremy L Thompson 1589c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1599c774eddSJeremy L Thompson 1609c774eddSJeremy L Thompson @ref Backend 1619c774eddSJeremy L Thompson **/ 1622b730f8bSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx, bool *has_valid_data) { 163ca94c3ddSJeremy L Thompson CeedCheck(ctx->HasValidData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextHasValidData"); 1642b730f8bSJeremy L Thompson CeedCall(ctx->HasValidData(ctx, has_valid_data)); 1659c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 1669c774eddSJeremy L Thompson } 1679c774eddSJeremy L Thompson 1689c774eddSJeremy L Thompson /** 169ca94c3ddSJeremy L Thompson @brief Check for borrowed data of a specific @ref CeedMemType in a `CeedQFunctionContext` 1709c774eddSJeremy L Thompson 171ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` to check 172ea61e9acSJeremy L Thompson @param[in] mem_type Memory type to check 1739c774eddSJeremy L Thompson @param[out] has_borrowed_data_of_type Variable to store result 1749c774eddSJeremy L Thompson 1759c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1769c774eddSJeremy L Thompson 1779c774eddSJeremy L Thompson @ref Backend 1789c774eddSJeremy L Thompson **/ 1792b730f8bSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx, CeedMemType mem_type, bool *has_borrowed_data_of_type) { 180ca94c3ddSJeremy L Thompson CeedCheck(ctx->HasBorrowedDataOfType, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextHasBorrowedDataOfType"); 1812b730f8bSJeremy L Thompson CeedCall(ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type)); 1829c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 1839c774eddSJeremy L Thompson } 1849c774eddSJeremy L Thompson 1859c774eddSJeremy L Thompson /** 186ca94c3ddSJeremy L Thompson @brief Get the state of a `CeedQFunctionContext` 187777ff853SJeremy L Thompson 188ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` to retrieve state 189777ff853SJeremy L Thompson @param[out] state Variable to store state 190777ff853SJeremy L Thompson 191777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 192777ff853SJeremy L Thompson 193777ff853SJeremy L Thompson @ref Backend 194777ff853SJeremy L Thompson **/ 195777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) { 196777ff853SJeremy L Thompson *state = ctx->state; 197e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 198777ff853SJeremy L Thompson } 199777ff853SJeremy L Thompson 200777ff853SJeremy L Thompson /** 201ca94c3ddSJeremy L Thompson @brief Get backend data of a `CeedQFunctionContext` 202777ff853SJeremy L Thompson 203ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` 204777ff853SJeremy L Thompson @param[out] data Variable to store data 205777ff853SJeremy L Thompson 206777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 207777ff853SJeremy L Thompson 208777ff853SJeremy L Thompson @ref Backend 209777ff853SJeremy L Thompson **/ 210777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) { 211777ff853SJeremy L Thompson *(void **)data = ctx->data; 212e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 213777ff853SJeremy L Thompson } 214777ff853SJeremy L Thompson 215777ff853SJeremy L Thompson /** 216ca94c3ddSJeremy L Thompson @brief Set backend data of a `CeedQFunctionContext` 217777ff853SJeremy L Thompson 218ca94c3ddSJeremy L Thompson @param[in,out] ctx `CeedQFunctionContext` 219ea61e9acSJeremy L Thompson @param[in] data Data to set 220777ff853SJeremy L Thompson 221777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 222777ff853SJeremy L Thompson 223777ff853SJeremy L Thompson @ref Backend 224777ff853SJeremy L Thompson **/ 225777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) { 226777ff853SJeremy L Thompson ctx->data = data; 227e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 228777ff853SJeremy L Thompson } 229777ff853SJeremy L Thompson 23034359f16Sjeremylt /** 231ca94c3ddSJeremy L Thompson @brief Get label for a registered `CeedQFunctionContext` field, or `NULL` if no field has been registered with this `field_name` 232e6a0ab89SJeremy L Thompson 233ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` 234e6a0ab89SJeremy L Thompson @param[in] field_name Name of field to retrieve label 235e6a0ab89SJeremy L Thompson @param[out] field_label Variable to field label 236e6a0ab89SJeremy L Thompson 237e6a0ab89SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 238e6a0ab89SJeremy L Thompson 2393e1e85abSJeremy L Thompson @ref Backend 240e6a0ab89SJeremy L Thompson **/ 2412b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx, const char *field_name, CeedContextFieldLabel *field_label) { 242e6a0ab89SJeremy L Thompson CeedInt field_index; 2431c66c397SJeremy L Thompson 2442b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index)); 245e6a0ab89SJeremy L Thompson 246e6a0ab89SJeremy L Thompson if (field_index != -1) { 247e6a0ab89SJeremy L Thompson *field_label = ctx->field_labels[field_index]; 248e6a0ab89SJeremy L Thompson } else { 249e6a0ab89SJeremy L Thompson *field_label = NULL; 250e6a0ab89SJeremy L Thompson } 251e6a0ab89SJeremy L Thompson return CEED_ERROR_SUCCESS; 252e6a0ab89SJeremy L Thompson } 253e6a0ab89SJeremy L Thompson 254e6a0ab89SJeremy L Thompson /** 255ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field 256d8dd9a91SJeremy L Thompson 257ca94c3ddSJeremy L Thompson @param[in,out] ctx `CeedQFunctionContext` 258ea61e9acSJeremy L Thompson @param[in] field_label Label of field to set 259ea61e9acSJeremy L Thompson @param[in] field_type Type of field to set 2602788fa27SJeremy L Thompson @param[in] values Value to set 261d8dd9a91SJeremy L Thompson 262d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 263d8dd9a91SJeremy L Thompson 2643e1e85abSJeremy L Thompson @ref Backend 265d8dd9a91SJeremy L Thompson **/ 2662788fa27SJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *values) { 2671a34d7dcSJeremy L Thompson bool is_different; 2681c66c397SJeremy L Thompson char *data; 2691c66c397SJeremy L Thompson 2703668ca4bSJeremy L Thompson // Check field type 2716574a04fSJeremy L Thompson CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED, 2726574a04fSJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name, 2736574a04fSJeremy L Thompson CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 274d8dd9a91SJeremy L Thompson 2751a34d7dcSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data)); 2761a34d7dcSJeremy L Thompson is_different = memcmp(&data[field_label->offset], values, field_label->size); 2771a34d7dcSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, &data)); 2781a34d7dcSJeremy L Thompson if (is_different) { 2792b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data)); 2802788fa27SJeremy L Thompson memcpy(&data[field_label->offset], values, field_label->size); 2812b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, &data)); 2821a34d7dcSJeremy L Thompson } 283d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 284d8dd9a91SJeremy L Thompson } 285d8dd9a91SJeremy L Thompson 286d8dd9a91SJeremy L Thompson /** 287ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field data, read-only 2882788fa27SJeremy L Thompson 289ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` 2902788fa27SJeremy L Thompson @param[in] field_label Label of field to read 2912788fa27SJeremy L Thompson @param[in] field_type Type of field to read 2922788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 2932788fa27SJeremy L Thompson @param[out] values Pointer to context values 2942788fa27SJeremy L Thompson 2952788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2962788fa27SJeremy L Thompson 2972788fa27SJeremy L Thompson @ref Backend 2982788fa27SJeremy L Thompson **/ 2992788fa27SJeremy L Thompson int CeedQFunctionContextGetGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, 3002788fa27SJeremy L Thompson size_t *num_values, void *values) { 3011c66c397SJeremy L Thompson char *data; 3021c66c397SJeremy L Thompson 3032788fa27SJeremy L Thompson // Check field type 3046574a04fSJeremy L Thompson CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED, 3056574a04fSJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name, 3066574a04fSJeremy L Thompson CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 3072788fa27SJeremy L Thompson 3082788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data)); 3092788fa27SJeremy L Thompson *(void **)values = &data[field_label->offset]; 3102788fa27SJeremy L Thompson switch (field_type) { 3112788fa27SJeremy L Thompson case CEED_CONTEXT_FIELD_INT32: 3122788fa27SJeremy L Thompson *num_values = field_label->size / sizeof(int); 3132788fa27SJeremy L Thompson break; 3142788fa27SJeremy L Thompson case CEED_CONTEXT_FIELD_DOUBLE: 3152788fa27SJeremy L Thompson *num_values = field_label->size / sizeof(double); 3162788fa27SJeremy L Thompson break; 3175b6ec284SJeremy L Thompson case CEED_CONTEXT_FIELD_BOOL: 3185b6ec284SJeremy L Thompson *num_values = field_label->size / sizeof(bool); 3195b6ec284SJeremy L Thompson break; 3202788fa27SJeremy L Thompson } 3212788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3222788fa27SJeremy L Thompson } 3232788fa27SJeremy L Thompson 3242788fa27SJeremy L Thompson /** 325ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field data, read-only 3262788fa27SJeremy L Thompson 327ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` 3282788fa27SJeremy L Thompson @param[in] field_label Label of field to restore 3292788fa27SJeremy L Thompson @param[in] field_type Type of field to restore 3302788fa27SJeremy L Thompson @param[out] values Pointer to context values 3312788fa27SJeremy L Thompson 3322788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3332788fa27SJeremy L Thompson 3342788fa27SJeremy L Thompson @ref Backend 3352788fa27SJeremy L Thompson **/ 3362788fa27SJeremy L Thompson int CeedQFunctionContextRestoreGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, 3372788fa27SJeremy L Thompson void *values) { 3382788fa27SJeremy L Thompson // Check field type 3396574a04fSJeremy L Thompson CeedCheck(field_label->type == field_type, ctx->ceed, CEED_ERROR_UNSUPPORTED, 3406574a04fSJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name, 3416574a04fSJeremy L Thompson CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 3422788fa27SJeremy L Thompson 3432788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, values)); 3442788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3452788fa27SJeremy L Thompson } 3462788fa27SJeremy L Thompson 3472788fa27SJeremy L Thompson /** 348ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field holding double precision values 349bfacc300SJeremy L Thompson 350ca94c3ddSJeremy L Thompson @param[in,out] ctx `CeedQFunctionContext` 3512788fa27SJeremy L Thompson @param[in] field_label Label for field to set 352ea61e9acSJeremy L Thompson @param[in] values Values to set 353bfacc300SJeremy L Thompson 354bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 355bfacc300SJeremy L Thompson 3563e1e85abSJeremy L Thompson @ref Backend 357bfacc300SJeremy L Thompson **/ 3582b730f8bSJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, double *values) { 3596574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3602b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values)); 361bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 362bfacc300SJeremy L Thompson } 363bfacc300SJeremy L Thompson 364bfacc300SJeremy L Thompson /** 365ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding double precision values, read-only 3662788fa27SJeremy L Thompson 367ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` 3682788fa27SJeremy L Thompson @param[in] field_label Label for field to get 3692788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 3702788fa27SJeremy L Thompson @param[out] values Pointer to context values 3712788fa27SJeremy L Thompson 3722788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3732788fa27SJeremy L Thompson 3742788fa27SJeremy L Thompson @ref Backend 3752788fa27SJeremy L Thompson **/ 3762788fa27SJeremy L Thompson int CeedQFunctionContextGetDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const double **values) { 3776574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3782788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values)); 3792788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3802788fa27SJeremy L Thompson } 3812788fa27SJeremy L Thompson 3822788fa27SJeremy L Thompson /** 383ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding double precision values, read-only 3842788fa27SJeremy L Thompson 385ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` 3862788fa27SJeremy L Thompson @param[in] field_label Label for field to restore 3872788fa27SJeremy L Thompson @param[out] values Pointer to context values 3882788fa27SJeremy L Thompson 3892788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3902788fa27SJeremy L Thompson 3912788fa27SJeremy L Thompson @ref Backend 3922788fa27SJeremy L Thompson **/ 3932788fa27SJeremy L Thompson int CeedQFunctionContextRestoreDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const double **values) { 3946574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3952788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values)); 3962788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3972788fa27SJeremy L Thompson } 3982788fa27SJeremy L Thompson 3992788fa27SJeremy L Thompson /** 400ca94c3ddSJeremy L Thompson @brief Set CeedQFunctionContext field holding `int32` values 401bfacc300SJeremy L Thompson 402ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 4032788fa27SJeremy L Thompson @param[in] field_label Label for field to set 404ea61e9acSJeremy L Thompson @param[in] values Values to set 405bfacc300SJeremy L Thompson 406bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 407bfacc300SJeremy L Thompson 4083e1e85abSJeremy L Thompson @ref Backend 409bfacc300SJeremy L Thompson **/ 41023dbfd29SJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, int32_t *values) { 4116574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4122b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values)); 413bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 414bfacc300SJeremy L Thompson } 415bfacc300SJeremy L Thompson 416bfacc300SJeremy L Thompson /** 417ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding `int32` values, read-only 4182788fa27SJeremy L Thompson 419ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` 4202788fa27SJeremy L Thompson @param[in] field_label Label for field to get 4212788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 4222788fa27SJeremy L Thompson @param[out] values Pointer to context values 4232788fa27SJeremy L Thompson 4242788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4252788fa27SJeremy L Thompson 4262788fa27SJeremy L Thompson @ref Backend 4272788fa27SJeremy L Thompson **/ 42823dbfd29SJeremy L Thompson int CeedQFunctionContextGetInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const int32_t **values) { 4296574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4302788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values)); 4312788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4322788fa27SJeremy L Thompson } 4332788fa27SJeremy L Thompson 4342788fa27SJeremy L Thompson /** 435ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding `int32` values, read-only 4362788fa27SJeremy L Thompson 437ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` 4382788fa27SJeremy L Thompson @param[in] field_label Label for field to restore 4392788fa27SJeremy L Thompson @param[out] values Pointer to context values 4402788fa27SJeremy L Thompson 4412788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4422788fa27SJeremy L Thompson 4432788fa27SJeremy L Thompson @ref Backend 4442788fa27SJeremy L Thompson **/ 44523dbfd29SJeremy L Thompson int CeedQFunctionContextRestoreInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const int32_t **values) { 4466574a04fSJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4472788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values)); 4482788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4492788fa27SJeremy L Thompson } 4502788fa27SJeremy L Thompson 4512788fa27SJeremy L Thompson /** 452ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field holding boolean values 4535b6ec284SJeremy L Thompson 454ca94c3ddSJeremy L Thompson @param[in,out] ctx `CeedQFunctionContext` 4555b6ec284SJeremy L Thompson @param[in] field_label Label for field to set 4565b6ec284SJeremy L Thompson @param[in] values Values to set 4575b6ec284SJeremy L Thompson 4585b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4595b6ec284SJeremy L Thompson 4605b6ec284SJeremy L Thompson @ref Backend 4615b6ec284SJeremy L Thompson **/ 4625b6ec284SJeremy L Thompson int CeedQFunctionContextSetBoolean(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, bool *values) { 4635b6ec284SJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4645b6ec284SJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, values)); 4655b6ec284SJeremy L Thompson return CEED_ERROR_SUCCESS; 4665b6ec284SJeremy L Thompson } 4675b6ec284SJeremy L Thompson 4685b6ec284SJeremy L Thompson /** 469ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding boolean values, read-only 4705b6ec284SJeremy L Thompson 471ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` 4725b6ec284SJeremy L Thompson @param[in] field_label Label for field to get 4735b6ec284SJeremy L Thompson @param[out] num_values Number of values in the field label 4745b6ec284SJeremy L Thompson @param[out] values Pointer to context values 4755b6ec284SJeremy L Thompson 4765b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4775b6ec284SJeremy L Thompson 4785b6ec284SJeremy L Thompson @ref Backend 4795b6ec284SJeremy L Thompson **/ 4805b6ec284SJeremy L Thompson int CeedQFunctionContextGetBooleanRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const bool **values) { 4815b6ec284SJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4825b6ec284SJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, num_values, values)); 4835b6ec284SJeremy L Thompson return CEED_ERROR_SUCCESS; 4845b6ec284SJeremy L Thompson } 4855b6ec284SJeremy L Thompson 4865b6ec284SJeremy L Thompson /** 487ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding boolean values, read-only 4885b6ec284SJeremy L Thompson 489ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` 4905b6ec284SJeremy L Thompson @param[in] field_label Label for field to restore 4915b6ec284SJeremy L Thompson @param[out] values Pointer to context values 4925b6ec284SJeremy L Thompson 4935b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4945b6ec284SJeremy L Thompson 4955b6ec284SJeremy L Thompson @ref Backend 4965b6ec284SJeremy L Thompson **/ 4975b6ec284SJeremy L Thompson int CeedQFunctionContextRestoreBooleanRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const bool **values) { 4985b6ec284SJeremy L Thompson CeedCheck(field_label, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4995b6ec284SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, values)); 5005b6ec284SJeremy L Thompson return CEED_ERROR_SUCCESS; 5015b6ec284SJeremy L Thompson } 5025b6ec284SJeremy L Thompson 5035b6ec284SJeremy L Thompson /** 504ca94c3ddSJeremy L Thompson @brief Get additional destroy routine for `CeedQFunctionContext` user data 5052e64a2b9SJeremy L Thompson 506ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` to get user destroy function 5072e64a2b9SJeremy L Thompson @param[out] f_mem_type Memory type to use when passing data into `f` 5082e64a2b9SJeremy L Thompson @param[out] f Additional routine to use to destroy user data 5092e64a2b9SJeremy L Thompson 5102e64a2b9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 5112e64a2b9SJeremy L Thompson 5122e64a2b9SJeremy L Thompson @ref Backend 5132e64a2b9SJeremy L Thompson **/ 5142b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx, CeedMemType *f_mem_type, CeedQFunctionContextDataDestroyUser *f) { 5152e64a2b9SJeremy L Thompson if (f_mem_type) *f_mem_type = ctx->data_destroy_mem_type; 5162e64a2b9SJeremy L Thompson if (f) *f = ctx->data_destroy_function; 5172e64a2b9SJeremy L Thompson return CEED_ERROR_SUCCESS; 5182e64a2b9SJeremy L Thompson } 5192e64a2b9SJeremy L Thompson 5202e64a2b9SJeremy L Thompson /** 521ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedQFunctionContext` 52234359f16Sjeremylt 523ca94c3ddSJeremy L Thompson @param[in,out] ctx `CeedQFunctionContext` to increment the reference counter 52434359f16Sjeremylt 52534359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 52634359f16Sjeremylt 52734359f16Sjeremylt @ref Backend 52834359f16Sjeremylt **/ 5299560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) { 53034359f16Sjeremylt ctx->ref_count++; 53134359f16Sjeremylt return CEED_ERROR_SUCCESS; 53234359f16Sjeremylt } 53334359f16Sjeremylt 534777ff853SJeremy L Thompson /// @} 535777ff853SJeremy L Thompson 536777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 537777ff853SJeremy L Thompson /// CeedQFunctionContext Public API 538777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 539777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser 540777ff853SJeremy L Thompson /// @{ 541777ff853SJeremy L Thompson 542777ff853SJeremy L Thompson /** 543ca94c3ddSJeremy L Thompson @brief Create a `CeedQFunctionContext` for storing `CeedQFunctionContext` user context data 544777ff853SJeremy L Thompson 545ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunctionContext` 546ca94c3ddSJeremy L Thompson @param[out] ctx Address of the variable where the newly created `CeedQFunctionContext` will be stored 547777ff853SJeremy L Thompson 548777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 549777ff853SJeremy L Thompson 550777ff853SJeremy L Thompson @ref User 551777ff853SJeremy L Thompson **/ 552777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) { 553777ff853SJeremy L Thompson if (!ceed->QFunctionContextCreate) { 554777ff853SJeremy L Thompson Ceed delegate; 5556574a04fSJeremy L Thompson 5562b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Context")); 557ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextCreate"); 5582b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextCreate(delegate, ctx)); 559e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 560777ff853SJeremy L Thompson } 561777ff853SJeremy L Thompson 5622b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, ctx)); 563db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*ctx)->ceed)); 564d1d35e2fSjeremylt (*ctx)->ref_count = 1; 5652b730f8bSJeremy L Thompson CeedCall(ceed->QFunctionContextCreate(*ctx)); 566e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 567777ff853SJeremy L Thompson } 568777ff853SJeremy L Thompson 569777ff853SJeremy L Thompson /** 570ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedQFunctionContext`. 5714385fb7fSSebastian Grimberg 572ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedQFunctionContextDestroy(). 573512bb800SJeremy L Thompson 574ca94c3ddSJeremy 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 `CeedQFunctionContext`. 575ca94c3ddSJeremy L Thompson This `CeedQFunctionContext` will be destroyed if `*ctx_copy` is the only reference to this `CeedQFunctionContext`. 5769560d06aSjeremylt 577ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to copy reference to 578ea61e9acSJeremy L Thompson @param[in,out] ctx_copy Variable to store copied reference 5799560d06aSjeremylt 5809560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 5819560d06aSjeremylt 5829560d06aSjeremylt @ref User 5839560d06aSjeremylt **/ 5842b730f8bSJeremy L Thompson int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, CeedQFunctionContext *ctx_copy) { 5852b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextReference(ctx)); 5862b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(ctx_copy)); 5879560d06aSjeremylt *ctx_copy = ctx; 5889560d06aSjeremylt return CEED_ERROR_SUCCESS; 5899560d06aSjeremylt } 5909560d06aSjeremylt 5919560d06aSjeremylt /** 592ca94c3ddSJeremy L Thompson @brief Set the data used by a `CeedQFunctionContext`, freeing any previously allocated data if applicable. 5934385fb7fSSebastian Grimberg 594ca94c3ddSJeremy L Thompson The backend may copy values to a different @ref CeedMemType, such as during @ref CeedQFunctionApply(). 595777ff853SJeremy L Thompson See also @ref CeedQFunctionContextTakeData(). 596777ff853SJeremy L Thompson 597ca94c3ddSJeremy L Thompson @param[in,out] ctx `CeedQFunctionContext` 598ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the data being passed 599ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the data 600ea61e9acSJeremy L Thompson @param[in] size Size of data, in bytes 601ea61e9acSJeremy L Thompson @param[in] data Data to be used 602777ff853SJeremy L Thompson 603777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 604777ff853SJeremy L Thompson 605777ff853SJeremy L Thompson @ref User 606777ff853SJeremy L Thompson **/ 6072b730f8bSJeremy L Thompson int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, size_t size, void *data) { 608ca94c3ddSJeremy L Thompson CeedCheck(ctx->SetData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextSetData"); 6096574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 610777ff853SJeremy L Thompson 6112b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroyData(ctx)); 612d1d35e2fSjeremylt ctx->ctx_size = size; 6132b730f8bSJeremy L Thompson CeedCall(ctx->SetData(ctx, mem_type, copy_mode, data)); 614777ff853SJeremy L Thompson ctx->state += 2; 615e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 616777ff853SJeremy L Thompson } 617777ff853SJeremy L Thompson 618777ff853SJeremy L Thompson /** 619ca94c3ddSJeremy L Thompson @brief Take ownership of the data in a `CeedQFunctionContext` via the specified memory type. 6204385fb7fSSebastian Grimberg 621891038deSjeremylt The caller is responsible for managing and freeing the memory. 622891038deSjeremylt 623ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` to access 624ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 625ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 626891038deSjeremylt @param[out] data Data on memory type mem_type 627891038deSjeremylt 628891038deSjeremylt @return An error code: 0 - success, otherwise - failure 629891038deSjeremylt 630891038deSjeremylt @ref User 631891038deSjeremylt **/ 6322b730f8bSJeremy L Thompson int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 6331c66c397SJeremy L Thompson void *temp_data = NULL; 6341c66c397SJeremy L Thompson bool has_valid_data = true, has_borrowed_data_of_type = true; 6351c66c397SJeremy L Thompson 6362b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 6376574a04fSJeremy L Thompson CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to take, must set data"); 6389c774eddSJeremy L Thompson 639ca94c3ddSJeremy L Thompson CeedCheck(ctx->TakeData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextTakeData"); 6406574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 641891038deSjeremylt 6422b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, &has_borrowed_data_of_type)); 6436574a04fSJeremy L Thompson CeedCheck(has_borrowed_data_of_type, ctx->ceed, CEED_ERROR_BACKEND, 6446574a04fSJeremy L Thompson "CeedQFunctionContext has no borrowed %s data, must set data with CeedQFunctionContextSetData", CeedMemTypes[mem_type]); 6459c774eddSJeremy L Thompson 6462b730f8bSJeremy L Thompson CeedCall(ctx->TakeData(ctx, mem_type, &temp_data)); 647891038deSjeremylt if (data) (*(void **)data) = temp_data; 648891038deSjeremylt return CEED_ERROR_SUCCESS; 649891038deSjeremylt } 650891038deSjeremylt 651891038deSjeremylt /** 652ca94c3ddSJeremy L Thompson @brief Get read/write access to a `CeedQFunctionContext` via the specified memory type. 6534385fb7fSSebastian Grimberg 654777ff853SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 655777ff853SJeremy L Thompson 656ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` to access 657ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 658ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 659d1d35e2fSjeremylt @param[out] data Data on memory type mem_type 660777ff853SJeremy L Thompson 661ca94c3ddSJeremy L Thompson @note The @ref CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions provide access to array pointers in the desired memory space. 662ca94c3ddSJeremy L Thompson Pairing get/restore allows the `CeedQFunctionContext` to track access. 663777ff853SJeremy L Thompson 664777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 665777ff853SJeremy L Thompson 666777ff853SJeremy L Thompson @ref User 667777ff853SJeremy L Thompson **/ 6682b730f8bSJeremy L Thompson int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 6691c66c397SJeremy L Thompson bool has_valid_data = true; 6701c66c397SJeremy L Thompson 671ca94c3ddSJeremy L Thompson CeedCheck(ctx->GetData, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextGetData"); 6726574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 6736574a04fSJeremy L Thompson CeedCheck(ctx->num_readers == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, a process has read access"); 67428bfd0b7SJeremy L Thompson 6752b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 6766574a04fSJeremy L Thompson CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data"); 6779c774eddSJeremy L Thompson 6782b730f8bSJeremy L Thompson CeedCall(ctx->GetData(ctx, mem_type, data)); 67928bfd0b7SJeremy L Thompson ctx->state++; 68028bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 68128bfd0b7SJeremy L Thompson } 68228bfd0b7SJeremy L Thompson 68328bfd0b7SJeremy L Thompson /** 684ca94c3ddSJeremy L Thompson @brief Get read only access to a `CeedQFunctionContext` via the specified memory type. 6854385fb7fSSebastian Grimberg 68628bfd0b7SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 68728bfd0b7SJeremy L Thompson 688ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` to access 689ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 690ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 69128bfd0b7SJeremy L Thompson @param[out] data Data on memory type mem_type 69228bfd0b7SJeremy L Thompson 693ca94c3ddSJeremy L Thompson @note The @ref CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead() functions provide access to array pointers in the desired memory space. 694ca94c3ddSJeremy L Thompson Pairing get/restore allows the `CeedQFunctionContext` to track access. 69528bfd0b7SJeremy L Thompson 69628bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 69728bfd0b7SJeremy L Thompson 69828bfd0b7SJeremy L Thompson @ref User 69928bfd0b7SJeremy L Thompson **/ 7002b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 7011c66c397SJeremy L Thompson bool has_valid_data = true; 7021c66c397SJeremy L Thompson 703ca94c3ddSJeremy L Thompson CeedCheck(ctx->GetDataRead, ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextGetDataRead"); 7046574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 0, ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 70528bfd0b7SJeremy L Thompson 7062b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 7076574a04fSJeremy L Thompson CeedCheck(has_valid_data, ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data"); 70828bfd0b7SJeremy L Thompson 7092b730f8bSJeremy L Thompson CeedCall(ctx->GetDataRead(ctx, mem_type, data)); 71028bfd0b7SJeremy L Thompson ctx->num_readers++; 711e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 712777ff853SJeremy L Thompson } 713777ff853SJeremy L Thompson 714777ff853SJeremy L Thompson /** 715777ff853SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetData() 716777ff853SJeremy L Thompson 717ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` to restore 718ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 719777ff853SJeremy L Thompson 720777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 721777ff853SJeremy L Thompson 722777ff853SJeremy L Thompson @ref User 723777ff853SJeremy L Thompson **/ 724777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) { 7256574a04fSJeremy L Thompson CeedCheck(ctx->state % 2 == 1, ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted"); 726777ff853SJeremy L Thompson 7276574a04fSJeremy L Thompson if (ctx->RestoreData) CeedCall(ctx->RestoreData(ctx)); 728777ff853SJeremy L Thompson *(void **)data = NULL; 72928bfd0b7SJeremy L Thompson ctx->state++; 73028bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 73128bfd0b7SJeremy L Thompson } 73228bfd0b7SJeremy L Thompson 73328bfd0b7SJeremy L Thompson /** 73428bfd0b7SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead() 73528bfd0b7SJeremy L Thompson 736ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` to restore 737ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 73828bfd0b7SJeremy L Thompson 73928bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 74028bfd0b7SJeremy L Thompson 74128bfd0b7SJeremy L Thompson @ref User 74228bfd0b7SJeremy L Thompson **/ 74328bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) { 7446574a04fSJeremy L Thompson CeedCheck(ctx->num_readers > 0, ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted"); 74528bfd0b7SJeremy L Thompson 74675a19770SJeremy L Thompson ctx->num_readers--; 7476574a04fSJeremy L Thompson if (ctx->num_readers == 0 && ctx->RestoreDataRead) CeedCall(ctx->RestoreDataRead(ctx)); 74828bfd0b7SJeremy L Thompson *(void **)data = NULL; 749e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 750777ff853SJeremy L Thompson } 751777ff853SJeremy L Thompson 752777ff853SJeremy L Thompson /** 753ca94c3ddSJeremy L Thompson @brief Register a `CeedQFunctionContext` field holding double precision values 754cdf32b93SJeremy L Thompson 755ca94c3ddSJeremy L Thompson @param[in,out] ctx `CeedQFunctionContext` 756ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 757ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 758ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 759ca94c3ddSJeremy L Thompson @param[in] field_description Description of field, or `NULL` for none 760cdf32b93SJeremy L Thompson 761cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 762cdf32b93SJeremy L Thompson 763cdf32b93SJeremy L Thompson @ref User 764cdf32b93SJeremy L Thompson **/ 7652b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 766cdf32b93SJeremy L Thompson const char *field_description) { 7675b6ec284SJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_DOUBLE, num_values); 768cdf32b93SJeremy L Thompson } 769cdf32b93SJeremy L Thompson 770cdf32b93SJeremy L Thompson /** 771ca94c3ddSJeremy L Thompson @brief Register a `CeedQFunctionContext` field holding `int32` values 772cdf32b93SJeremy L Thompson 773ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 774ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 775ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 776ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 777ca94c3ddSJeremy L Thompson @param[in] field_description Description of field, or `NULL` for none 778cdf32b93SJeremy L Thompson 779cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 780cdf32b93SJeremy L Thompson 781cdf32b93SJeremy L Thompson @ref User 782cdf32b93SJeremy L Thompson **/ 7832b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 784cdf32b93SJeremy L Thompson const char *field_description) { 7855b6ec284SJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_INT32, num_values); 7865b6ec284SJeremy L Thompson } 7875b6ec284SJeremy L Thompson 7885b6ec284SJeremy L Thompson /** 789ca94c3ddSJeremy L Thompson @brief Register a `CeedQFunctionContext` field holding boolean values 7905b6ec284SJeremy L Thompson 791ca94c3ddSJeremy L Thompson @param[in,out] ctx `CeedQFunctionContext` 7925b6ec284SJeremy L Thompson @param[in] field_name Name of field to register 7935b6ec284SJeremy L Thompson @param[in] field_offset Offset of field to register 7945b6ec284SJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 795ca94c3ddSJeremy L Thompson @param[in] field_description Description of field, or `NULL` for none 7965b6ec284SJeremy L Thompson 7975b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7985b6ec284SJeremy L Thompson 7995b6ec284SJeremy L Thompson @ref User 8005b6ec284SJeremy L Thompson **/ 8015b6ec284SJeremy L Thompson int CeedQFunctionContextRegisterBoolean(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 8025b6ec284SJeremy L Thompson const char *field_description) { 8035b6ec284SJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_BOOL, num_values); 804cdf32b93SJeremy L Thompson } 805cdf32b93SJeremy L Thompson 806cdf32b93SJeremy L Thompson /** 807ca94c3ddSJeremy L Thompson @brief Get labels for all registered `CeedQFunctionContext` fields 808cdf32b93SJeremy L Thompson 809ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` 8103668ca4bSJeremy L Thompson @param[out] field_labels Variable to hold array of field labels 811cdf32b93SJeremy L Thompson @param[out] num_fields Length of field descriptions array 812cdf32b93SJeremy L Thompson 813cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 814cdf32b93SJeremy L Thompson 815cdf32b93SJeremy L Thompson @ref User 816cdf32b93SJeremy L Thompson **/ 8172b730f8bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, const CeedContextFieldLabel **field_labels, CeedInt *num_fields) { 8183668ca4bSJeremy L Thompson *field_labels = ctx->field_labels; 819cdf32b93SJeremy L Thompson *num_fields = ctx->num_fields; 820cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 821cdf32b93SJeremy L Thompson } 822cdf32b93SJeremy L Thompson 823cdf32b93SJeremy L Thompson /** 824ca94c3ddSJeremy L Thompson @brief Get the descriptive information about a `CeedContextFieldLabel` 8250f86cbe7SJeremy L Thompson 826ca94c3ddSJeremy L Thompson @param[in] label @ref CeedContextFieldLabel 8270f86cbe7SJeremy L Thompson @param[out] field_name Name of labeled field 8281ff07f3dSJeremy L Thompson @param[out] field_offset Offset of field registered 8297bfe0f0eSJeremy L Thompson @param[out] num_values Number of values registered 8301ff07f3dSJeremy L Thompson @param[out] field_description Description of field, or NULL for none 831ca94c3ddSJeremy L Thompson @param[out] field_type @ref CeedContextFieldType 8320f86cbe7SJeremy L Thompson 8330f86cbe7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8340f86cbe7SJeremy L Thompson 8350f86cbe7SJeremy L Thompson @ref User 8360f86cbe7SJeremy L Thompson **/ 8371ff07f3dSJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, const char **field_name, size_t *field_offset, size_t *num_values, 8381ff07f3dSJeremy L Thompson const char **field_description, CeedContextFieldType *field_type) { 8390f86cbe7SJeremy L Thompson if (field_name) *field_name = label->name; 8401ff07f3dSJeremy L Thompson if (field_offset) *field_offset = label->offset; 8417bfe0f0eSJeremy L Thompson if (num_values) *num_values = label->num_values; 8421ff07f3dSJeremy L Thompson if (field_description) *field_description = label->description; 8430f86cbe7SJeremy L Thompson if (field_type) *field_type = label->type; 8440f86cbe7SJeremy L Thompson return CEED_ERROR_SUCCESS; 8450f86cbe7SJeremy L Thompson } 8460f86cbe7SJeremy L Thompson 8470f86cbe7SJeremy L Thompson /** 84880a9ef05SNatalie Beams @brief Get data size for a Context 84980a9ef05SNatalie Beams 850ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` 85180a9ef05SNatalie Beams @param[out] ctx_size Variable to store size of context data values 85280a9ef05SNatalie Beams 85380a9ef05SNatalie Beams @return An error code: 0 - success, otherwise - failure 85480a9ef05SNatalie Beams 85580a9ef05SNatalie Beams @ref User 85680a9ef05SNatalie Beams **/ 8572b730f8bSJeremy L Thompson int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, size_t *ctx_size) { 85880a9ef05SNatalie Beams *ctx_size = ctx->ctx_size; 85980a9ef05SNatalie Beams return CEED_ERROR_SUCCESS; 86080a9ef05SNatalie Beams } 86180a9ef05SNatalie Beams 86280a9ef05SNatalie Beams /** 863ca94c3ddSJeremy L Thompson @brief View a `CeedQFunctionContext` 864777ff853SJeremy L Thompson 865ca94c3ddSJeremy L Thompson @param[in] ctx `CeedQFunctionContext` to view 866777ff853SJeremy L Thompson @param[in] stream Filestream to write to 867777ff853SJeremy L Thompson 868777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 869777ff853SJeremy L Thompson 870777ff853SJeremy L Thompson @ref User 871777ff853SJeremy L Thompson **/ 872777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) { 873777ff853SJeremy L Thompson fprintf(stream, "CeedQFunctionContext\n"); 874*249f8407SJeremy L Thompson fprintf(stream, " Context Data Size: %zu\n", ctx->ctx_size); 8753668ca4bSJeremy L Thompson for (CeedInt i = 0; i < ctx->num_fields; i++) { 8762b730f8bSJeremy L Thompson fprintf(stream, " Labeled %s field: %s\n", CeedContextFieldTypes[ctx->field_labels[i]->type], ctx->field_labels[i]->name); 8773668ca4bSJeremy L Thompson } 878e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 879777ff853SJeremy L Thompson } 880777ff853SJeremy L Thompson 881777ff853SJeremy L Thompson /** 882ca94c3ddSJeremy L Thompson @brief Set additional destroy routine for `CeedQFunctionContext` user data 8832790b72bSJeremy L Thompson 884ca94c3ddSJeremy L Thompson @param[in,out] ctx `CeedQFunctionContext` to set user destroy function 8852e64a2b9SJeremy L Thompson @param[in] f_mem_type Memory type to use when passing data into `f` 8862e64a2b9SJeremy L Thompson @param[in] f Additional routine to use to destroy user data 8872790b72bSJeremy L Thompson 8882790b72bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8892790b72bSJeremy L Thompson 8902790b72bSJeremy L Thompson @ref User 8912790b72bSJeremy L Thompson **/ 8922b730f8bSJeremy L Thompson int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) { 8936574a04fSJeremy L Thompson CeedCheck(f, ctx->ceed, 1, "Must provide valid callback function for destroying user data"); 8942790b72bSJeremy L Thompson ctx->data_destroy_mem_type = f_mem_type; 8952790b72bSJeremy L Thompson ctx->data_destroy_function = f; 8962790b72bSJeremy L Thompson return CEED_ERROR_SUCCESS; 8972790b72bSJeremy L Thompson } 8982790b72bSJeremy L Thompson 8992790b72bSJeremy L Thompson /** 900ca94c3ddSJeremy L Thompson @brief Destroy a `CeedQFunctionContext` 901777ff853SJeremy L Thompson 902ca94c3ddSJeremy L Thompson @param[in,out] ctx `CeedQFunctionContext` to destroy 903777ff853SJeremy L Thompson 904777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 905777ff853SJeremy L Thompson 906777ff853SJeremy L Thompson @ref User 907777ff853SJeremy L Thompson **/ 908777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) { 909ad6481ceSJeremy L Thompson if (!*ctx || --(*ctx)->ref_count > 0) { 910ad6481ceSJeremy L Thompson *ctx = NULL; 911ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 912ad6481ceSJeremy L Thompson } 9136574a04fSJeremy L Thompson CeedCheck(((*ctx)->state % 2) == 0, (*ctx)->ceed, 1, "Cannot destroy CeedQFunctionContext, the access lock is in use"); 914777ff853SJeremy L Thompson 9152b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroyData(*ctx)); 9162b730f8bSJeremy L Thompson if ((*ctx)->Destroy) CeedCall((*ctx)->Destroy(*ctx)); 917cdf32b93SJeremy L Thompson for (CeedInt i = 0; i < (*ctx)->num_fields; i++) { 9182b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i]->name)); 9192b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i]->description)); 9202b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i])); 921cdf32b93SJeremy L Thompson } 9222b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels)); 9232b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*ctx)->ceed)); 9242b730f8bSJeremy L Thompson CeedCall(CeedFree(ctx)); 925e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 926777ff853SJeremy L Thompson } 927777ff853SJeremy L Thompson 928777ff853SJeremy L Thompson /// @} 929