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 1033b190ab8SJeremy L Thompson /** 1043b190ab8SJeremy L Thompson @brief Destroy user data held by CeedQFunctionContext, using function set by 1053b190ab8SJeremy L Thompson CeedQFunctionContextSetDataDestroy, if applicable 1063b190ab8SJeremy L Thompson 1073b190ab8SJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to destroy user data 1083b190ab8SJeremy L Thompson 1093b190ab8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1103b190ab8SJeremy L Thompson 1113b190ab8SJeremy L Thompson @ref Developer 1123b190ab8SJeremy L Thompson **/ 1133b190ab8SJeremy L Thompson static int CeedQFunctionContextDestroyData(CeedQFunctionContext ctx) { 1143b190ab8SJeremy L Thompson int ierr; 1153b190ab8SJeremy L Thompson 1163b190ab8SJeremy L Thompson if (ctx->DataDestroy) { 1173b190ab8SJeremy L Thompson ierr = ctx->DataDestroy(ctx); CeedChk(ierr); 1183b190ab8SJeremy L Thompson } else { 1193b190ab8SJeremy L Thompson CeedQFunctionContextDataDestroyUser data_destroy_function; 1203b190ab8SJeremy L Thompson CeedMemType data_destroy_mem_type; 1213b190ab8SJeremy L Thompson 1223b190ab8SJeremy L Thompson ierr = CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, 1233b190ab8SJeremy L Thompson &data_destroy_function); CeedChk(ierr); 1243b190ab8SJeremy L Thompson if (data_destroy_function) { 1253b190ab8SJeremy L Thompson void *data; 1263b190ab8SJeremy L Thompson 1273b190ab8SJeremy L Thompson ierr = CeedQFunctionContextGetData(ctx, data_destroy_mem_type, &data); 1283b190ab8SJeremy L Thompson CeedChk(ierr); 1293b190ab8SJeremy L Thompson ierr = data_destroy_function(data); CeedChk(ierr); 1303b190ab8SJeremy L Thompson ierr = CeedQFunctionContextRestoreData(ctx, &data); CeedChk(ierr); 1313b190ab8SJeremy L Thompson } 1323b190ab8SJeremy L Thompson } 1333b190ab8SJeremy L Thompson 1343b190ab8SJeremy L Thompson return CEED_ERROR_SUCCESS; 1353b190ab8SJeremy L Thompson } 1363b190ab8SJeremy L Thompson 137cdf32b93SJeremy L Thompson /// @} 138cdf32b93SJeremy L Thompson 139cdf32b93SJeremy L Thompson /// ---------------------------------------------------------------------------- 140777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API 141777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 142777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend 143777ff853SJeremy L Thompson /// @{ 144777ff853SJeremy L Thompson 145777ff853SJeremy L Thompson /** 146777ff853SJeremy L Thompson @brief Get the Ceed associated with a CeedQFunctionContext 147777ff853SJeremy L Thompson 148777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 149777ff853SJeremy L Thompson @param[out] ceed Variable to store Ceed 150777ff853SJeremy L Thompson 151777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 152777ff853SJeremy L Thompson 153777ff853SJeremy L Thompson @ref Backend 154777ff853SJeremy L Thompson **/ 155777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) { 156777ff853SJeremy L Thompson *ceed = ctx->ceed; 157e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 158777ff853SJeremy L Thompson } 159777ff853SJeremy L Thompson 160777ff853SJeremy L Thompson /** 1619c774eddSJeremy L Thompson @brief Check for valid data in a CeedQFunctionContext 1629c774eddSJeremy L Thompson 1639c774eddSJeremy L Thompson @param ctx CeedQFunctionContext to check validity 1649c774eddSJeremy L Thompson @param[out] has_valid_data Variable to store validity 1659c774eddSJeremy L Thompson 1669c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1679c774eddSJeremy L Thompson 1689c774eddSJeremy L Thompson @ref Backend 1699c774eddSJeremy L Thompson **/ 1709c774eddSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx, 1719c774eddSJeremy L Thompson bool *has_valid_data) { 1729c774eddSJeremy L Thompson int ierr; 1739c774eddSJeremy L Thompson 1749c774eddSJeremy L Thompson if (!ctx->HasValidData) 1759c774eddSJeremy L Thompson // LCOV_EXCL_START 1769c774eddSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 1779c774eddSJeremy L Thompson "Backend does not support HasValidData"); 1789c774eddSJeremy L Thompson // LCOV_EXCL_STOP 1799c774eddSJeremy L Thompson 1809c774eddSJeremy L Thompson ierr = ctx->HasValidData(ctx, has_valid_data); CeedChk(ierr); 1819c774eddSJeremy L Thompson 1829c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 1839c774eddSJeremy L Thompson } 1849c774eddSJeremy L Thompson 1859c774eddSJeremy L Thompson /** 1869c774eddSJeremy L Thompson @brief Check for borrowed data of a specific CeedMemType in a 1879c774eddSJeremy L Thompson CeedQFunctionContext 1889c774eddSJeremy L Thompson 1899c774eddSJeremy L Thompson @param ctx CeedQFunctionContext to check 1909c774eddSJeremy L Thompson @param mem_type Memory type to check 1919c774eddSJeremy L Thompson @param[out] has_borrowed_data_of_type Variable to store result 1929c774eddSJeremy L Thompson 1939c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1949c774eddSJeremy L Thompson 1959c774eddSJeremy L Thompson @ref Backend 1969c774eddSJeremy L Thompson **/ 1979c774eddSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx, 1989c774eddSJeremy L Thompson CeedMemType mem_type, bool *has_borrowed_data_of_type) { 1999c774eddSJeremy L Thompson int ierr; 2009c774eddSJeremy L Thompson 2019c774eddSJeremy L Thompson if (!ctx->HasBorrowedDataOfType) 2029c774eddSJeremy L Thompson // LCOV_EXCL_START 2039c774eddSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 2049c774eddSJeremy L Thompson "Backend does not support HasBorrowedDataOfType"); 2059c774eddSJeremy L Thompson // LCOV_EXCL_STOP 2069c774eddSJeremy L Thompson 2079c774eddSJeremy L Thompson ierr = ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type); 2089c774eddSJeremy L Thompson CeedChk(ierr); 2099c774eddSJeremy L Thompson 2109c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 2119c774eddSJeremy L Thompson } 2129c774eddSJeremy L Thompson 2139c774eddSJeremy L Thompson /** 214777ff853SJeremy L Thompson @brief Get the state of a CeedQFunctionContext 215777ff853SJeremy L Thompson 216777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to retrieve state 217777ff853SJeremy L Thompson @param[out] state Variable to store state 218777ff853SJeremy L Thompson 219777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 220777ff853SJeremy L Thompson 221777ff853SJeremy L Thompson @ref Backend 222777ff853SJeremy L Thompson **/ 223777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) { 224777ff853SJeremy L Thompson *state = ctx->state; 225e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 226777ff853SJeremy L Thompson } 227777ff853SJeremy L Thompson 228777ff853SJeremy L Thompson /** 229777ff853SJeremy L Thompson @brief Get backend data of a CeedQFunctionContext 230777ff853SJeremy L Thompson 231777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 232777ff853SJeremy L Thompson @param[out] data Variable to store data 233777ff853SJeremy L Thompson 234777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 235777ff853SJeremy L Thompson 236777ff853SJeremy L Thompson @ref Backend 237777ff853SJeremy L Thompson **/ 238777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) { 239777ff853SJeremy L Thompson *(void **)data = ctx->data; 240e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 241777ff853SJeremy L Thompson } 242777ff853SJeremy L Thompson 243777ff853SJeremy L Thompson /** 244777ff853SJeremy L Thompson @brief Set backend data of a CeedQFunctionContext 245777ff853SJeremy L Thompson 246777ff853SJeremy L Thompson @param[out] ctx CeedQFunctionContext 247777ff853SJeremy L Thompson @param data Data to set 248777ff853SJeremy L Thompson 249777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 250777ff853SJeremy L Thompson 251777ff853SJeremy L Thompson @ref Backend 252777ff853SJeremy L Thompson **/ 253777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) { 254777ff853SJeremy L Thompson ctx->data = data; 255e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 256777ff853SJeremy L Thompson } 257777ff853SJeremy L Thompson 25834359f16Sjeremylt /** 259e6a0ab89SJeremy L Thompson @brief Get label for a registered QFunctionContext field, or `NULL` if no 260e6a0ab89SJeremy L Thompson field has been registered with this `field_name` 261e6a0ab89SJeremy L Thompson 262e6a0ab89SJeremy L Thompson @param[in] ctx CeedQFunctionContext 263e6a0ab89SJeremy L Thompson @param[in] field_name Name of field to retrieve label 264e6a0ab89SJeremy L Thompson @param[out] field_label Variable to field label 265e6a0ab89SJeremy L Thompson 266e6a0ab89SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 267e6a0ab89SJeremy L Thompson 2683e1e85abSJeremy L Thompson @ref Backend 269e6a0ab89SJeremy L Thompson **/ 270e6a0ab89SJeremy L Thompson int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx, 271e6a0ab89SJeremy L Thompson const char *field_name, 272e6a0ab89SJeremy L Thompson CeedContextFieldLabel *field_label) { 273e6a0ab89SJeremy L Thompson int ierr; 274e6a0ab89SJeremy L Thompson 275e6a0ab89SJeremy L Thompson CeedInt field_index; 276e6a0ab89SJeremy L Thompson ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index); 277e6a0ab89SJeremy L Thompson CeedChk(ierr); 278e6a0ab89SJeremy L Thompson 279e6a0ab89SJeremy L Thompson if (field_index != -1) { 280e6a0ab89SJeremy L Thompson *field_label = ctx->field_labels[field_index]; 281e6a0ab89SJeremy L Thompson } else { 282e6a0ab89SJeremy L Thompson *field_label = NULL; 283e6a0ab89SJeremy L Thompson } 284e6a0ab89SJeremy L Thompson 285e6a0ab89SJeremy L Thompson return CEED_ERROR_SUCCESS; 286e6a0ab89SJeremy L Thompson } 287e6a0ab89SJeremy L Thompson 288e6a0ab89SJeremy L Thompson /** 289d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field 290d8dd9a91SJeremy L Thompson 291d8dd9a91SJeremy L Thompson @param ctx CeedQFunctionContext 2923668ca4bSJeremy L Thompson @param field_label Label of field to set 293d8dd9a91SJeremy L Thompson @param field_type Type of field to set 294d8dd9a91SJeremy L Thompson @param value Value to set 295d8dd9a91SJeremy L Thompson 296d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 297d8dd9a91SJeremy L Thompson 2983e1e85abSJeremy L Thompson @ref Backend 299d8dd9a91SJeremy L Thompson **/ 300d8dd9a91SJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx, 3013668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, 302d8dd9a91SJeremy L Thompson CeedContextFieldType field_type, 3033668ca4bSJeremy L Thompson void *value) { 304d8dd9a91SJeremy L Thompson int ierr; 305d8dd9a91SJeremy L Thompson 3063668ca4bSJeremy L Thompson // Check field type 3073668ca4bSJeremy L Thompson if (field_label->type != field_type) 308d8dd9a91SJeremy L Thompson // LCOV_EXCL_START 309d8dd9a91SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 310d8dd9a91SJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, " 3113668ca4bSJeremy L Thompson "not registered as %s", field_label->name, 3123668ca4bSJeremy L Thompson CeedContextFieldTypes[field_label->type], 313d8dd9a91SJeremy L Thompson CeedContextFieldTypes[field_type]); 314d8dd9a91SJeremy L Thompson // LCOV_EXCL_STOP 315d8dd9a91SJeremy L Thompson 316d8dd9a91SJeremy L Thompson char *data; 317d8dd9a91SJeremy L Thompson ierr = CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data); CeedChk(ierr); 3183668ca4bSJeremy L Thompson memcpy(&data[field_label->offset], value, field_label->size); 319d8dd9a91SJeremy L Thompson ierr = CeedQFunctionContextRestoreData(ctx, &data); CeedChk(ierr); 320d8dd9a91SJeremy L Thompson 321d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 322d8dd9a91SJeremy L Thompson } 323d8dd9a91SJeremy L Thompson 324d8dd9a91SJeremy L Thompson /** 325bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value 326bfacc300SJeremy L Thompson 327bfacc300SJeremy L Thompson @param ctx CeedQFunctionContext 328bfacc300SJeremy L Thompson @param field_label Label for field to register 329bfacc300SJeremy L Thompson @param values Values to set 330bfacc300SJeremy L Thompson 331bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 332bfacc300SJeremy L Thompson 3333e1e85abSJeremy L Thompson @ref Backend 334bfacc300SJeremy L Thompson **/ 335bfacc300SJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, 336bfacc300SJeremy L Thompson CeedContextFieldLabel field_label, double *values) { 337bfacc300SJeremy L Thompson int ierr; 338bfacc300SJeremy L Thompson 339bfacc300SJeremy L Thompson if (!field_label) 340bfacc300SJeremy L Thompson // LCOV_EXCL_START 341bfacc300SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 342bfacc300SJeremy L Thompson "Invalid field label"); 343bfacc300SJeremy L Thompson // LCOV_EXCL_STOP 344bfacc300SJeremy L Thompson 345bfacc300SJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(ctx, field_label, 346bfacc300SJeremy L Thompson CEED_CONTEXT_FIELD_DOUBLE, 347bfacc300SJeremy L Thompson values); CeedChk(ierr); 348bfacc300SJeremy L Thompson 349bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 350bfacc300SJeremy L Thompson } 351bfacc300SJeremy L Thompson 352bfacc300SJeremy L Thompson /** 353bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding an int32 value 354bfacc300SJeremy L Thompson 355bfacc300SJeremy L Thompson @param ctx CeedQFunctionContext 356bfacc300SJeremy L Thompson @param field_label Label for field to register 357bfacc300SJeremy L Thompson @param values Values to set 358bfacc300SJeremy L Thompson 359bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 360bfacc300SJeremy L Thompson 3613e1e85abSJeremy L Thompson @ref Backend 362bfacc300SJeremy L Thompson **/ 363bfacc300SJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, 364bfacc300SJeremy L Thompson CeedContextFieldLabel field_label, int *values) { 365bfacc300SJeremy L Thompson int ierr; 366bfacc300SJeremy L Thompson 367bfacc300SJeremy L Thompson if (!field_label) 368bfacc300SJeremy L Thompson // LCOV_EXCL_START 369bfacc300SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 370bfacc300SJeremy L Thompson "Invalid field label"); 371bfacc300SJeremy L Thompson // LCOV_EXCL_STOP 372bfacc300SJeremy L Thompson 373bfacc300SJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(ctx, field_label, 374bfacc300SJeremy L Thompson CEED_CONTEXT_FIELD_INT32, 375bfacc300SJeremy L Thompson values); CeedChk(ierr); 376bfacc300SJeremy L Thompson 377bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 378bfacc300SJeremy L Thompson } 379bfacc300SJeremy L Thompson 380bfacc300SJeremy L Thompson /** 3812e64a2b9SJeremy L Thompson @brief Get additional destroy routine for CeedQFunctionContext user data 3822e64a2b9SJeremy L Thompson 3832e64a2b9SJeremy L Thompson @param[in] ctx CeedQFunctionContext to get user destroy function 3842e64a2b9SJeremy L Thompson @param[out] f_mem_type Memory type to use when passing data into `f` 3852e64a2b9SJeremy L Thompson @param[out] f Additional routine to use to destroy user data 3862e64a2b9SJeremy L Thompson 3872e64a2b9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3882e64a2b9SJeremy L Thompson 3892e64a2b9SJeremy L Thompson @ref Backend 3902e64a2b9SJeremy L Thompson **/ 3912e64a2b9SJeremy L Thompson int CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx, 3922e64a2b9SJeremy L Thompson CeedMemType *f_mem_type, CeedQFunctionContextDataDestroyUser *f) { 3932e64a2b9SJeremy L Thompson if (f_mem_type) *f_mem_type = ctx->data_destroy_mem_type; 3942e64a2b9SJeremy L Thompson if (f) *f = ctx->data_destroy_function; 3952e64a2b9SJeremy L Thompson return CEED_ERROR_SUCCESS; 3962e64a2b9SJeremy L Thompson } 3972e64a2b9SJeremy L Thompson 3982e64a2b9SJeremy 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 5152e64a2b9SJeremy 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 727*75a19770SJeremy L Thompson ctx->num_readers--; 728*75a19770SJeremy L Thompson if (ctx->num_readers == 0 && ctx->RestoreDataRead) { 72928bfd0b7SJeremy L Thompson ierr = ctx->RestoreData(ctx); CeedChk(ierr); 73028bfd0b7SJeremy L Thompson } 73128bfd0b7SJeremy L Thompson *(void **)data = NULL; 732*75a19770SJeremy L Thompson 733e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 734777ff853SJeremy L Thompson } 735777ff853SJeremy L Thompson 736777ff853SJeremy L Thompson /** 737cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a double precision value 738cdf32b93SJeremy L Thompson 739cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 740cdf32b93SJeremy L Thompson @param field_name Name of field to register 741cdf32b93SJeremy L Thompson @param field_offset Offset of field to register 7427bfe0f0eSJeremy L Thompson @param num_values Number of values to register, must be contiguous in memory 743cdf32b93SJeremy L Thompson @param field_description Description of field, or NULL for none 744cdf32b93SJeremy L Thompson 745cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 746cdf32b93SJeremy L Thompson 747cdf32b93SJeremy L Thompson @ref User 748cdf32b93SJeremy L Thompson **/ 749cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, 750cdf32b93SJeremy L Thompson const char *field_name, size_t field_offset, 7517bfe0f0eSJeremy L Thompson size_t num_values, 752cdf32b93SJeremy L Thompson const char *field_description) { 753cdf32b93SJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, 7547bfe0f0eSJeremy L Thompson field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double), num_values); 755cdf32b93SJeremy L Thompson } 756cdf32b93SJeremy L Thompson 757cdf32b93SJeremy L Thompson /** 758cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a int32 value 759cdf32b93SJeremy L Thompson 760cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 761cdf32b93SJeremy L Thompson @param field_name Name of field to register 762cdf32b93SJeremy L Thompson @param field_offset Offset of field to register 7637bfe0f0eSJeremy L Thompson @param num_values Number of values to register, must be contiguous in memory 764cdf32b93SJeremy L Thompson @param field_description Description of field, or NULL for none 765cdf32b93SJeremy L Thompson 766cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 767cdf32b93SJeremy L Thompson 768cdf32b93SJeremy L Thompson @ref User 769cdf32b93SJeremy L Thompson **/ 770cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, 771cdf32b93SJeremy L Thompson const char *field_name, size_t field_offset, 7727bfe0f0eSJeremy L Thompson size_t num_values, 773cdf32b93SJeremy L Thompson const char *field_description) { 774cdf32b93SJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, 7757bfe0f0eSJeremy L Thompson field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int), num_values); 776cdf32b93SJeremy L Thompson } 777cdf32b93SJeremy L Thompson 778cdf32b93SJeremy L Thompson /** 7793668ca4bSJeremy L Thompson @brief Get labels for all registered QFunctionContext fields 780cdf32b93SJeremy L Thompson 781cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 7823668ca4bSJeremy L Thompson @param[out] field_labels Variable to hold array of field labels 783cdf32b93SJeremy L Thompson @param[out] num_fields Length of field descriptions array 784cdf32b93SJeremy L Thompson 785cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 786cdf32b93SJeremy L Thompson 787cdf32b93SJeremy L Thompson @ref User 788cdf32b93SJeremy L Thompson **/ 7893668ca4bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, 7903668ca4bSJeremy L Thompson const CeedContextFieldLabel **field_labels, CeedInt *num_fields) { 7913668ca4bSJeremy L Thompson *field_labels = ctx->field_labels; 792cdf32b93SJeremy L Thompson *num_fields = ctx->num_fields; 793cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 794cdf32b93SJeremy L Thompson } 795cdf32b93SJeremy L Thompson 796cdf32b93SJeremy L Thompson /** 7970f86cbe7SJeremy L Thompson @brief Get the descriptive information about a CeedContextFieldLabel 7980f86cbe7SJeremy L Thompson 7990f86cbe7SJeremy L Thompson @param[in] label CeedContextFieldLabel 8000f86cbe7SJeremy L Thompson @param[out] field_name Name of labeled field 8010f86cbe7SJeremy L Thompson @param[out] field_description Description of field, or NULL for none 8027bfe0f0eSJeremy L Thompson @param[out] num_values Number of values registered 8030f86cbe7SJeremy L Thompson @param[out] field_type CeedContextFieldType 8040f86cbe7SJeremy L Thompson 8050f86cbe7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8060f86cbe7SJeremy L Thompson 8070f86cbe7SJeremy L Thompson @ref User 8080f86cbe7SJeremy L Thompson **/ 8090f86cbe7SJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, 8100f86cbe7SJeremy L Thompson const char **field_name, 8110f86cbe7SJeremy L Thompson const char **field_description, 8127bfe0f0eSJeremy L Thompson size_t *num_values, 8130f86cbe7SJeremy L Thompson CeedContextFieldType *field_type) { 8140f86cbe7SJeremy L Thompson if (field_name) *field_name = label->name; 8150f86cbe7SJeremy L Thompson if (field_description) *field_description = label->description; 8167bfe0f0eSJeremy L Thompson if (num_values) *num_values = label->num_values; 8170f86cbe7SJeremy L Thompson if (field_type) *field_type = label->type; 8180f86cbe7SJeremy L Thompson return CEED_ERROR_SUCCESS; 8190f86cbe7SJeremy L Thompson } 8200f86cbe7SJeremy L Thompson 8210f86cbe7SJeremy L Thompson /** 82280a9ef05SNatalie Beams @brief Get data size for a Context 82380a9ef05SNatalie Beams 82480a9ef05SNatalie Beams @param ctx CeedQFunctionContext 82580a9ef05SNatalie Beams @param[out] ctx_size Variable to store size of context data values 82680a9ef05SNatalie Beams 82780a9ef05SNatalie Beams @return An error code: 0 - success, otherwise - failure 82880a9ef05SNatalie Beams 82980a9ef05SNatalie Beams @ref User 83080a9ef05SNatalie Beams **/ 83180a9ef05SNatalie Beams int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, 83280a9ef05SNatalie Beams size_t *ctx_size) { 83380a9ef05SNatalie Beams *ctx_size = ctx->ctx_size; 83480a9ef05SNatalie Beams return CEED_ERROR_SUCCESS; 83580a9ef05SNatalie Beams } 83680a9ef05SNatalie Beams 83780a9ef05SNatalie Beams 83880a9ef05SNatalie Beams /** 839777ff853SJeremy L Thompson @brief View a CeedQFunctionContext 840777ff853SJeremy L Thompson 841777ff853SJeremy L Thompson @param[in] ctx CeedQFunctionContext to view 842777ff853SJeremy L Thompson @param[in] stream Filestream to write to 843777ff853SJeremy L Thompson 844777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 845777ff853SJeremy L Thompson 846777ff853SJeremy L Thompson @ref User 847777ff853SJeremy L Thompson **/ 848777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) { 849777ff853SJeremy L Thompson fprintf(stream, "CeedQFunctionContext\n"); 850d1d35e2fSjeremylt fprintf(stream, " Context Data Size: %ld\n", ctx->ctx_size); 8513668ca4bSJeremy L Thompson for (CeedInt i = 0; i < ctx->num_fields; i++) { 8523668ca4bSJeremy L Thompson // LCOV_EXCL_START 8533668ca4bSJeremy L Thompson fprintf(stream, " Labeled %s field: %s\n", 8543668ca4bSJeremy L Thompson CeedContextFieldTypes[ctx->field_labels[i]->type], 8553668ca4bSJeremy L Thompson ctx->field_labels[i]->name); 8563668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 8573668ca4bSJeremy L Thompson } 858e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 859777ff853SJeremy L Thompson } 860777ff853SJeremy L Thompson 861777ff853SJeremy L Thompson /** 8622790b72bSJeremy L Thompson @brief Set additional destroy routine for CeedQFunctionContext user data 8632790b72bSJeremy L Thompson 8642e64a2b9SJeremy L Thompson @param[in] ctx CeedQFunctionContext to set user destroy function 8652e64a2b9SJeremy L Thompson @param[in] f_mem_type Memory type to use when passing data into `f` 8662e64a2b9SJeremy L Thompson @param[in] f Additional routine to use to destroy user data 8672790b72bSJeremy L Thompson 8682790b72bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8692790b72bSJeremy L Thompson 8702790b72bSJeremy L Thompson @ref User 8712790b72bSJeremy L Thompson **/ 8722790b72bSJeremy L Thompson int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, 8732790b72bSJeremy L Thompson CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) { 8742790b72bSJeremy L Thompson if (!f) 8752790b72bSJeremy L Thompson // LCOV_EXCL_START 8762790b72bSJeremy L Thompson return CeedError(ctx->ceed, 1, 8772790b72bSJeremy L Thompson "Must provide valid callback function for destroying user data"); 8782790b72bSJeremy L Thompson // LCOV_EXCL_STOP 8792790b72bSJeremy L Thompson ctx->data_destroy_mem_type = f_mem_type; 8802790b72bSJeremy L Thompson ctx->data_destroy_function = f; 8812790b72bSJeremy L Thompson return CEED_ERROR_SUCCESS; 8822790b72bSJeremy L Thompson } 8832790b72bSJeremy L Thompson 8842790b72bSJeremy L Thompson /** 885777ff853SJeremy L Thompson @brief Destroy a CeedQFunctionContext 886777ff853SJeremy L Thompson 887777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to destroy 888777ff853SJeremy L Thompson 889777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 890777ff853SJeremy L Thompson 891777ff853SJeremy L Thompson @ref User 892777ff853SJeremy L Thompson **/ 893777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) { 894777ff853SJeremy L Thompson int ierr; 895777ff853SJeremy L Thompson 896d1d35e2fSjeremylt if (!*ctx || --(*ctx)->ref_count > 0) 897e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 898777ff853SJeremy L Thompson 899777ff853SJeremy L Thompson if ((*ctx) && ((*ctx)->state % 2) == 1) 900777ff853SJeremy L Thompson // LCOV_EXCL_START 901777ff853SJeremy L Thompson return CeedError((*ctx)->ceed, 1, 902777ff853SJeremy L Thompson "Cannot destroy CeedQFunctionContext, the access " 903777ff853SJeremy L Thompson "lock is in use"); 904777ff853SJeremy L Thompson // LCOV_EXCL_STOP 905777ff853SJeremy L Thompson 9062e64a2b9SJeremy L Thompson ierr = CeedQFunctionContextDestroyData(*ctx); CeedChk(ierr); 907777ff853SJeremy L Thompson if ((*ctx)->Destroy) { 908777ff853SJeremy L Thompson ierr = (*ctx)->Destroy(*ctx); CeedChk(ierr); 909777ff853SJeremy L Thompson } 910cdf32b93SJeremy L Thompson for (CeedInt i=0; i<(*ctx)->num_fields; i++) { 9113668ca4bSJeremy L Thompson ierr = CeedFree(&(*ctx)->field_labels[i]->name); CeedChk(ierr); 9123668ca4bSJeremy L Thompson ierr = CeedFree(&(*ctx)->field_labels[i]->description); CeedChk(ierr); 9133668ca4bSJeremy L Thompson ierr = CeedFree(&(*ctx)->field_labels[i]); CeedChk(ierr); 914cdf32b93SJeremy L Thompson } 9153668ca4bSJeremy L Thompson ierr = CeedFree(&(*ctx)->field_labels); CeedChk(ierr); 916777ff853SJeremy L Thompson ierr = CeedDestroy(&(*ctx)->ceed); CeedChk(ierr); 917777ff853SJeremy L Thompson ierr = CeedFree(ctx); CeedChk(ierr); 918cdf32b93SJeremy L Thompson 919e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 920777ff853SJeremy L Thompson } 921777ff853SJeremy L Thompson 922777ff853SJeremy L Thompson /// @} 923