1777ff853SJeremy L Thompson // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2777ff853SJeremy L Thompson // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3777ff853SJeremy L Thompson // reserved. See files LICENSE and NOTICE for details. 4777ff853SJeremy L Thompson // 5777ff853SJeremy L Thompson // This file is part of CEED, a collection of benchmarks, miniapps, software 6777ff853SJeremy L Thompson // libraries and APIs for efficient high-order finite element and spectral 7777ff853SJeremy L Thompson // element discretizations for exascale applications. For more information and 8777ff853SJeremy L Thompson // source code availability see http://github.com/ceed. 9777ff853SJeremy L Thompson // 10777ff853SJeremy L Thompson // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11777ff853SJeremy L Thompson // a collaborative effort of two U.S. Department of Energy organizations (Office 12777ff853SJeremy L Thompson // of Science and the National Nuclear Security Administration) responsible for 13777ff853SJeremy L Thompson // the planning and preparation of a capable exascale ecosystem, including 14777ff853SJeremy L Thompson // software, applications, hardware, advanced system engineering and early 15777ff853SJeremy L Thompson // testbed platforms, in support of the nation's exascale computing imperative. 16777ff853SJeremy L Thompson 17ec3da8bcSJed Brown #include <ceed/ceed.h> 18ec3da8bcSJed Brown #include <ceed/backend.h> 193d576824SJeremy L Thompson #include <ceed-impl.h> 203d576824SJeremy L Thompson #include <stdint.h> 213d576824SJeremy L Thompson #include <stdio.h> 22cdf32b93SJeremy L Thompson #include <string.h> 23777ff853SJeremy L Thompson 24777ff853SJeremy L Thompson /// @file 25777ff853SJeremy L Thompson /// Implementation of public CeedQFunctionContext interfaces 26777ff853SJeremy L Thompson 27777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 28cdf32b93SJeremy L Thompson /// CeedQFunctionContext Library Internal Functions 29cdf32b93SJeremy L Thompson /// ---------------------------------------------------------------------------- 30cdf32b93SJeremy L Thompson /// @addtogroup CeedQFunctionDeveloper 31cdf32b93SJeremy L Thompson /// @{ 32cdf32b93SJeremy L Thompson 33cdf32b93SJeremy L Thompson /** 34cdf32b93SJeremy L Thompson @brief Get index for QFunctionContext field 35cdf32b93SJeremy L Thompson 36cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 37cdf32b93SJeremy L Thompson @param field_name Name of field 38cdf32b93SJeremy L Thompson @param field_index Index of field, or -1 if field is not registered 39cdf32b93SJeremy L Thompson 40cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 41cdf32b93SJeremy L Thompson 42cdf32b93SJeremy L Thompson @ref Developer 43cdf32b93SJeremy L Thompson **/ 44cdf32b93SJeremy L Thompson int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx, 45cdf32b93SJeremy L Thompson const char *field_name, CeedInt *field_index) { 46cdf32b93SJeremy L Thompson *field_index = -1; 47cdf32b93SJeremy L Thompson for (CeedInt i=0; i<ctx->num_fields; i++) 48cdf32b93SJeremy L Thompson if (!strcmp(ctx->field_descriptions[i].name, field_name)) 49cdf32b93SJeremy L Thompson *field_index = i; 50cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 51cdf32b93SJeremy L Thompson } 52cdf32b93SJeremy L Thompson 53cdf32b93SJeremy L Thompson /** 54cdf32b93SJeremy L Thompson @brief Common function for registering QFunctionContext fields 55cdf32b93SJeremy L Thompson 56cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 57cdf32b93SJeremy L Thompson @param field_name Name of field to register 58cdf32b93SJeremy L Thompson @param field_offset Offset of field to register 59cdf32b93SJeremy L Thompson @param field_description Description of field, or NULL for none 60cdf32b93SJeremy L Thompson @param field_type Field data type, such as double or int32 61cdf32b93SJeremy L Thompson @param field_size Size of field, in bytes 62cdf32b93SJeremy L Thompson 63cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 64cdf32b93SJeremy L Thompson 65cdf32b93SJeremy L Thompson @ref Developer 66cdf32b93SJeremy L Thompson **/ 67cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx, 68cdf32b93SJeremy L Thompson const char *field_name, size_t field_offset, 69cdf32b93SJeremy L Thompson const char *field_description, 70cdf32b93SJeremy L Thompson CeedContextFieldType field_type, 71cdf32b93SJeremy L Thompson size_t field_size) { 72cdf32b93SJeremy L Thompson int ierr; 73cdf32b93SJeremy L Thompson 74cdf32b93SJeremy L Thompson // Check for duplicate 75cdf32b93SJeremy L Thompson CeedInt field_index = -1; 76cdf32b93SJeremy L Thompson ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index); 77cdf32b93SJeremy L Thompson CeedChk(ierr); 78cdf32b93SJeremy L Thompson if (field_index != -1) 79cdf32b93SJeremy L Thompson // LCOV_EXCL_START 80cdf32b93SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 81cdf32b93SJeremy L Thompson "QFunctionContext field with name \"%s\" already registered", 82cdf32b93SJeremy L Thompson field_name); 83cdf32b93SJeremy L Thompson // LCOV_EXCL_STOP 84cdf32b93SJeremy L Thompson 85cdf32b93SJeremy L Thompson // Allocate space for field data 86cdf32b93SJeremy L Thompson if (ctx->num_fields == 0) { 87cdf32b93SJeremy L Thompson ierr = CeedCalloc(1, &ctx->field_descriptions); CeedChk(ierr); 88cdf32b93SJeremy L Thompson ctx->max_fields = 1; 89cdf32b93SJeremy L Thompson } else if (ctx->num_fields == ctx->max_fields) { 90cdf32b93SJeremy L Thompson ierr = CeedRealloc(2*ctx->max_fields, &ctx->field_descriptions); 91cdf32b93SJeremy L Thompson CeedChk(ierr); 92cdf32b93SJeremy L Thompson ctx->max_fields *= 2; 93cdf32b93SJeremy L Thompson } 94cdf32b93SJeremy L Thompson 95cdf32b93SJeremy L Thompson // Copy field data 96*f7e22acaSJeremy L Thompson ierr = CeedStringAllocCopy(field_name, 97*f7e22acaSJeremy L Thompson (char **)&ctx->field_descriptions[ctx->num_fields].name); 98*f7e22acaSJeremy L Thompson CeedChk(ierr); 99*f7e22acaSJeremy L Thompson ierr = CeedStringAllocCopy(field_description, 100*f7e22acaSJeremy L Thompson (char **)&ctx->field_descriptions[ctx->num_fields].description); 101*f7e22acaSJeremy L Thompson CeedChk(ierr); 102cdf32b93SJeremy L Thompson ctx->field_descriptions[ctx->num_fields].type = field_type; 103cdf32b93SJeremy L Thompson ctx->field_descriptions[ctx->num_fields].offset = field_offset; 104cdf32b93SJeremy L Thompson ctx->field_descriptions[ctx->num_fields].size = field_size; 105cdf32b93SJeremy L Thompson ctx->num_fields++; 106cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 107cdf32b93SJeremy L Thompson } 108cdf32b93SJeremy L Thompson 109cdf32b93SJeremy L Thompson /** 110cdf32b93SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value 111cdf32b93SJeremy L Thompson 112cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 113cdf32b93SJeremy L Thompson @param field_name Name of field to set 114cdf32b93SJeremy L Thompson @param field_type Type of field to set 115cdf32b93SJeremy L Thompson @param value Value to set 116cdf32b93SJeremy L Thompson 117cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 118cdf32b93SJeremy L Thompson 119cdf32b93SJeremy L Thompson @ref User 120cdf32b93SJeremy L Thompson **/ 121cdf32b93SJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx, 122cdf32b93SJeremy L Thompson const char *field_name, 123cdf32b93SJeremy L Thompson CeedContextFieldType field_type, void *value) { 124cdf32b93SJeremy L Thompson int ierr; 125cdf32b93SJeremy L Thompson 126cdf32b93SJeremy L Thompson // Check field index 127cdf32b93SJeremy L Thompson CeedInt field_index = -1; 128cdf32b93SJeremy L Thompson ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index); 129cdf32b93SJeremy L Thompson CeedChk(ierr); 130cdf32b93SJeremy L Thompson if (field_index == -1) 131cdf32b93SJeremy L Thompson // LCOV_EXCL_START 132cdf32b93SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 133cdf32b93SJeremy L Thompson "QFunctionContext field with name \"%s\" not registered", 134cdf32b93SJeremy L Thompson field_name); 135cdf32b93SJeremy L Thompson // LCOV_EXCL_STOP 136cdf32b93SJeremy L Thompson 137cdf32b93SJeremy L Thompson if (ctx->field_descriptions[field_index].type != field_type) 138cdf32b93SJeremy L Thompson // LCOV_EXCL_START 139cdf32b93SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 140cdf32b93SJeremy L Thompson "QFunctionContext field with name \"%s\" registered as %s, " 141cdf32b93SJeremy L Thompson "not registered as %s", field_name, 142cdf32b93SJeremy L Thompson CeedContextFieldTypes[ctx->field_descriptions[field_index].type], 143cdf32b93SJeremy L Thompson CeedContextFieldTypes[field_type]); 144cdf32b93SJeremy L Thompson // LCOV_EXCL_STOP 145cdf32b93SJeremy L Thompson 146cdf32b93SJeremy L Thompson char *data; 147cdf32b93SJeremy L Thompson ierr = CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data); CeedChk(ierr); 148cdf32b93SJeremy L Thompson memcpy(&data[ctx->field_descriptions[field_index].offset], value, 149cdf32b93SJeremy L Thompson ctx->field_descriptions[field_index].size); 150cdf32b93SJeremy L Thompson ierr = CeedQFunctionContextRestoreData(ctx, &data); CeedChk(ierr); 151cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 152cdf32b93SJeremy L Thompson } 153cdf32b93SJeremy L Thompson 154cdf32b93SJeremy L Thompson /// @} 155cdf32b93SJeremy L Thompson 156cdf32b93SJeremy L Thompson /// ---------------------------------------------------------------------------- 157777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API 158777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 159777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend 160777ff853SJeremy L Thompson /// @{ 161777ff853SJeremy L Thompson 162777ff853SJeremy L Thompson /** 163777ff853SJeremy L Thompson @brief Get the Ceed associated with a CeedQFunctionContext 164777ff853SJeremy L Thompson 165777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 166777ff853SJeremy L Thompson @param[out] ceed Variable to store Ceed 167777ff853SJeremy L Thompson 168777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 169777ff853SJeremy L Thompson 170777ff853SJeremy L Thompson @ref Backend 171777ff853SJeremy L Thompson **/ 172777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) { 173777ff853SJeremy L Thompson *ceed = ctx->ceed; 174e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 175777ff853SJeremy L Thompson } 176777ff853SJeremy L Thompson 177777ff853SJeremy L Thompson /** 1789c774eddSJeremy L Thompson @brief Check for valid data in a CeedQFunctionContext 1799c774eddSJeremy L Thompson 1809c774eddSJeremy L Thompson @param ctx CeedQFunctionContext to check validity 1819c774eddSJeremy L Thompson @param[out] has_valid_data Variable to store validity 1829c774eddSJeremy L Thompson 1839c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1849c774eddSJeremy L Thompson 1859c774eddSJeremy L Thompson @ref Backend 1869c774eddSJeremy L Thompson **/ 1879c774eddSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx, 1889c774eddSJeremy L Thompson bool *has_valid_data) { 1899c774eddSJeremy L Thompson int ierr; 1909c774eddSJeremy L Thompson 1919c774eddSJeremy L Thompson if (!ctx->HasValidData) 1929c774eddSJeremy L Thompson // LCOV_EXCL_START 1939c774eddSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 1949c774eddSJeremy L Thompson "Backend does not support HasValidData"); 1959c774eddSJeremy L Thompson // LCOV_EXCL_STOP 1969c774eddSJeremy L Thompson 1979c774eddSJeremy L Thompson ierr = ctx->HasValidData(ctx, has_valid_data); CeedChk(ierr); 1989c774eddSJeremy L Thompson 1999c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 2009c774eddSJeremy L Thompson } 2019c774eddSJeremy L Thompson 2029c774eddSJeremy L Thompson /** 2039c774eddSJeremy L Thompson @brief Check for borrowed data of a specific CeedMemType in a 2049c774eddSJeremy L Thompson CeedQFunctionContext 2059c774eddSJeremy L Thompson 2069c774eddSJeremy L Thompson @param ctx CeedQFunctionContext to check 2079c774eddSJeremy L Thompson @param mem_type Memory type to check 2089c774eddSJeremy L Thompson @param[out] has_borrowed_data_of_type Variable to store result 2099c774eddSJeremy L Thompson 2109c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2119c774eddSJeremy L Thompson 2129c774eddSJeremy L Thompson @ref Backend 2139c774eddSJeremy L Thompson **/ 2149c774eddSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx, 2159c774eddSJeremy L Thompson CeedMemType mem_type, bool *has_borrowed_data_of_type) { 2169c774eddSJeremy L Thompson int ierr; 2179c774eddSJeremy L Thompson 2189c774eddSJeremy L Thompson if (!ctx->HasBorrowedDataOfType) 2199c774eddSJeremy L Thompson // LCOV_EXCL_START 2209c774eddSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 2219c774eddSJeremy L Thompson "Backend does not support HasBorrowedDataOfType"); 2229c774eddSJeremy L Thompson // LCOV_EXCL_STOP 2239c774eddSJeremy L Thompson 2249c774eddSJeremy L Thompson ierr = ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type); 2259c774eddSJeremy L Thompson CeedChk(ierr); 2269c774eddSJeremy L Thompson 2279c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 2289c774eddSJeremy L Thompson } 2299c774eddSJeremy L Thompson 2309c774eddSJeremy L Thompson /** 231777ff853SJeremy L Thompson @brief Get the state of a CeedQFunctionContext 232777ff853SJeremy L Thompson 233777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to retrieve state 234777ff853SJeremy L Thompson @param[out] state Variable to store state 235777ff853SJeremy L Thompson 236777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 237777ff853SJeremy L Thompson 238777ff853SJeremy L Thompson @ref Backend 239777ff853SJeremy L Thompson **/ 240777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) { 241777ff853SJeremy L Thompson *state = ctx->state; 242e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 243777ff853SJeremy L Thompson } 244777ff853SJeremy L Thompson 245777ff853SJeremy L Thompson /** 246777ff853SJeremy L Thompson @brief Get backend data of a CeedQFunctionContext 247777ff853SJeremy L Thompson 248777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 249777ff853SJeremy L Thompson @param[out] data Variable to store data 250777ff853SJeremy L Thompson 251777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 252777ff853SJeremy L Thompson 253777ff853SJeremy L Thompson @ref Backend 254777ff853SJeremy L Thompson **/ 255777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) { 256777ff853SJeremy L Thompson *(void **)data = ctx->data; 257e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 258777ff853SJeremy L Thompson } 259777ff853SJeremy L Thompson 260777ff853SJeremy L Thompson /** 261777ff853SJeremy L Thompson @brief Set backend data of a CeedQFunctionContext 262777ff853SJeremy L Thompson 263777ff853SJeremy L Thompson @param[out] ctx CeedQFunctionContext 264777ff853SJeremy L Thompson @param data Data to set 265777ff853SJeremy L Thompson 266777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 267777ff853SJeremy L Thompson 268777ff853SJeremy L Thompson @ref Backend 269777ff853SJeremy L Thompson **/ 270777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) { 271777ff853SJeremy L Thompson ctx->data = data; 272e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 273777ff853SJeremy L Thompson } 274777ff853SJeremy L Thompson 27534359f16Sjeremylt /** 27634359f16Sjeremylt @brief Increment the reference counter for a CeedQFunctionContext 27734359f16Sjeremylt 27834359f16Sjeremylt @param ctx CeedQFunctionContext to increment the reference counter 27934359f16Sjeremylt 28034359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 28134359f16Sjeremylt 28234359f16Sjeremylt @ref Backend 28334359f16Sjeremylt **/ 2849560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) { 28534359f16Sjeremylt ctx->ref_count++; 28634359f16Sjeremylt return CEED_ERROR_SUCCESS; 28734359f16Sjeremylt } 28834359f16Sjeremylt 289777ff853SJeremy L Thompson /// @} 290777ff853SJeremy L Thompson 291777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 292777ff853SJeremy L Thompson /// CeedQFunctionContext Public API 293777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 294777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser 295777ff853SJeremy L Thompson /// @{ 296777ff853SJeremy L Thompson 297777ff853SJeremy L Thompson /** 298777ff853SJeremy L Thompson @brief Create a CeedQFunctionContext for storing CeedQFunction user context data 299777ff853SJeremy L Thompson 300777ff853SJeremy L Thompson @param ceed A Ceed object where the CeedQFunctionContext will be created 301777ff853SJeremy L Thompson @param[out] ctx Address of the variable where the newly created 302777ff853SJeremy L Thompson CeedQFunctionContext will be stored 303777ff853SJeremy L Thompson 304777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 305777ff853SJeremy L Thompson 306777ff853SJeremy L Thompson @ref User 307777ff853SJeremy L Thompson **/ 308777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) { 309777ff853SJeremy L Thompson int ierr; 310777ff853SJeremy L Thompson 311777ff853SJeremy L Thompson if (!ceed->QFunctionContextCreate) { 312777ff853SJeremy L Thompson Ceed delegate; 313777ff853SJeremy L Thompson ierr = CeedGetObjectDelegate(ceed, &delegate, "Context"); CeedChk(ierr); 314777ff853SJeremy L Thompson 315777ff853SJeremy L Thompson if (!delegate) 316777ff853SJeremy L Thompson // LCOV_EXCL_START 317e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 318e15f9bd0SJeremy L Thompson "Backend does not support ContextCreate"); 319777ff853SJeremy L Thompson // LCOV_EXCL_STOP 320777ff853SJeremy L Thompson 321777ff853SJeremy L Thompson ierr = CeedQFunctionContextCreate(delegate, ctx); CeedChk(ierr); 322e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 323777ff853SJeremy L Thompson } 324777ff853SJeremy L Thompson 325777ff853SJeremy L Thompson ierr = CeedCalloc(1, ctx); CeedChk(ierr); 326777ff853SJeremy L Thompson (*ctx)->ceed = ceed; 3279560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 328d1d35e2fSjeremylt (*ctx)->ref_count = 1; 329777ff853SJeremy L Thompson ierr = ceed->QFunctionContextCreate(*ctx); CeedChk(ierr); 330e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 331777ff853SJeremy L Thompson } 332777ff853SJeremy L Thompson 333777ff853SJeremy L Thompson /** 3349560d06aSjeremylt @brief Copy the pointer to a CeedQFunctionContext. Both pointers should 3359560d06aSjeremylt be destroyed with `CeedQFunctionContextDestroy()`; 3369560d06aSjeremylt Note: If `*ctx_copy` is non-NULL, then it is assumed that 3379560d06aSjeremylt `*ctx_copy` is a pointer to a CeedQFunctionContext. This 3389560d06aSjeremylt CeedQFunctionContext will be destroyed if `*ctx_copy` is the 3399560d06aSjeremylt only reference to this CeedQFunctionContext. 3409560d06aSjeremylt 3419560d06aSjeremylt @param ctx CeedQFunctionContext to copy reference to 3429560d06aSjeremylt @param[out] ctx_copy Variable to store copied reference 3439560d06aSjeremylt 3449560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 3459560d06aSjeremylt 3469560d06aSjeremylt @ref User 3479560d06aSjeremylt **/ 3489560d06aSjeremylt int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, 3499560d06aSjeremylt CeedQFunctionContext *ctx_copy) { 3509560d06aSjeremylt int ierr; 3519560d06aSjeremylt 3529560d06aSjeremylt ierr = CeedQFunctionContextReference(ctx); CeedChk(ierr); 3539560d06aSjeremylt ierr = CeedQFunctionContextDestroy(ctx_copy); CeedChk(ierr); 3549560d06aSjeremylt *ctx_copy = ctx; 3559560d06aSjeremylt return CEED_ERROR_SUCCESS; 3569560d06aSjeremylt } 3579560d06aSjeremylt 3589560d06aSjeremylt /** 359777ff853SJeremy L Thompson @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated 360777ff853SJeremy L Thompson data if applicable. The backend may copy values to a different 361777ff853SJeremy L Thompson memtype, such as during @ref CeedQFunctionApply(). 362777ff853SJeremy L Thompson See also @ref CeedQFunctionContextTakeData(). 363777ff853SJeremy L Thompson 364777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 365d1d35e2fSjeremylt @param mem_type Memory type of the data being passed 366d1d35e2fSjeremylt @param copy_mode Copy mode for the data 367891038deSjeremylt @param size Size of data, in bytes 368777ff853SJeremy L Thompson @param data Data to be used 369777ff853SJeremy L Thompson 370777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 371777ff853SJeremy L Thompson 372777ff853SJeremy L Thompson @ref User 373777ff853SJeremy L Thompson **/ 374d1d35e2fSjeremylt int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, 375d1d35e2fSjeremylt CeedCopyMode copy_mode, 376777ff853SJeremy L Thompson size_t size, void *data) { 377777ff853SJeremy L Thompson int ierr; 378777ff853SJeremy L Thompson 379777ff853SJeremy L Thompson if (!ctx->SetData) 380777ff853SJeremy L Thompson // LCOV_EXCL_START 381e15f9bd0SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 382e15f9bd0SJeremy L Thompson "Backend does not support ContextSetData"); 383777ff853SJeremy L Thompson // LCOV_EXCL_STOP 384777ff853SJeremy L Thompson 385777ff853SJeremy L Thompson if (ctx->state % 2 == 1) 386777ff853SJeremy L Thompson // LCOV_EXCL_START 387777ff853SJeremy L Thompson return CeedError(ctx->ceed, 1, 388777ff853SJeremy L Thompson "Cannot grant CeedQFunctionContext data access, the " 389777ff853SJeremy L Thompson "access lock is already in use"); 390777ff853SJeremy L Thompson // LCOV_EXCL_STOP 391777ff853SJeremy L Thompson 392d1d35e2fSjeremylt ctx->ctx_size = size; 393d1d35e2fSjeremylt ierr = ctx->SetData(ctx, mem_type, copy_mode, data); CeedChk(ierr); 394777ff853SJeremy L Thompson ctx->state += 2; 395e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 396777ff853SJeremy L Thompson } 397777ff853SJeremy L Thompson 398777ff853SJeremy L Thompson /** 399891038deSjeremylt @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type. 400891038deSjeremylt The caller is responsible for managing and freeing the memory. 401891038deSjeremylt 402891038deSjeremylt @param ctx CeedQFunctionContext to access 403891038deSjeremylt @param mem_type Memory type on which to access the data. If the backend 404891038deSjeremylt uses a different memory type, this will perform a copy. 405891038deSjeremylt @param[out] data Data on memory type mem_type 406891038deSjeremylt 407891038deSjeremylt @return An error code: 0 - success, otherwise - failure 408891038deSjeremylt 409891038deSjeremylt @ref User 410891038deSjeremylt **/ 411891038deSjeremylt int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, 412891038deSjeremylt void *data) { 413891038deSjeremylt int ierr; 414891038deSjeremylt 4159c774eddSJeremy L Thompson bool has_valid_data = true; 4169c774eddSJeremy L Thompson ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr); 4179c774eddSJeremy L Thompson if (!has_valid_data) 4189c774eddSJeremy L Thompson // LCOV_EXCL_START 4199c774eddSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, 4209c774eddSJeremy L Thompson "CeedQFunctionContext has no valid data to take, must set data"); 4219c774eddSJeremy L Thompson // LCOV_EXCL_STOP 4229c774eddSJeremy L Thompson 423891038deSjeremylt if (!ctx->TakeData) 424891038deSjeremylt // LCOV_EXCL_START 425891038deSjeremylt return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 426891038deSjeremylt "Backend does not support TakeData"); 427891038deSjeremylt // LCOV_EXCL_STOP 428891038deSjeremylt 429891038deSjeremylt if (ctx->state % 2 == 1) 430891038deSjeremylt // LCOV_EXCL_START 431891038deSjeremylt return CeedError(ctx->ceed, 1, 432891038deSjeremylt "Cannot grant CeedQFunctionContext data access, the " 433891038deSjeremylt "access lock is already in use"); 434891038deSjeremylt // LCOV_EXCL_STOP 435891038deSjeremylt 4369c774eddSJeremy L Thompson bool has_borrowed_data_of_type = true; 4379c774eddSJeremy L Thompson ierr = CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, 4389c774eddSJeremy L Thompson &has_borrowed_data_of_type); CeedChk(ierr); 4399c774eddSJeremy L Thompson if (!has_borrowed_data_of_type) 4409c774eddSJeremy L Thompson // LCOV_EXCL_START 4419c774eddSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, 4429c774eddSJeremy L Thompson "CeedQFunctionContext has no borowed %s data, " 4439c774eddSJeremy L Thompson "must set data with CeedQFunctionContextSetData", 4449c774eddSJeremy L Thompson CeedMemTypes[mem_type]); 4459c774eddSJeremy L Thompson // LCOV_EXCL_STOP 4469c774eddSJeremy L Thompson 447891038deSjeremylt void *temp_data = NULL; 448891038deSjeremylt ierr = ctx->TakeData(ctx, mem_type, &temp_data); CeedChk(ierr); 449891038deSjeremylt if (data) (*(void **)data) = temp_data; 450891038deSjeremylt return CEED_ERROR_SUCCESS; 451891038deSjeremylt } 452891038deSjeremylt 453891038deSjeremylt /** 454777ff853SJeremy L Thompson @brief Get read/write access to a CeedQFunctionContext via the specified memory type. 455777ff853SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 456777ff853SJeremy L Thompson 457777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to access 458d1d35e2fSjeremylt @param mem_type Memory type on which to access the data. If the backend 459777ff853SJeremy L Thompson uses a different memory type, this will perform a copy. 460d1d35e2fSjeremylt @param[out] data Data on memory type mem_type 461777ff853SJeremy L Thompson 462777ff853SJeremy L Thompson @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions 463777ff853SJeremy L Thompson provide access to array pointers in the desired memory space. Pairing 464777ff853SJeremy L Thompson get/restore allows the Context to track access. 465777ff853SJeremy L Thompson 466777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 467777ff853SJeremy L Thompson 468777ff853SJeremy L Thompson @ref User 469777ff853SJeremy L Thompson **/ 470d1d35e2fSjeremylt int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, 471777ff853SJeremy L Thompson void *data) { 472777ff853SJeremy L Thompson int ierr; 473777ff853SJeremy L Thompson 474777ff853SJeremy L Thompson if (!ctx->GetData) 475777ff853SJeremy L Thompson // LCOV_EXCL_START 476e15f9bd0SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 477e15f9bd0SJeremy L Thompson "Backend does not support GetData"); 478777ff853SJeremy L Thompson // LCOV_EXCL_STOP 479777ff853SJeremy L Thompson 480777ff853SJeremy L Thompson if (ctx->state % 2 == 1) 481777ff853SJeremy L Thompson // LCOV_EXCL_START 482777ff853SJeremy L Thompson return CeedError(ctx->ceed, 1, 483777ff853SJeremy L Thompson "Cannot grant CeedQFunctionContext data access, the " 484777ff853SJeremy L Thompson "access lock is already in use"); 485777ff853SJeremy L Thompson // LCOV_EXCL_STOP 486777ff853SJeremy L Thompson 4879c774eddSJeremy L Thompson bool has_valid_data = true; 4889c774eddSJeremy L Thompson ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr); 4899c774eddSJeremy L Thompson if (!has_valid_data) 4909c774eddSJeremy L Thompson // LCOV_EXCL_START 4919c774eddSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, 4929c774eddSJeremy L Thompson "CeedQFunctionContext has no valid data to get, must set data"); 4939c774eddSJeremy L Thompson // LCOV_EXCL_STOP 4949c774eddSJeremy L Thompson 495d1d35e2fSjeremylt ierr = ctx->GetData(ctx, mem_type, data); CeedChk(ierr); 496777ff853SJeremy L Thompson ctx->state += 1; 497e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 498777ff853SJeremy L Thompson } 499777ff853SJeremy L Thompson 500777ff853SJeremy L Thompson /** 501777ff853SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetData() 502777ff853SJeremy L Thompson 503777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to restore 504777ff853SJeremy L Thompson @param data Data to restore 505777ff853SJeremy L Thompson 506777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 507777ff853SJeremy L Thompson 508777ff853SJeremy L Thompson @ref User 509777ff853SJeremy L Thompson **/ 510777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) { 511777ff853SJeremy L Thompson int ierr; 512777ff853SJeremy L Thompson 513777ff853SJeremy L Thompson if (!ctx->RestoreData) 514777ff853SJeremy L Thompson // LCOV_EXCL_START 515e15f9bd0SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 516e15f9bd0SJeremy L Thompson "Backend does not support RestoreData"); 517777ff853SJeremy L Thompson // LCOV_EXCL_STOP 518777ff853SJeremy L Thompson 519777ff853SJeremy L Thompson if (ctx->state % 2 != 1) 520777ff853SJeremy L Thompson // LCOV_EXCL_START 521777ff853SJeremy L Thompson return CeedError(ctx->ceed, 1, 522777ff853SJeremy L Thompson "Cannot restore CeedQFunctionContext array access, " 523777ff853SJeremy L Thompson "access was not granted"); 524777ff853SJeremy L Thompson // LCOV_EXCL_STOP 525777ff853SJeremy L Thompson 526777ff853SJeremy L Thompson ierr = ctx->RestoreData(ctx); CeedChk(ierr); 527777ff853SJeremy L Thompson *(void **)data = NULL; 528777ff853SJeremy L Thompson ctx->state += 1; 529e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 530777ff853SJeremy L Thompson } 531777ff853SJeremy L Thompson 532777ff853SJeremy L Thompson /** 533cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a double precision value 534cdf32b93SJeremy L Thompson 535cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 536cdf32b93SJeremy L Thompson @param field_name Name of field to register 537cdf32b93SJeremy L Thompson @param field_offset Offset of field to register 538cdf32b93SJeremy L Thompson @param field_description Description of field, or NULL for none 539cdf32b93SJeremy L Thompson 540cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 541cdf32b93SJeremy L Thompson 542cdf32b93SJeremy L Thompson @ref User 543cdf32b93SJeremy L Thompson **/ 544cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, 545cdf32b93SJeremy L Thompson const char *field_name, size_t field_offset, 546cdf32b93SJeremy L Thompson const char *field_description) { 547cdf32b93SJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, 548cdf32b93SJeremy L Thompson field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double)); 549cdf32b93SJeremy L Thompson } 550cdf32b93SJeremy L Thompson 551cdf32b93SJeremy L Thompson /** 552cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a int32 value 553cdf32b93SJeremy L Thompson 554cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 555cdf32b93SJeremy L Thompson @param field_name Name of field to register 556cdf32b93SJeremy L Thompson @param field_offset Offset of field to register 557cdf32b93SJeremy L Thompson @param field_description Description of field, or NULL for none 558cdf32b93SJeremy L Thompson 559cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 560cdf32b93SJeremy L Thompson 561cdf32b93SJeremy L Thompson @ref User 562cdf32b93SJeremy L Thompson **/ 563cdf32b93SJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, 564cdf32b93SJeremy L Thompson const char *field_name, size_t field_offset, 565cdf32b93SJeremy L Thompson const char *field_description) { 566cdf32b93SJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, 567cdf32b93SJeremy L Thompson field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int)); 568cdf32b93SJeremy L Thompson } 569cdf32b93SJeremy L Thompson 570cdf32b93SJeremy L Thompson /** 571cdf32b93SJeremy L Thompson @brief Get descriptions for registered QFunctionContext fields 572cdf32b93SJeremy L Thompson 573cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 574cdf32b93SJeremy L Thompson @param[out] field_descriptions Variable to hold array of field descriptions 575cdf32b93SJeremy L Thompson @param[out] num_fields Length of field descriptions array 576cdf32b93SJeremy L Thompson 577cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 578cdf32b93SJeremy L Thompson 579cdf32b93SJeremy L Thompson @ref User 580cdf32b93SJeremy L Thompson **/ 581cdf32b93SJeremy L Thompson int CeedQFunctionContextGetFieldDescriptions(CeedQFunctionContext ctx, 582cdf32b93SJeremy L Thompson const CeedQFunctionContextFieldDescription **field_descriptions, 583cdf32b93SJeremy L Thompson CeedInt *num_fields) { 584cdf32b93SJeremy L Thompson *field_descriptions = ctx->field_descriptions; 585cdf32b93SJeremy L Thompson *num_fields = ctx->num_fields; 586cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 587cdf32b93SJeremy L Thompson } 588cdf32b93SJeremy L Thompson 589cdf32b93SJeremy L Thompson /** 590cdf32b93SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value 591cdf32b93SJeremy L Thompson 592cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 593cdf32b93SJeremy L Thompson @param field_name Name of field to register 594cdf32b93SJeremy L Thompson @param value Value to set 595cdf32b93SJeremy L Thompson 596cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 597cdf32b93SJeremy L Thompson 598cdf32b93SJeremy L Thompson @ref User 599cdf32b93SJeremy L Thompson **/ 600cdf32b93SJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, 601cdf32b93SJeremy L Thompson const char *field_name, double value) { 602cdf32b93SJeremy L Thompson return CeedQFunctionContextSetGeneric(ctx, field_name, 603cdf32b93SJeremy L Thompson CEED_CONTEXT_FIELD_DOUBLE, 604cdf32b93SJeremy L Thompson &value); 605cdf32b93SJeremy L Thompson } 606cdf32b93SJeremy L Thompson 607cdf32b93SJeremy L Thompson /** 608cdf32b93SJeremy L Thompson @brief Set QFunctionContext field holding a int32 value 609cdf32b93SJeremy L Thompson 610cdf32b93SJeremy L Thompson @param ctx CeedQFunctionContext 611cdf32b93SJeremy L Thompson @param field_name Name of field to set 612cdf32b93SJeremy L Thompson @param value Value to set 613cdf32b93SJeremy L Thompson 614cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 615cdf32b93SJeremy L Thompson 616cdf32b93SJeremy L Thompson @ref User 617cdf32b93SJeremy L Thompson **/ 618cdf32b93SJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, 619cdf32b93SJeremy L Thompson const char *field_name, int value) { 620cdf32b93SJeremy L Thompson return CeedQFunctionContextSetGeneric(ctx, field_name, CEED_CONTEXT_FIELD_INT32, 621cdf32b93SJeremy L Thompson &value); 622cdf32b93SJeremy L Thompson } 623cdf32b93SJeremy L Thompson 624cdf32b93SJeremy L Thompson /** 62580a9ef05SNatalie Beams @brief Get data size for a Context 62680a9ef05SNatalie Beams 62780a9ef05SNatalie Beams @param ctx CeedQFunctionContext 62880a9ef05SNatalie Beams @param[out] ctx_size Variable to store size of context data values 62980a9ef05SNatalie Beams 63080a9ef05SNatalie Beams @return An error code: 0 - success, otherwise - failure 63180a9ef05SNatalie Beams 63280a9ef05SNatalie Beams @ref User 63380a9ef05SNatalie Beams **/ 63480a9ef05SNatalie Beams int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, 63580a9ef05SNatalie Beams size_t *ctx_size) { 63680a9ef05SNatalie Beams *ctx_size = ctx->ctx_size; 63780a9ef05SNatalie Beams return CEED_ERROR_SUCCESS; 63880a9ef05SNatalie Beams } 63980a9ef05SNatalie Beams 64080a9ef05SNatalie Beams 64180a9ef05SNatalie Beams /** 642777ff853SJeremy L Thompson @brief View a CeedQFunctionContext 643777ff853SJeremy L Thompson 644777ff853SJeremy L Thompson @param[in] ctx CeedQFunctionContext to view 645777ff853SJeremy L Thompson @param[in] stream Filestream to write to 646777ff853SJeremy L Thompson 647777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 648777ff853SJeremy L Thompson 649777ff853SJeremy L Thompson @ref User 650777ff853SJeremy L Thompson **/ 651777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) { 652777ff853SJeremy L Thompson fprintf(stream, "CeedQFunctionContext\n"); 653d1d35e2fSjeremylt fprintf(stream, " Context Data Size: %ld\n", ctx->ctx_size); 654e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 655777ff853SJeremy L Thompson } 656777ff853SJeremy L Thompson 657777ff853SJeremy L Thompson /** 658777ff853SJeremy L Thompson @brief Destroy a CeedQFunctionContext 659777ff853SJeremy L Thompson 660777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to destroy 661777ff853SJeremy L Thompson 662777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 663777ff853SJeremy L Thompson 664777ff853SJeremy L Thompson @ref User 665777ff853SJeremy L Thompson **/ 666777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) { 667777ff853SJeremy L Thompson int ierr; 668777ff853SJeremy L Thompson 669d1d35e2fSjeremylt if (!*ctx || --(*ctx)->ref_count > 0) 670e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 671777ff853SJeremy L Thompson 672777ff853SJeremy L Thompson if ((*ctx) && ((*ctx)->state % 2) == 1) 673777ff853SJeremy L Thompson // LCOV_EXCL_START 674777ff853SJeremy L Thompson return CeedError((*ctx)->ceed, 1, 675777ff853SJeremy L Thompson "Cannot destroy CeedQFunctionContext, the access " 676777ff853SJeremy L Thompson "lock is in use"); 677777ff853SJeremy L Thompson // LCOV_EXCL_STOP 678777ff853SJeremy L Thompson 679777ff853SJeremy L Thompson if ((*ctx)->Destroy) { 680777ff853SJeremy L Thompson ierr = (*ctx)->Destroy(*ctx); CeedChk(ierr); 681777ff853SJeremy L Thompson } 682cdf32b93SJeremy L Thompson for (CeedInt i=0; i<(*ctx)->num_fields; i++) { 683cdf32b93SJeremy L Thompson ierr = CeedFree(&(*ctx)->field_descriptions[i].name); CeedChk(ierr); 684cdf32b93SJeremy L Thompson ierr = CeedFree(&(*ctx)->field_descriptions[i].description); CeedChk(ierr); 685cdf32b93SJeremy L Thompson } 686cdf32b93SJeremy L Thompson ierr = CeedFree(&(*ctx)->field_descriptions); CeedChk(ierr); 687777ff853SJeremy L Thompson ierr = CeedDestroy(&(*ctx)->ceed); CeedChk(ierr); 688777ff853SJeremy L Thompson ierr = CeedFree(ctx); CeedChk(ierr); 689cdf32b93SJeremy L Thompson 690e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 691777ff853SJeremy L Thompson } 692777ff853SJeremy L Thompson 693777ff853SJeremy L Thompson /// @} 694