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 8ec3da8bcSJed Brown #include <ceed/ceed.h> 9ec3da8bcSJed Brown #include <ceed/backend.h> 103d576824SJeremy L Thompson #include <ceed-impl.h> 113d576824SJeremy L Thompson #include <stdint.h> 123d576824SJeremy L Thompson #include <stdio.h> 13cdf32b93SJeremy L Thompson #include <string.h> 14777ff853SJeremy L Thompson 15777ff853SJeremy L Thompson /// @file 16777ff853SJeremy L Thompson /// Implementation of public CeedQFunctionContext interfaces 17777ff853SJeremy L Thompson 18777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 19cdf32b93SJeremy L Thompson /// CeedQFunctionContext Library Internal Functions 20cdf32b93SJeremy L Thompson /// ---------------------------------------------------------------------------- 21cdf32b93SJeremy L Thompson /// @addtogroup CeedQFunctionDeveloper 22cdf32b93SJeremy L Thompson /// @{ 23cdf32b93SJeremy L Thompson 24cdf32b93SJeremy L Thompson /** 25cdf32b93SJeremy L Thompson @brief Get index for QFunctionContext field 26cdf32b93SJeremy L Thompson 27cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 28cdf32b93SJeremy L Thompson @param field_name Name of field 29cdf32b93SJeremy L Thompson @param field_index Index of field, or -1 if field is not registered 30cdf32b93SJeremy L Thompson 31cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 32cdf32b93SJeremy L Thompson 33cdf32b93SJeremy L Thompson @ref Developer 34cdf32b93SJeremy L Thompson **/ 35cdf32b93SJeremy L Thompson int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx, 36cdf32b93SJeremy L Thompson const char *field_name, CeedInt *field_index) { 37cdf32b93SJeremy L Thompson *field_index = -1; 38cdf32b93SJeremy L Thompson for (CeedInt i=0; i<ctx->num_fields; i++) 393668ca4bSJeremy L Thompson if (!strcmp(ctx->field_labels[i]->name, field_name)) 40cdf32b93SJeremy L Thompson *field_index = i; 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 47cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 48cdf32b93SJeremy L Thompson @param field_name Name of field to register 49cdf32b93SJeremy L Thompson @param field_offset Offset of field to register 50cdf32b93SJeremy L Thompson @param field_description Description of field, or NULL for none 51cdf32b93SJeremy L Thompson @param field_type Field data type, such as double or int32 52cdf32b93SJeremy L Thompson @param field_size Size of field, in bytes 537bfe0f0eSJeremy L Thompson @param 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 **/ 59cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx, 60cdf32b93SJeremy L Thompson const char *field_name, size_t field_offset, 61cdf32b93SJeremy L Thompson const char *field_description, 62cdf32b93SJeremy L Thompson CeedContextFieldType field_type, 637bfe0f0eSJeremy L Thompson size_t field_size, size_t num_values) { 64cdf32b93SJeremy L Thompson int ierr; 65cdf32b93SJeremy L Thompson 66cdf32b93SJeremy L Thompson // Check for duplicate 67cdf32b93SJeremy L Thompson CeedInt field_index = -1; 68cdf32b93SJeremy L Thompson ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index); 69cdf32b93SJeremy L Thompson CeedChk(ierr); 70cdf32b93SJeremy L Thompson if (field_index != -1) 71cdf32b93SJeremy L Thompson // LCOV_EXCL_START 72cdf32b93SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 73cdf32b93SJeremy L Thompson "QFunctionContext field with name \"%s\" already registered", 74cdf32b93SJeremy L Thompson field_name); 75cdf32b93SJeremy L Thompson // LCOV_EXCL_STOP 76cdf32b93SJeremy L Thompson 77cdf32b93SJeremy L Thompson // Allocate space for field data 78cdf32b93SJeremy L Thompson if (ctx->num_fields == 0) { 793668ca4bSJeremy L Thompson ierr = CeedCalloc(1, &ctx->field_labels); CeedChk(ierr); 80cdf32b93SJeremy L Thompson ctx->max_fields = 1; 81cdf32b93SJeremy L Thompson } else if (ctx->num_fields == ctx->max_fields) { 823668ca4bSJeremy L Thompson ierr = CeedRealloc(2*ctx->max_fields, &ctx->field_labels); 83cdf32b93SJeremy L Thompson CeedChk(ierr); 84cdf32b93SJeremy L Thompson ctx->max_fields *= 2; 85cdf32b93SJeremy L Thompson } 863668ca4bSJeremy L Thompson ierr = CeedCalloc(1, &ctx->field_labels[ctx->num_fields]); CeedChk(ierr); 87cdf32b93SJeremy L Thompson 88cdf32b93SJeremy L Thompson // Copy field data 89f7e22acaSJeremy L Thompson ierr = CeedStringAllocCopy(field_name, 903668ca4bSJeremy L Thompson (char **)&ctx->field_labels[ctx->num_fields]->name); 91f7e22acaSJeremy L Thompson CeedChk(ierr); 92f7e22acaSJeremy L Thompson ierr = CeedStringAllocCopy(field_description, 933668ca4bSJeremy L Thompson (char **)&ctx->field_labels[ctx->num_fields]->description); 94f7e22acaSJeremy L Thompson CeedChk(ierr); 953668ca4bSJeremy L Thompson ctx->field_labels[ctx->num_fields]->type = field_type; 963668ca4bSJeremy L Thompson ctx->field_labels[ctx->num_fields]->offset = field_offset; 977bfe0f0eSJeremy L Thompson ctx->field_labels[ctx->num_fields]->size = field_size * num_values; 987bfe0f0eSJeremy L Thompson ctx->field_labels[ctx->num_fields]->num_values = num_values; 99cdf32b93SJeremy L Thompson ctx->num_fields++; 100cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 101cdf32b93SJeremy L Thompson } 102cdf32b93SJeremy L Thompson 103cdf32b93SJeremy L Thompson /// @} 104cdf32b93SJeremy L Thompson 105cdf32b93SJeremy L Thompson /// ---------------------------------------------------------------------------- 106777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API 107777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 108777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend 109777ff853SJeremy L Thompson /// @{ 110777ff853SJeremy L Thompson 111777ff853SJeremy L Thompson /** 112777ff853SJeremy L Thompson @brief Get the Ceed associated with a CeedQFunctionContext 113777ff853SJeremy L Thompson 114777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 115777ff853SJeremy L Thompson @param[out] ceed Variable to store Ceed 116777ff853SJeremy L Thompson 117777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 118777ff853SJeremy L Thompson 119777ff853SJeremy L Thompson @ref Backend 120777ff853SJeremy L Thompson **/ 121777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) { 122777ff853SJeremy L Thompson *ceed = ctx->ceed; 123e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 124777ff853SJeremy L Thompson } 125777ff853SJeremy L Thompson 126777ff853SJeremy L Thompson /** 1279c774eddSJeremy L Thompson @brief Check for valid data in a CeedQFunctionContext 1289c774eddSJeremy L Thompson 1299c774eddSJeremy L Thompson @param ctx CeedQFunctionContext to check validity 1309c774eddSJeremy L Thompson @param[out] has_valid_data Variable to store validity 1319c774eddSJeremy L Thompson 1329c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1339c774eddSJeremy L Thompson 1349c774eddSJeremy L Thompson @ref Backend 1359c774eddSJeremy L Thompson **/ 1369c774eddSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx, 1379c774eddSJeremy L Thompson bool *has_valid_data) { 1389c774eddSJeremy L Thompson int ierr; 1399c774eddSJeremy L Thompson 1409c774eddSJeremy L Thompson if (!ctx->HasValidData) 1419c774eddSJeremy L Thompson // LCOV_EXCL_START 1429c774eddSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 1439c774eddSJeremy L Thompson "Backend does not support HasValidData"); 1449c774eddSJeremy L Thompson // LCOV_EXCL_STOP 1459c774eddSJeremy L Thompson 1469c774eddSJeremy L Thompson ierr = ctx->HasValidData(ctx, has_valid_data); CeedChk(ierr); 1479c774eddSJeremy L Thompson 1489c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 1499c774eddSJeremy L Thompson } 1509c774eddSJeremy L Thompson 1519c774eddSJeremy L Thompson /** 1529c774eddSJeremy L Thompson @brief Check for borrowed data of a specific CeedMemType in a 1539c774eddSJeremy L Thompson CeedQFunctionContext 1549c774eddSJeremy L Thompson 1559c774eddSJeremy L Thompson @param ctx CeedQFunctionContext to check 1569c774eddSJeremy L Thompson @param mem_type Memory type to check 1579c774eddSJeremy L Thompson @param[out] has_borrowed_data_of_type Variable to store result 1589c774eddSJeremy L Thompson 1599c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1609c774eddSJeremy L Thompson 1619c774eddSJeremy L Thompson @ref Backend 1629c774eddSJeremy L Thompson **/ 1639c774eddSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx, 1649c774eddSJeremy L Thompson CeedMemType mem_type, bool *has_borrowed_data_of_type) { 1659c774eddSJeremy L Thompson int ierr; 1669c774eddSJeremy L Thompson 1679c774eddSJeremy L Thompson if (!ctx->HasBorrowedDataOfType) 1689c774eddSJeremy L Thompson // LCOV_EXCL_START 1699c774eddSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 1709c774eddSJeremy L Thompson "Backend does not support HasBorrowedDataOfType"); 1719c774eddSJeremy L Thompson // LCOV_EXCL_STOP 1729c774eddSJeremy L Thompson 1739c774eddSJeremy L Thompson ierr = ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type); 1749c774eddSJeremy L Thompson CeedChk(ierr); 1759c774eddSJeremy L Thompson 1769c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 1779c774eddSJeremy L Thompson } 1789c774eddSJeremy L Thompson 1799c774eddSJeremy L Thompson /** 180777ff853SJeremy L Thompson @brief Get the state of a CeedQFunctionContext 181777ff853SJeremy L Thompson 182777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to retrieve state 183777ff853SJeremy L Thompson @param[out] state Variable to store state 184777ff853SJeremy L Thompson 185777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 186777ff853SJeremy L Thompson 187777ff853SJeremy L Thompson @ref Backend 188777ff853SJeremy L Thompson **/ 189777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) { 190777ff853SJeremy L Thompson *state = ctx->state; 191e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 192777ff853SJeremy L Thompson } 193777ff853SJeremy L Thompson 194777ff853SJeremy L Thompson /** 195777ff853SJeremy L Thompson @brief Get backend data of a CeedQFunctionContext 196777ff853SJeremy L Thompson 197777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 198777ff853SJeremy L Thompson @param[out] data Variable to store data 199777ff853SJeremy L Thompson 200777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 201777ff853SJeremy L Thompson 202777ff853SJeremy L Thompson @ref Backend 203777ff853SJeremy L Thompson **/ 204777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) { 205777ff853SJeremy L Thompson *(void **)data = ctx->data; 206e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 207777ff853SJeremy L Thompson } 208777ff853SJeremy L Thompson 209777ff853SJeremy L Thompson /** 210777ff853SJeremy L Thompson @brief Set backend data of a CeedQFunctionContext 211777ff853SJeremy L Thompson 212777ff853SJeremy L Thompson @param[out] ctx CeedQFunctionContext 213777ff853SJeremy L Thompson @param data Data to set 214777ff853SJeremy L Thompson 215777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 216777ff853SJeremy L Thompson 217777ff853SJeremy L Thompson @ref Backend 218777ff853SJeremy L Thompson **/ 219777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) { 220777ff853SJeremy L Thompson ctx->data = data; 221e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 222777ff853SJeremy L Thompson } 223777ff853SJeremy L Thompson 22434359f16Sjeremylt /** 225e6a0ab89SJeremy L Thompson @brief Get label for a registered QFunctionContext field, or `NULL` if no 226e6a0ab89SJeremy L Thompson field has been registered with this `field_name` 227e6a0ab89SJeremy L Thompson 228e6a0ab89SJeremy L Thompson @param[in] ctx CeedQFunctionContext 229e6a0ab89SJeremy L Thompson @param[in] field_name Name of field to retrieve label 230e6a0ab89SJeremy L Thompson @param[out] field_label Variable to field label 231e6a0ab89SJeremy L Thompson 232e6a0ab89SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 233e6a0ab89SJeremy L Thompson 2343e1e85abSJeremy L Thompson @ref Backend 235e6a0ab89SJeremy L Thompson **/ 236e6a0ab89SJeremy L Thompson int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx, 237e6a0ab89SJeremy L Thompson const char *field_name, 238e6a0ab89SJeremy L Thompson CeedContextFieldLabel *field_label) { 239e6a0ab89SJeremy L Thompson int ierr; 240e6a0ab89SJeremy L Thompson 241e6a0ab89SJeremy L Thompson CeedInt field_index; 242e6a0ab89SJeremy L Thompson ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index); 243e6a0ab89SJeremy L Thompson CeedChk(ierr); 244e6a0ab89SJeremy L Thompson 245e6a0ab89SJeremy L Thompson if (field_index != -1) { 246e6a0ab89SJeremy L Thompson *field_label = ctx->field_labels[field_index]; 247e6a0ab89SJeremy L Thompson } else { 248e6a0ab89SJeremy L Thompson *field_label = NULL; 249e6a0ab89SJeremy L Thompson } 250e6a0ab89SJeremy L Thompson 251e6a0ab89SJeremy L Thompson return CEED_ERROR_SUCCESS; 252e6a0ab89SJeremy L Thompson } 253e6a0ab89SJeremy L Thompson 254e6a0ab89SJeremy L Thompson /** 255d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field 256d8dd9a91SJeremy L Thompson 257d8dd9a91SJeremy L Thompson @param ctx CeedQFunctionContext 2583668ca4bSJeremy L Thompson @param field_label Label of field to set 259d8dd9a91SJeremy L Thompson @param field_type Type of field to set 260d8dd9a91SJeremy L Thompson @param value 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 **/ 266d8dd9a91SJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx, 2673668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, 268d8dd9a91SJeremy L Thompson CeedContextFieldType field_type, 2693668ca4bSJeremy L Thompson void *value) { 270d8dd9a91SJeremy L Thompson int ierr; 271d8dd9a91SJeremy L Thompson 2723668ca4bSJeremy L Thompson // Check field type 2733668ca4bSJeremy L Thompson if (field_label->type != field_type) 274d8dd9a91SJeremy L Thompson // LCOV_EXCL_START 275d8dd9a91SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 276d8dd9a91SJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, " 2773668ca4bSJeremy L Thompson "not registered as %s", field_label->name, 2783668ca4bSJeremy L Thompson CeedContextFieldTypes[field_label->type], 279d8dd9a91SJeremy L Thompson CeedContextFieldTypes[field_type]); 280d8dd9a91SJeremy L Thompson // LCOV_EXCL_STOP 281d8dd9a91SJeremy L Thompson 282d8dd9a91SJeremy L Thompson char *data; 283d8dd9a91SJeremy L Thompson ierr = CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data); CeedChk(ierr); 2843668ca4bSJeremy L Thompson memcpy(&data[field_label->offset], value, field_label->size); 285d8dd9a91SJeremy L Thompson ierr = CeedQFunctionContextRestoreData(ctx, &data); CeedChk(ierr); 286d8dd9a91SJeremy L Thompson 287d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 288d8dd9a91SJeremy L Thompson } 289d8dd9a91SJeremy L Thompson 290d8dd9a91SJeremy L Thompson /** 291bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value 292bfacc300SJeremy L Thompson 293bfacc300SJeremy L Thompson @param ctx CeedQFunctionContext 294bfacc300SJeremy L Thompson @param field_label Label for field to register 295bfacc300SJeremy L Thompson @param values Values to set 296bfacc300SJeremy L Thompson 297bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 298bfacc300SJeremy L Thompson 2993e1e85abSJeremy L Thompson @ref Backend 300bfacc300SJeremy L Thompson **/ 301bfacc300SJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, 302bfacc300SJeremy L Thompson CeedContextFieldLabel field_label, double *values) { 303bfacc300SJeremy L Thompson int ierr; 304bfacc300SJeremy L Thompson 305bfacc300SJeremy L Thompson if (!field_label) 306bfacc300SJeremy L Thompson // LCOV_EXCL_START 307bfacc300SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 308bfacc300SJeremy L Thompson "Invalid field label"); 309bfacc300SJeremy L Thompson // LCOV_EXCL_STOP 310bfacc300SJeremy L Thompson 311bfacc300SJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(ctx, field_label, 312bfacc300SJeremy L Thompson CEED_CONTEXT_FIELD_DOUBLE, 313bfacc300SJeremy L Thompson values); CeedChk(ierr); 314bfacc300SJeremy L Thompson 315bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 316bfacc300SJeremy L Thompson } 317bfacc300SJeremy L Thompson 318bfacc300SJeremy L Thompson /** 319bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding an int32 value 320bfacc300SJeremy L Thompson 321bfacc300SJeremy L Thompson @param ctx CeedQFunctionContext 322bfacc300SJeremy L Thompson @param field_label Label for field to register 323bfacc300SJeremy L Thompson @param values Values to set 324bfacc300SJeremy L Thompson 325bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 326bfacc300SJeremy L Thompson 3273e1e85abSJeremy L Thompson @ref Backend 328bfacc300SJeremy L Thompson **/ 329bfacc300SJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, 330bfacc300SJeremy L Thompson CeedContextFieldLabel field_label, int *values) { 331bfacc300SJeremy L Thompson int ierr; 332bfacc300SJeremy L Thompson 333bfacc300SJeremy L Thompson if (!field_label) 334bfacc300SJeremy L Thompson // LCOV_EXCL_START 335bfacc300SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 336bfacc300SJeremy L Thompson "Invalid field label"); 337bfacc300SJeremy L Thompson // LCOV_EXCL_STOP 338bfacc300SJeremy L Thompson 339bfacc300SJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(ctx, field_label, 340bfacc300SJeremy L Thompson CEED_CONTEXT_FIELD_INT32, 341bfacc300SJeremy L Thompson values); CeedChk(ierr); 342bfacc300SJeremy L Thompson 343bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 344bfacc300SJeremy L Thompson } 345bfacc300SJeremy L Thompson 346bfacc300SJeremy L Thompson /** 347*2e64a2b9SJeremy L Thompson @brief Get additional destroy routine for CeedQFunctionContext user data 348*2e64a2b9SJeremy L Thompson 349*2e64a2b9SJeremy L Thompson @param[in] ctx CeedQFunctionContext to get user destroy function 350*2e64a2b9SJeremy L Thompson @param[out] f_mem_type Memory type to use when passing data into `f` 351*2e64a2b9SJeremy L Thompson @param[out] f Additional routine to use to destroy user data 352*2e64a2b9SJeremy L Thompson 353*2e64a2b9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 354*2e64a2b9SJeremy L Thompson 355*2e64a2b9SJeremy L Thompson @ref Backend 356*2e64a2b9SJeremy L Thompson **/ 357*2e64a2b9SJeremy L Thompson int CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx, 358*2e64a2b9SJeremy L Thompson CeedMemType *f_mem_type, CeedQFunctionContextDataDestroyUser *f) { 359*2e64a2b9SJeremy L Thompson if (f_mem_type) *f_mem_type = ctx->data_destroy_mem_type; 360*2e64a2b9SJeremy L Thompson if (f) *f = ctx->data_destroy_function; 361*2e64a2b9SJeremy L Thompson return CEED_ERROR_SUCCESS; 362*2e64a2b9SJeremy L Thompson } 363*2e64a2b9SJeremy L Thompson 364*2e64a2b9SJeremy L Thompson /** 365*2e64a2b9SJeremy L Thompson @brief Destroy user data held by CeedQFunctionContext, using function set by 366*2e64a2b9SJeremy L Thompson CeedQFunctionContextSetDataDestroy, if applicable 367*2e64a2b9SJeremy L Thompson 368*2e64a2b9SJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to destroy user data 369*2e64a2b9SJeremy L Thompson 370*2e64a2b9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 371*2e64a2b9SJeremy L Thompson 372*2e64a2b9SJeremy L Thompson @ref Backend 373*2e64a2b9SJeremy L Thompson **/ 374*2e64a2b9SJeremy L Thompson int CeedQFunctionContextDestroyData(CeedQFunctionContext ctx) { 375*2e64a2b9SJeremy L Thompson int ierr; 376*2e64a2b9SJeremy L Thompson 377*2e64a2b9SJeremy L Thompson if (ctx->DataDestroy) { 378*2e64a2b9SJeremy L Thompson ierr = ctx->DataDestroy(ctx); CeedChk(ierr); 379*2e64a2b9SJeremy L Thompson } else { 380*2e64a2b9SJeremy L Thompson CeedQFunctionContextDataDestroyUser data_destroy_function; 381*2e64a2b9SJeremy L Thompson CeedMemType data_destroy_mem_type; 382*2e64a2b9SJeremy L Thompson 383*2e64a2b9SJeremy L Thompson ierr = CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, 384*2e64a2b9SJeremy L Thompson &data_destroy_function); CeedChk(ierr); 385*2e64a2b9SJeremy L Thompson if (data_destroy_function) { 386*2e64a2b9SJeremy L Thompson void *data; 387*2e64a2b9SJeremy L Thompson 388*2e64a2b9SJeremy L Thompson ierr = CeedQFunctionContextGetData(ctx, data_destroy_mem_type, &data); 389*2e64a2b9SJeremy L Thompson CeedChk(ierr); 390*2e64a2b9SJeremy L Thompson ierr = data_destroy_function(data); CeedChk(ierr); 391*2e64a2b9SJeremy L Thompson ierr = CeedQFunctionContextRestoreData(ctx, &data); CeedChk(ierr); 392*2e64a2b9SJeremy L Thompson } 393*2e64a2b9SJeremy L Thompson } 394*2e64a2b9SJeremy L Thompson 395*2e64a2b9SJeremy L Thompson return CEED_ERROR_SUCCESS; 396*2e64a2b9SJeremy L Thompson } 397*2e64a2b9SJeremy L Thompson 398*2e64a2b9SJeremy L Thompson /** 39934359f16Sjeremylt @brief Increment the reference counter for a CeedQFunctionContext 40034359f16Sjeremylt 40134359f16Sjeremylt @param ctx CeedQFunctionContext to increment the reference counter 40234359f16Sjeremylt 40334359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 40434359f16Sjeremylt 40534359f16Sjeremylt @ref Backend 40634359f16Sjeremylt **/ 4079560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) { 40834359f16Sjeremylt ctx->ref_count++; 40934359f16Sjeremylt return CEED_ERROR_SUCCESS; 41034359f16Sjeremylt } 41134359f16Sjeremylt 412777ff853SJeremy L Thompson /// @} 413777ff853SJeremy L Thompson 414777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 415777ff853SJeremy L Thompson /// CeedQFunctionContext Public API 416777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 417777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser 418777ff853SJeremy L Thompson /// @{ 419777ff853SJeremy L Thompson 420777ff853SJeremy L Thompson /** 421777ff853SJeremy L Thompson @brief Create a CeedQFunctionContext for storing CeedQFunction user context data 422777ff853SJeremy L Thompson 423777ff853SJeremy L Thompson @param ceed A Ceed object where the CeedQFunctionContext will be created 424777ff853SJeremy L Thompson @param[out] ctx Address of the variable where the newly created 425777ff853SJeremy L Thompson CeedQFunctionContext will be stored 426777ff853SJeremy L Thompson 427777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 428777ff853SJeremy L Thompson 429777ff853SJeremy L Thompson @ref User 430777ff853SJeremy L Thompson **/ 431777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) { 432777ff853SJeremy L Thompson int ierr; 433777ff853SJeremy L Thompson 434777ff853SJeremy L Thompson if (!ceed->QFunctionContextCreate) { 435777ff853SJeremy L Thompson Ceed delegate; 436777ff853SJeremy L Thompson ierr = CeedGetObjectDelegate(ceed, &delegate, "Context"); CeedChk(ierr); 437777ff853SJeremy L Thompson 438777ff853SJeremy L Thompson if (!delegate) 439777ff853SJeremy L Thompson // LCOV_EXCL_START 440e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 441e15f9bd0SJeremy L Thompson "Backend does not support ContextCreate"); 442777ff853SJeremy L Thompson // LCOV_EXCL_STOP 443777ff853SJeremy L Thompson 444777ff853SJeremy L Thompson ierr = CeedQFunctionContextCreate(delegate, ctx); CeedChk(ierr); 445e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 446777ff853SJeremy L Thompson } 447777ff853SJeremy L Thompson 448777ff853SJeremy L Thompson ierr = CeedCalloc(1, ctx); CeedChk(ierr); 449777ff853SJeremy L Thompson (*ctx)->ceed = ceed; 4509560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 451d1d35e2fSjeremylt (*ctx)->ref_count = 1; 452777ff853SJeremy L Thompson ierr = ceed->QFunctionContextCreate(*ctx); CeedChk(ierr); 453e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 454777ff853SJeremy L Thompson } 455777ff853SJeremy L Thompson 456777ff853SJeremy L Thompson /** 4579560d06aSjeremylt @brief Copy the pointer to a CeedQFunctionContext. Both pointers should 4589560d06aSjeremylt be destroyed with `CeedQFunctionContextDestroy()`; 4599560d06aSjeremylt Note: If `*ctx_copy` is non-NULL, then it is assumed that 4609560d06aSjeremylt `*ctx_copy` is a pointer to a CeedQFunctionContext. This 4619560d06aSjeremylt CeedQFunctionContext will be destroyed if `*ctx_copy` is the 4629560d06aSjeremylt only reference to this CeedQFunctionContext. 4639560d06aSjeremylt 4649560d06aSjeremylt @param ctx CeedQFunctionContext to copy reference to 4659560d06aSjeremylt @param[out] ctx_copy Variable to store copied reference 4669560d06aSjeremylt 4679560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 4689560d06aSjeremylt 4699560d06aSjeremylt @ref User 4709560d06aSjeremylt **/ 4719560d06aSjeremylt int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, 4729560d06aSjeremylt CeedQFunctionContext *ctx_copy) { 4739560d06aSjeremylt int ierr; 4749560d06aSjeremylt 4759560d06aSjeremylt ierr = CeedQFunctionContextReference(ctx); CeedChk(ierr); 4769560d06aSjeremylt ierr = CeedQFunctionContextDestroy(ctx_copy); CeedChk(ierr); 4779560d06aSjeremylt *ctx_copy = ctx; 4789560d06aSjeremylt return CEED_ERROR_SUCCESS; 4799560d06aSjeremylt } 4809560d06aSjeremylt 4819560d06aSjeremylt /** 482777ff853SJeremy L Thompson @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated 483777ff853SJeremy L Thompson data if applicable. The backend may copy values to a different 484777ff853SJeremy L Thompson memtype, such as during @ref CeedQFunctionApply(). 485777ff853SJeremy L Thompson See also @ref CeedQFunctionContextTakeData(). 486777ff853SJeremy L Thompson 487777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 488d1d35e2fSjeremylt @param mem_type Memory type of the data being passed 489d1d35e2fSjeremylt @param copy_mode Copy mode for the data 490891038deSjeremylt @param size Size of data, in bytes 491777ff853SJeremy L Thompson @param data Data to be used 492777ff853SJeremy L Thompson 493777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 494777ff853SJeremy L Thompson 495777ff853SJeremy L Thompson @ref User 496777ff853SJeremy L Thompson **/ 497d1d35e2fSjeremylt int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, 498d1d35e2fSjeremylt CeedCopyMode copy_mode, 499777ff853SJeremy L Thompson size_t size, void *data) { 500777ff853SJeremy L Thompson int ierr; 501777ff853SJeremy L Thompson 502777ff853SJeremy L Thompson if (!ctx->SetData) 503777ff853SJeremy L Thompson // LCOV_EXCL_START 504e15f9bd0SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 505e15f9bd0SJeremy L Thompson "Backend does not support ContextSetData"); 506777ff853SJeremy L Thompson // LCOV_EXCL_STOP 507777ff853SJeremy L Thompson 508777ff853SJeremy L Thompson if (ctx->state % 2 == 1) 509777ff853SJeremy L Thompson // LCOV_EXCL_START 510777ff853SJeremy L Thompson return CeedError(ctx->ceed, 1, 511777ff853SJeremy L Thompson "Cannot grant CeedQFunctionContext data access, the " 512777ff853SJeremy L Thompson "access lock is already in use"); 513777ff853SJeremy L Thompson // LCOV_EXCL_STOP 514777ff853SJeremy L Thompson 515*2e64a2b9SJeremy L Thompson ierr = CeedQFunctionContextDestroyData(ctx); CeedChk(ierr); 516d1d35e2fSjeremylt ctx->ctx_size = size; 517d1d35e2fSjeremylt ierr = ctx->SetData(ctx, mem_type, copy_mode, data); CeedChk(ierr); 518777ff853SJeremy L Thompson ctx->state += 2; 519e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 520777ff853SJeremy L Thompson } 521777ff853SJeremy L Thompson 522777ff853SJeremy L Thompson /** 523891038deSjeremylt @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type. 524891038deSjeremylt The caller is responsible for managing and freeing the memory. 525891038deSjeremylt 526891038deSjeremylt @param ctx CeedQFunctionContext to access 527891038deSjeremylt @param mem_type Memory type on which to access the data. If the backend 528891038deSjeremylt uses a different memory type, this will perform a copy. 529891038deSjeremylt @param[out] data Data on memory type mem_type 530891038deSjeremylt 531891038deSjeremylt @return An error code: 0 - success, otherwise - failure 532891038deSjeremylt 533891038deSjeremylt @ref User 534891038deSjeremylt **/ 535891038deSjeremylt int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, 536891038deSjeremylt void *data) { 537891038deSjeremylt int ierr; 538891038deSjeremylt 5399c774eddSJeremy L Thompson bool has_valid_data = true; 5409c774eddSJeremy L Thompson ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr); 5419c774eddSJeremy L Thompson if (!has_valid_data) 5429c774eddSJeremy L Thompson // LCOV_EXCL_START 5439c774eddSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, 5449c774eddSJeremy L Thompson "CeedQFunctionContext has no valid data to take, must set data"); 5459c774eddSJeremy L Thompson // LCOV_EXCL_STOP 5469c774eddSJeremy L Thompson 547891038deSjeremylt if (!ctx->TakeData) 548891038deSjeremylt // LCOV_EXCL_START 549891038deSjeremylt return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 550891038deSjeremylt "Backend does not support TakeData"); 551891038deSjeremylt // LCOV_EXCL_STOP 552891038deSjeremylt 553891038deSjeremylt if (ctx->state % 2 == 1) 554891038deSjeremylt // LCOV_EXCL_START 555891038deSjeremylt return CeedError(ctx->ceed, 1, 556891038deSjeremylt "Cannot grant CeedQFunctionContext data access, the " 557891038deSjeremylt "access lock is already in use"); 558891038deSjeremylt // LCOV_EXCL_STOP 559891038deSjeremylt 5609c774eddSJeremy L Thompson bool has_borrowed_data_of_type = true; 5619c774eddSJeremy L Thompson ierr = CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, 5629c774eddSJeremy L Thompson &has_borrowed_data_of_type); CeedChk(ierr); 5639c774eddSJeremy L Thompson if (!has_borrowed_data_of_type) 5649c774eddSJeremy L Thompson // LCOV_EXCL_START 5659c774eddSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, 5669c774eddSJeremy L Thompson "CeedQFunctionContext has no borowed %s data, " 5679c774eddSJeremy L Thompson "must set data with CeedQFunctionContextSetData", 5689c774eddSJeremy L Thompson CeedMemTypes[mem_type]); 5699c774eddSJeremy L Thompson // LCOV_EXCL_STOP 5709c774eddSJeremy L Thompson 571891038deSjeremylt void *temp_data = NULL; 572891038deSjeremylt ierr = ctx->TakeData(ctx, mem_type, &temp_data); CeedChk(ierr); 573891038deSjeremylt if (data) (*(void **)data) = temp_data; 574891038deSjeremylt return CEED_ERROR_SUCCESS; 575891038deSjeremylt } 576891038deSjeremylt 577891038deSjeremylt /** 578777ff853SJeremy L Thompson @brief Get read/write access to a CeedQFunctionContext via the specified memory type. 579777ff853SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 580777ff853SJeremy L Thompson 581777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to access 582d1d35e2fSjeremylt @param mem_type Memory type on which to access the data. If the backend 583777ff853SJeremy L Thompson uses a different memory type, this will perform a copy. 584d1d35e2fSjeremylt @param[out] data Data on memory type mem_type 585777ff853SJeremy L Thompson 586777ff853SJeremy L Thompson @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions 587777ff853SJeremy L Thompson provide access to array pointers in the desired memory space. Pairing 588777ff853SJeremy L Thompson get/restore allows the Context to track access. 589777ff853SJeremy L Thompson 590777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 591777ff853SJeremy L Thompson 592777ff853SJeremy L Thompson @ref User 593777ff853SJeremy L Thompson **/ 594d1d35e2fSjeremylt int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, 595777ff853SJeremy L Thompson void *data) { 596777ff853SJeremy L Thompson int ierr; 597777ff853SJeremy L Thompson 598777ff853SJeremy L Thompson if (!ctx->GetData) 599777ff853SJeremy L Thompson // LCOV_EXCL_START 600e15f9bd0SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 601e15f9bd0SJeremy L Thompson "Backend does not support GetData"); 602777ff853SJeremy L Thompson // LCOV_EXCL_STOP 603777ff853SJeremy L Thompson 604777ff853SJeremy L Thompson if (ctx->state % 2 == 1) 605777ff853SJeremy L Thompson // LCOV_EXCL_START 606777ff853SJeremy L Thompson return CeedError(ctx->ceed, 1, 607777ff853SJeremy L Thompson "Cannot grant CeedQFunctionContext data access, the " 608777ff853SJeremy L Thompson "access lock is already in use"); 609777ff853SJeremy L Thompson // LCOV_EXCL_STOP 610777ff853SJeremy L Thompson 61128bfd0b7SJeremy L Thompson if (ctx->num_readers > 0) 61228bfd0b7SJeremy L Thompson // LCOV_EXCL_START 61328bfd0b7SJeremy L Thompson return CeedError(ctx->ceed, 1, 61428bfd0b7SJeremy L Thompson "Cannot grant CeedQFunctionContext data access, a " 61528bfd0b7SJeremy L Thompson "process has read access"); 61628bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 61728bfd0b7SJeremy L Thompson 6189c774eddSJeremy L Thompson bool has_valid_data = true; 6199c774eddSJeremy L Thompson ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr); 6209c774eddSJeremy L Thompson if (!has_valid_data) 6219c774eddSJeremy L Thompson // LCOV_EXCL_START 6229c774eddSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, 6239c774eddSJeremy L Thompson "CeedQFunctionContext has no valid data to get, must set data"); 6249c774eddSJeremy L Thompson // LCOV_EXCL_STOP 6259c774eddSJeremy L Thompson 626d1d35e2fSjeremylt ierr = ctx->GetData(ctx, mem_type, data); CeedChk(ierr); 62728bfd0b7SJeremy L Thompson ctx->state++; 62828bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 62928bfd0b7SJeremy L Thompson } 63028bfd0b7SJeremy L Thompson 63128bfd0b7SJeremy L Thompson /** 63228bfd0b7SJeremy L Thompson @brief Get read only access to a CeedQFunctionContext via the specified memory type. 63328bfd0b7SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 63428bfd0b7SJeremy L Thompson 63528bfd0b7SJeremy L Thompson @param ctx CeedQFunctionContext to access 63628bfd0b7SJeremy L Thompson @param mem_type Memory type on which to access the data. If the backend 63728bfd0b7SJeremy L Thompson uses a different memory type, this will perform a copy. 63828bfd0b7SJeremy L Thompson @param[out] data Data on memory type mem_type 63928bfd0b7SJeremy L Thompson 64028bfd0b7SJeremy L Thompson @note The CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead() 64128bfd0b7SJeremy L Thompson functions provide access to array pointers in the desired memory space. Pairing 64228bfd0b7SJeremy L Thompson get/restore allows the Context to track access. 64328bfd0b7SJeremy L Thompson 64428bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 64528bfd0b7SJeremy L Thompson 64628bfd0b7SJeremy L Thompson @ref User 64728bfd0b7SJeremy L Thompson **/ 64828bfd0b7SJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx, 64928bfd0b7SJeremy L Thompson CeedMemType mem_type, 65028bfd0b7SJeremy L Thompson void *data) { 65128bfd0b7SJeremy L Thompson int ierr; 65228bfd0b7SJeremy L Thompson 65328bfd0b7SJeremy L Thompson if (!ctx->GetDataRead) 65428bfd0b7SJeremy L Thompson // LCOV_EXCL_START 65528bfd0b7SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 65628bfd0b7SJeremy L Thompson "Backend does not support GetDataRead"); 65728bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 65828bfd0b7SJeremy L Thompson 65928bfd0b7SJeremy L Thompson if (ctx->state % 2 == 1) 66028bfd0b7SJeremy L Thompson // LCOV_EXCL_START 66128bfd0b7SJeremy L Thompson return CeedError(ctx->ceed, 1, 66228bfd0b7SJeremy L Thompson "Cannot grant CeedQFunctionContext data access, the " 66328bfd0b7SJeremy L Thompson "access lock is already in use"); 66428bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 66528bfd0b7SJeremy L Thompson 66628bfd0b7SJeremy L Thompson bool has_valid_data = true; 66728bfd0b7SJeremy L Thompson ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr); 66828bfd0b7SJeremy L Thompson if (!has_valid_data) 66928bfd0b7SJeremy L Thompson // LCOV_EXCL_START 67028bfd0b7SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, 67128bfd0b7SJeremy L Thompson "CeedQFunctionContext has no valid data to get, must set data"); 67228bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 67328bfd0b7SJeremy L Thompson 67428bfd0b7SJeremy L Thompson ierr = ctx->GetDataRead(ctx, mem_type, data); CeedChk(ierr); 67528bfd0b7SJeremy L Thompson ctx->num_readers++; 676e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 677777ff853SJeremy L Thompson } 678777ff853SJeremy L Thompson 679777ff853SJeremy L Thompson /** 680777ff853SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetData() 681777ff853SJeremy L Thompson 682777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to restore 683777ff853SJeremy L Thompson @param data Data to restore 684777ff853SJeremy L Thompson 685777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 686777ff853SJeremy L Thompson 687777ff853SJeremy L Thompson @ref User 688777ff853SJeremy L Thompson **/ 689777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) { 690777ff853SJeremy L Thompson int ierr; 691777ff853SJeremy L Thompson 692777ff853SJeremy L Thompson if (ctx->state % 2 != 1) 693777ff853SJeremy L Thompson // LCOV_EXCL_START 694777ff853SJeremy L Thompson return CeedError(ctx->ceed, 1, 695777ff853SJeremy L Thompson "Cannot restore CeedQFunctionContext array access, " 696777ff853SJeremy L Thompson "access was not granted"); 697777ff853SJeremy L Thompson // LCOV_EXCL_STOP 698777ff853SJeremy L Thompson 699706efda3SJeremy L Thompson if (ctx->RestoreData) { 700777ff853SJeremy L Thompson ierr = ctx->RestoreData(ctx); CeedChk(ierr); 701706efda3SJeremy L Thompson } 702777ff853SJeremy L Thompson *(void **)data = NULL; 70328bfd0b7SJeremy L Thompson ctx->state++; 70428bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 70528bfd0b7SJeremy L Thompson } 70628bfd0b7SJeremy L Thompson 70728bfd0b7SJeremy L Thompson /** 70828bfd0b7SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead() 70928bfd0b7SJeremy L Thompson 71028bfd0b7SJeremy L Thompson @param ctx CeedQFunctionContext to restore 71128bfd0b7SJeremy L Thompson @param data Data to restore 71228bfd0b7SJeremy L Thompson 71328bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 71428bfd0b7SJeremy L Thompson 71528bfd0b7SJeremy L Thompson @ref User 71628bfd0b7SJeremy L Thompson **/ 71728bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) { 71828bfd0b7SJeremy L Thompson int ierr; 71928bfd0b7SJeremy L Thompson 72028bfd0b7SJeremy L Thompson if (ctx->num_readers == 0) 72128bfd0b7SJeremy L Thompson // LCOV_EXCL_START 72228bfd0b7SJeremy L Thompson return CeedError(ctx->ceed, 1, 72328bfd0b7SJeremy L Thompson "Cannot restore CeedQFunctionContext array access, " 72428bfd0b7SJeremy L Thompson "access was not granted"); 72528bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 72628bfd0b7SJeremy L Thompson 72728bfd0b7SJeremy L Thompson if (ctx->RestoreDataRead) { 72828bfd0b7SJeremy L Thompson ierr = ctx->RestoreData(ctx); CeedChk(ierr); 72928bfd0b7SJeremy L Thompson } 73028bfd0b7SJeremy L Thompson *(void **)data = NULL; 73128bfd0b7SJeremy L Thompson ctx->num_readers--; 732e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 733777ff853SJeremy L Thompson } 734777ff853SJeremy L Thompson 735777ff853SJeremy L Thompson /** 736cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a double precision value 737cdf32b93SJeremy L Thompson 738cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 739cdf32b93SJeremy L Thompson @param field_name Name of field to register 740cdf32b93SJeremy L Thompson @param field_offset Offset of field to register 7417bfe0f0eSJeremy L Thompson @param num_values Number of values to register, must be contiguous in memory 742cdf32b93SJeremy L Thompson @param field_description Description of field, or NULL for none 743cdf32b93SJeremy L Thompson 744cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 745cdf32b93SJeremy L Thompson 746cdf32b93SJeremy L Thompson @ref User 747cdf32b93SJeremy L Thompson **/ 748cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, 749cdf32b93SJeremy L Thompson const char *field_name, size_t field_offset, 7507bfe0f0eSJeremy L Thompson size_t num_values, 751cdf32b93SJeremy L Thompson const char *field_description) { 752cdf32b93SJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, 7537bfe0f0eSJeremy L Thompson field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double), num_values); 754cdf32b93SJeremy L Thompson } 755cdf32b93SJeremy L Thompson 756cdf32b93SJeremy L Thompson /** 757cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a int32 value 758cdf32b93SJeremy L Thompson 759cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 760cdf32b93SJeremy L Thompson @param field_name Name of field to register 761cdf32b93SJeremy L Thompson @param field_offset Offset of field to register 7627bfe0f0eSJeremy L Thompson @param num_values Number of values to register, must be contiguous in memory 763cdf32b93SJeremy L Thompson @param field_description Description of field, or NULL for none 764cdf32b93SJeremy L Thompson 765cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 766cdf32b93SJeremy L Thompson 767cdf32b93SJeremy L Thompson @ref User 768cdf32b93SJeremy L Thompson **/ 769cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, 770cdf32b93SJeremy L Thompson const char *field_name, size_t field_offset, 7717bfe0f0eSJeremy L Thompson size_t num_values, 772cdf32b93SJeremy L Thompson const char *field_description) { 773cdf32b93SJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, 7747bfe0f0eSJeremy L Thompson field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int), num_values); 775cdf32b93SJeremy L Thompson } 776cdf32b93SJeremy L Thompson 777cdf32b93SJeremy L Thompson /** 7783668ca4bSJeremy L Thompson @brief Get labels for all registered QFunctionContext fields 779cdf32b93SJeremy L Thompson 780cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 7813668ca4bSJeremy L Thompson @param[out] field_labels Variable to hold array of field labels 782cdf32b93SJeremy L Thompson @param[out] num_fields Length of field descriptions array 783cdf32b93SJeremy L Thompson 784cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 785cdf32b93SJeremy L Thompson 786cdf32b93SJeremy L Thompson @ref User 787cdf32b93SJeremy L Thompson **/ 7883668ca4bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, 7893668ca4bSJeremy L Thompson const CeedContextFieldLabel **field_labels, CeedInt *num_fields) { 7903668ca4bSJeremy L Thompson *field_labels = ctx->field_labels; 791cdf32b93SJeremy L Thompson *num_fields = ctx->num_fields; 792cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 793cdf32b93SJeremy L Thompson } 794cdf32b93SJeremy L Thompson 795cdf32b93SJeremy L Thompson /** 7960f86cbe7SJeremy L Thompson @brief Get the descriptive information about a CeedContextFieldLabel 7970f86cbe7SJeremy L Thompson 7980f86cbe7SJeremy L Thompson @param[in] label CeedContextFieldLabel 7990f86cbe7SJeremy L Thompson @param[out] field_name Name of labeled field 8000f86cbe7SJeremy L Thompson @param[out] field_description Description of field, or NULL for none 8017bfe0f0eSJeremy L Thompson @param[out] num_values Number of values registered 8020f86cbe7SJeremy L Thompson @param[out] field_type CeedContextFieldType 8030f86cbe7SJeremy L Thompson 8040f86cbe7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8050f86cbe7SJeremy L Thompson 8060f86cbe7SJeremy L Thompson @ref User 8070f86cbe7SJeremy L Thompson **/ 8080f86cbe7SJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, 8090f86cbe7SJeremy L Thompson const char **field_name, 8100f86cbe7SJeremy L Thompson const char **field_description, 8117bfe0f0eSJeremy L Thompson size_t *num_values, 8120f86cbe7SJeremy L Thompson CeedContextFieldType *field_type) { 8130f86cbe7SJeremy L Thompson if (field_name) *field_name = label->name; 8140f86cbe7SJeremy L Thompson if (field_description) *field_description = label->description; 8157bfe0f0eSJeremy L Thompson if (num_values) *num_values = label->num_values; 8160f86cbe7SJeremy L Thompson if (field_type) *field_type = label->type; 8170f86cbe7SJeremy L Thompson return CEED_ERROR_SUCCESS; 8180f86cbe7SJeremy L Thompson } 8190f86cbe7SJeremy L Thompson 8200f86cbe7SJeremy L Thompson /** 82180a9ef05SNatalie Beams @brief Get data size for a Context 82280a9ef05SNatalie Beams 82380a9ef05SNatalie Beams @param ctx CeedQFunctionContext 82480a9ef05SNatalie Beams @param[out] ctx_size Variable to store size of context data values 82580a9ef05SNatalie Beams 82680a9ef05SNatalie Beams @return An error code: 0 - success, otherwise - failure 82780a9ef05SNatalie Beams 82880a9ef05SNatalie Beams @ref User 82980a9ef05SNatalie Beams **/ 83080a9ef05SNatalie Beams int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, 83180a9ef05SNatalie Beams size_t *ctx_size) { 83280a9ef05SNatalie Beams *ctx_size = ctx->ctx_size; 83380a9ef05SNatalie Beams return CEED_ERROR_SUCCESS; 83480a9ef05SNatalie Beams } 83580a9ef05SNatalie Beams 83680a9ef05SNatalie Beams 83780a9ef05SNatalie Beams /** 838777ff853SJeremy L Thompson @brief View a CeedQFunctionContext 839777ff853SJeremy L Thompson 840777ff853SJeremy L Thompson @param[in] ctx CeedQFunctionContext to view 841777ff853SJeremy L Thompson @param[in] stream Filestream to write to 842777ff853SJeremy L Thompson 843777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 844777ff853SJeremy L Thompson 845777ff853SJeremy L Thompson @ref User 846777ff853SJeremy L Thompson **/ 847777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) { 848777ff853SJeremy L Thompson fprintf(stream, "CeedQFunctionContext\n"); 849d1d35e2fSjeremylt fprintf(stream, " Context Data Size: %ld\n", ctx->ctx_size); 8503668ca4bSJeremy L Thompson for (CeedInt i = 0; i < ctx->num_fields; i++) { 8513668ca4bSJeremy L Thompson // LCOV_EXCL_START 8523668ca4bSJeremy L Thompson fprintf(stream, " Labeled %s field: %s\n", 8533668ca4bSJeremy L Thompson CeedContextFieldTypes[ctx->field_labels[i]->type], 8543668ca4bSJeremy L Thompson ctx->field_labels[i]->name); 8553668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 8563668ca4bSJeremy L Thompson } 857e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 858777ff853SJeremy L Thompson } 859777ff853SJeremy L Thompson 860777ff853SJeremy L Thompson /** 8612790b72bSJeremy L Thompson @brief Set additional destroy routine for CeedQFunctionContext user data 8622790b72bSJeremy L Thompson 863*2e64a2b9SJeremy L Thompson @param[in] ctx CeedQFunctionContext to set user destroy function 864*2e64a2b9SJeremy L Thompson @param[in] f_mem_type Memory type to use when passing data into `f` 865*2e64a2b9SJeremy L Thompson @param[in] f Additional routine to use to destroy user data 8662790b72bSJeremy L Thompson 8672790b72bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8682790b72bSJeremy L Thompson 8692790b72bSJeremy L Thompson @ref User 8702790b72bSJeremy L Thompson **/ 8712790b72bSJeremy L Thompson int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, 8722790b72bSJeremy L Thompson CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) { 8732790b72bSJeremy L Thompson if (!f) 8742790b72bSJeremy L Thompson // LCOV_EXCL_START 8752790b72bSJeremy L Thompson return CeedError(ctx->ceed, 1, 8762790b72bSJeremy L Thompson "Must provide valid callback function for destroying user data"); 8772790b72bSJeremy L Thompson // LCOV_EXCL_STOP 8782790b72bSJeremy L Thompson ctx->data_destroy_mem_type = f_mem_type; 8792790b72bSJeremy L Thompson ctx->data_destroy_function = f; 8802790b72bSJeremy L Thompson return CEED_ERROR_SUCCESS; 8812790b72bSJeremy L Thompson } 8822790b72bSJeremy L Thompson 8832790b72bSJeremy L Thompson /** 884777ff853SJeremy L Thompson @brief Destroy a CeedQFunctionContext 885777ff853SJeremy L Thompson 886777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to destroy 887777ff853SJeremy L Thompson 888777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 889777ff853SJeremy L Thompson 890777ff853SJeremy L Thompson @ref User 891777ff853SJeremy L Thompson **/ 892777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) { 893777ff853SJeremy L Thompson int ierr; 894777ff853SJeremy L Thompson 895d1d35e2fSjeremylt if (!*ctx || --(*ctx)->ref_count > 0) 896e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 897777ff853SJeremy L Thompson 898777ff853SJeremy L Thompson if ((*ctx) && ((*ctx)->state % 2) == 1) 899777ff853SJeremy L Thompson // LCOV_EXCL_START 900777ff853SJeremy L Thompson return CeedError((*ctx)->ceed, 1, 901777ff853SJeremy L Thompson "Cannot destroy CeedQFunctionContext, the access " 902777ff853SJeremy L Thompson "lock is in use"); 903777ff853SJeremy L Thompson // LCOV_EXCL_STOP 904777ff853SJeremy L Thompson 905*2e64a2b9SJeremy L Thompson ierr = CeedQFunctionContextDestroyData(*ctx); CeedChk(ierr); 906777ff853SJeremy L Thompson if ((*ctx)->Destroy) { 907777ff853SJeremy L Thompson ierr = (*ctx)->Destroy(*ctx); CeedChk(ierr); 908777ff853SJeremy L Thompson } 909cdf32b93SJeremy L Thompson for (CeedInt i=0; i<(*ctx)->num_fields; i++) { 9103668ca4bSJeremy L Thompson ierr = CeedFree(&(*ctx)->field_labels[i]->name); CeedChk(ierr); 9113668ca4bSJeremy L Thompson ierr = CeedFree(&(*ctx)->field_labels[i]->description); CeedChk(ierr); 9123668ca4bSJeremy L Thompson ierr = CeedFree(&(*ctx)->field_labels[i]); CeedChk(ierr); 913cdf32b93SJeremy L Thompson } 9143668ca4bSJeremy L Thompson ierr = CeedFree(&(*ctx)->field_labels); CeedChk(ierr); 915777ff853SJeremy L Thompson ierr = CeedDestroy(&(*ctx)->ceed); CeedChk(ierr); 916777ff853SJeremy L Thompson ierr = CeedFree(ctx); CeedChk(ierr); 917cdf32b93SJeremy L Thompson 918e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 919777ff853SJeremy L Thompson } 920777ff853SJeremy L Thompson 921777ff853SJeremy L Thompson /// @} 922