1 // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2 // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3 // reserved. See files LICENSE and NOTICE for details. 4 // 5 // This file is part of CEED, a collection of benchmarks, miniapps, software 6 // libraries and APIs for efficient high-order finite element and spectral 7 // element discretizations for exascale applications. For more information and 8 // source code availability see http://github.com/ceed. 9 // 10 // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11 // a collaborative effort of two U.S. Department of Energy organizations (Office 12 // of Science and the National Nuclear Security Administration) responsible for 13 // the planning and preparation of a capable exascale ecosystem, including 14 // software, applications, hardware, advanced system engineering and early 15 // testbed platforms, in support of the nation's exascale computing imperative. 16 17 #include <ceed/ceed.h> 18 #include <ceed/backend.h> 19 #include <ceed-impl.h> 20 #include <stdint.h> 21 #include <stdio.h> 22 #include <string.h> 23 24 /// @file 25 /// Implementation of public CeedQFunctionContext interfaces 26 27 /// ---------------------------------------------------------------------------- 28 /// CeedQFunctionContext Library Internal Functions 29 /// ---------------------------------------------------------------------------- 30 /// @addtogroup CeedQFunctionDeveloper 31 /// @{ 32 33 /** 34 @brief Get index for QFunctionContext field 35 36 @param ctx CeedQFunctionContext 37 @param field_name Name of field 38 @param field_index Index of field, or -1 if field is not registered 39 40 @return An error code: 0 - success, otherwise - failure 41 42 @ref Developer 43 **/ 44 int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx, 45 const char *field_name, CeedInt *field_index) { 46 *field_index = -1; 47 for (CeedInt i=0; i<ctx->num_fields; i++) 48 if (!strcmp(ctx->field_labels[i]->name, field_name)) 49 *field_index = i; 50 return CEED_ERROR_SUCCESS; 51 } 52 53 /** 54 @brief Common function for registering QFunctionContext fields 55 56 @param ctx CeedQFunctionContext 57 @param field_name Name of field to register 58 @param field_offset Offset of field to register 59 @param field_description Description of field, or NULL for none 60 @param field_type Field data type, such as double or int32 61 @param field_size Size of field, in bytes 62 63 @return An error code: 0 - success, otherwise - failure 64 65 @ref Developer 66 **/ 67 int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx, 68 const char *field_name, size_t field_offset, 69 const char *field_description, 70 CeedContextFieldType field_type, 71 size_t field_size) { 72 int ierr; 73 74 // Check for duplicate 75 CeedInt field_index = -1; 76 ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index); 77 CeedChk(ierr); 78 if (field_index != -1) 79 // LCOV_EXCL_START 80 return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 81 "QFunctionContext field with name \"%s\" already registered", 82 field_name); 83 // LCOV_EXCL_STOP 84 85 // Allocate space for field data 86 if (ctx->num_fields == 0) { 87 ierr = CeedCalloc(1, &ctx->field_labels); CeedChk(ierr); 88 ctx->max_fields = 1; 89 } else if (ctx->num_fields == ctx->max_fields) { 90 ierr = CeedRealloc(2*ctx->max_fields, &ctx->field_labels); 91 CeedChk(ierr); 92 ctx->max_fields *= 2; 93 } 94 ierr = CeedCalloc(1, &ctx->field_labels[ctx->num_fields]); CeedChk(ierr); 95 96 // Copy field data 97 ierr = CeedStringAllocCopy(field_name, 98 (char **)&ctx->field_labels[ctx->num_fields]->name); 99 CeedChk(ierr); 100 ierr = CeedStringAllocCopy(field_description, 101 (char **)&ctx->field_labels[ctx->num_fields]->description); 102 CeedChk(ierr); 103 ctx->field_labels[ctx->num_fields]->type = field_type; 104 ctx->field_labels[ctx->num_fields]->offset = field_offset; 105 ctx->field_labels[ctx->num_fields]->size = field_size; 106 ctx->num_fields++; 107 return CEED_ERROR_SUCCESS; 108 } 109 110 /// @} 111 112 /// ---------------------------------------------------------------------------- 113 /// CeedQFunctionContext Backend API 114 /// ---------------------------------------------------------------------------- 115 /// @addtogroup CeedQFunctionBackend 116 /// @{ 117 118 /** 119 @brief Get the Ceed associated with a CeedQFunctionContext 120 121 @param ctx CeedQFunctionContext 122 @param[out] ceed Variable to store Ceed 123 124 @return An error code: 0 - success, otherwise - failure 125 126 @ref Backend 127 **/ 128 int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) { 129 *ceed = ctx->ceed; 130 return CEED_ERROR_SUCCESS; 131 } 132 133 /** 134 @brief Check for valid data in a CeedQFunctionContext 135 136 @param ctx CeedQFunctionContext to check validity 137 @param[out] has_valid_data Variable to store validity 138 139 @return An error code: 0 - success, otherwise - failure 140 141 @ref Backend 142 **/ 143 int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx, 144 bool *has_valid_data) { 145 int ierr; 146 147 if (!ctx->HasValidData) 148 // LCOV_EXCL_START 149 return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 150 "Backend does not support HasValidData"); 151 // LCOV_EXCL_STOP 152 153 ierr = ctx->HasValidData(ctx, has_valid_data); CeedChk(ierr); 154 155 return CEED_ERROR_SUCCESS; 156 } 157 158 /** 159 @brief Check for borrowed data of a specific CeedMemType in a 160 CeedQFunctionContext 161 162 @param ctx CeedQFunctionContext to check 163 @param mem_type Memory type to check 164 @param[out] has_borrowed_data_of_type Variable to store result 165 166 @return An error code: 0 - success, otherwise - failure 167 168 @ref Backend 169 **/ 170 int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx, 171 CeedMemType mem_type, bool *has_borrowed_data_of_type) { 172 int ierr; 173 174 if (!ctx->HasBorrowedDataOfType) 175 // LCOV_EXCL_START 176 return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 177 "Backend does not support HasBorrowedDataOfType"); 178 // LCOV_EXCL_STOP 179 180 ierr = ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type); 181 CeedChk(ierr); 182 183 return CEED_ERROR_SUCCESS; 184 } 185 186 /** 187 @brief Get the state of a CeedQFunctionContext 188 189 @param ctx CeedQFunctionContext to retrieve state 190 @param[out] state Variable to store state 191 192 @return An error code: 0 - success, otherwise - failure 193 194 @ref Backend 195 **/ 196 int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) { 197 *state = ctx->state; 198 return CEED_ERROR_SUCCESS; 199 } 200 201 /** 202 @brief Get backend data of a CeedQFunctionContext 203 204 @param ctx CeedQFunctionContext 205 @param[out] data Variable to store data 206 207 @return An error code: 0 - success, otherwise - failure 208 209 @ref Backend 210 **/ 211 int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) { 212 *(void **)data = ctx->data; 213 return CEED_ERROR_SUCCESS; 214 } 215 216 /** 217 @brief Set backend data of a CeedQFunctionContext 218 219 @param[out] ctx CeedQFunctionContext 220 @param data Data to set 221 222 @return An error code: 0 - success, otherwise - failure 223 224 @ref Backend 225 **/ 226 int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) { 227 ctx->data = data; 228 return CEED_ERROR_SUCCESS; 229 } 230 231 /** 232 @brief Set QFunctionContext field 233 234 @param ctx CeedQFunctionContext 235 @param field_label Label of field to set 236 @param field_type Type of field to set 237 @param value Value to set 238 239 @return An error code: 0 - success, otherwise - failure 240 241 @ref User 242 **/ 243 int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx, 244 CeedContextFieldLabel field_label, 245 CeedContextFieldType field_type, 246 void *value) { 247 int ierr; 248 249 // Check field type 250 if (field_label->type != field_type) 251 // LCOV_EXCL_START 252 return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 253 "QFunctionContext field with name \"%s\" registered as %s, " 254 "not registered as %s", field_label->name, 255 CeedContextFieldTypes[field_label->type], 256 CeedContextFieldTypes[field_type]); 257 // LCOV_EXCL_STOP 258 259 char *data; 260 ierr = CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data); CeedChk(ierr); 261 memcpy(&data[field_label->offset], value, field_label->size); 262 ierr = CeedQFunctionContextRestoreData(ctx, &data); CeedChk(ierr); 263 264 return CEED_ERROR_SUCCESS; 265 } 266 267 /** 268 @brief Increment the reference counter for a CeedQFunctionContext 269 270 @param ctx CeedQFunctionContext to increment the reference counter 271 272 @return An error code: 0 - success, otherwise - failure 273 274 @ref Backend 275 **/ 276 int CeedQFunctionContextReference(CeedQFunctionContext ctx) { 277 ctx->ref_count++; 278 return CEED_ERROR_SUCCESS; 279 } 280 281 /// @} 282 283 /// ---------------------------------------------------------------------------- 284 /// CeedQFunctionContext Public API 285 /// ---------------------------------------------------------------------------- 286 /// @addtogroup CeedQFunctionUser 287 /// @{ 288 289 /** 290 @brief Create a CeedQFunctionContext for storing CeedQFunction user context data 291 292 @param ceed A Ceed object where the CeedQFunctionContext will be created 293 @param[out] ctx Address of the variable where the newly created 294 CeedQFunctionContext will be stored 295 296 @return An error code: 0 - success, otherwise - failure 297 298 @ref User 299 **/ 300 int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) { 301 int ierr; 302 303 if (!ceed->QFunctionContextCreate) { 304 Ceed delegate; 305 ierr = CeedGetObjectDelegate(ceed, &delegate, "Context"); CeedChk(ierr); 306 307 if (!delegate) 308 // LCOV_EXCL_START 309 return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 310 "Backend does not support ContextCreate"); 311 // LCOV_EXCL_STOP 312 313 ierr = CeedQFunctionContextCreate(delegate, ctx); CeedChk(ierr); 314 return CEED_ERROR_SUCCESS; 315 } 316 317 ierr = CeedCalloc(1, ctx); CeedChk(ierr); 318 (*ctx)->ceed = ceed; 319 ierr = CeedReference(ceed); CeedChk(ierr); 320 (*ctx)->ref_count = 1; 321 ierr = ceed->QFunctionContextCreate(*ctx); CeedChk(ierr); 322 return CEED_ERROR_SUCCESS; 323 } 324 325 /** 326 @brief Copy the pointer to a CeedQFunctionContext. Both pointers should 327 be destroyed with `CeedQFunctionContextDestroy()`; 328 Note: If `*ctx_copy` is non-NULL, then it is assumed that 329 `*ctx_copy` is a pointer to a CeedQFunctionContext. This 330 CeedQFunctionContext will be destroyed if `*ctx_copy` is the 331 only reference to this CeedQFunctionContext. 332 333 @param ctx CeedQFunctionContext to copy reference to 334 @param[out] ctx_copy Variable to store copied reference 335 336 @return An error code: 0 - success, otherwise - failure 337 338 @ref User 339 **/ 340 int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, 341 CeedQFunctionContext *ctx_copy) { 342 int ierr; 343 344 ierr = CeedQFunctionContextReference(ctx); CeedChk(ierr); 345 ierr = CeedQFunctionContextDestroy(ctx_copy); CeedChk(ierr); 346 *ctx_copy = ctx; 347 return CEED_ERROR_SUCCESS; 348 } 349 350 /** 351 @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated 352 data if applicable. The backend may copy values to a different 353 memtype, such as during @ref CeedQFunctionApply(). 354 See also @ref CeedQFunctionContextTakeData(). 355 356 @param ctx CeedQFunctionContext 357 @param mem_type Memory type of the data being passed 358 @param copy_mode Copy mode for the data 359 @param size Size of data, in bytes 360 @param data Data to be used 361 362 @return An error code: 0 - success, otherwise - failure 363 364 @ref User 365 **/ 366 int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, 367 CeedCopyMode copy_mode, 368 size_t size, void *data) { 369 int ierr; 370 371 if (!ctx->SetData) 372 // LCOV_EXCL_START 373 return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 374 "Backend does not support ContextSetData"); 375 // LCOV_EXCL_STOP 376 377 if (ctx->state % 2 == 1) 378 // LCOV_EXCL_START 379 return CeedError(ctx->ceed, 1, 380 "Cannot grant CeedQFunctionContext data access, the " 381 "access lock is already in use"); 382 // LCOV_EXCL_STOP 383 384 ctx->ctx_size = size; 385 ierr = ctx->SetData(ctx, mem_type, copy_mode, data); CeedChk(ierr); 386 ctx->state += 2; 387 return CEED_ERROR_SUCCESS; 388 } 389 390 /** 391 @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type. 392 The caller is responsible for managing and freeing the memory. 393 394 @param ctx CeedQFunctionContext to access 395 @param mem_type Memory type on which to access the data. If the backend 396 uses a different memory type, this will perform a copy. 397 @param[out] data Data on memory type mem_type 398 399 @return An error code: 0 - success, otherwise - failure 400 401 @ref User 402 **/ 403 int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, 404 void *data) { 405 int ierr; 406 407 bool has_valid_data = true; 408 ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr); 409 if (!has_valid_data) 410 // LCOV_EXCL_START 411 return CeedError(ctx->ceed, CEED_ERROR_BACKEND, 412 "CeedQFunctionContext has no valid data to take, must set data"); 413 // LCOV_EXCL_STOP 414 415 if (!ctx->TakeData) 416 // LCOV_EXCL_START 417 return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 418 "Backend does not support TakeData"); 419 // LCOV_EXCL_STOP 420 421 if (ctx->state % 2 == 1) 422 // LCOV_EXCL_START 423 return CeedError(ctx->ceed, 1, 424 "Cannot grant CeedQFunctionContext data access, the " 425 "access lock is already in use"); 426 // LCOV_EXCL_STOP 427 428 bool has_borrowed_data_of_type = true; 429 ierr = CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, 430 &has_borrowed_data_of_type); CeedChk(ierr); 431 if (!has_borrowed_data_of_type) 432 // LCOV_EXCL_START 433 return CeedError(ctx->ceed, CEED_ERROR_BACKEND, 434 "CeedQFunctionContext has no borowed %s data, " 435 "must set data with CeedQFunctionContextSetData", 436 CeedMemTypes[mem_type]); 437 // LCOV_EXCL_STOP 438 439 void *temp_data = NULL; 440 ierr = ctx->TakeData(ctx, mem_type, &temp_data); CeedChk(ierr); 441 if (data) (*(void **)data) = temp_data; 442 return CEED_ERROR_SUCCESS; 443 } 444 445 /** 446 @brief Get read/write access to a CeedQFunctionContext via the specified memory type. 447 Restore access with @ref CeedQFunctionContextRestoreData(). 448 449 @param ctx CeedQFunctionContext to access 450 @param mem_type Memory type on which to access the data. If the backend 451 uses a different memory type, this will perform a copy. 452 @param[out] data Data on memory type mem_type 453 454 @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions 455 provide access to array pointers in the desired memory space. Pairing 456 get/restore allows the Context to track access. 457 458 @return An error code: 0 - success, otherwise - failure 459 460 @ref User 461 **/ 462 int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, 463 void *data) { 464 int ierr; 465 466 if (!ctx->GetData) 467 // LCOV_EXCL_START 468 return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 469 "Backend does not support GetData"); 470 // LCOV_EXCL_STOP 471 472 if (ctx->state % 2 == 1) 473 // LCOV_EXCL_START 474 return CeedError(ctx->ceed, 1, 475 "Cannot grant CeedQFunctionContext data access, the " 476 "access lock is already in use"); 477 // LCOV_EXCL_STOP 478 479 bool has_valid_data = true; 480 ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr); 481 if (!has_valid_data) 482 // LCOV_EXCL_START 483 return CeedError(ctx->ceed, CEED_ERROR_BACKEND, 484 "CeedQFunctionContext has no valid data to get, must set data"); 485 // LCOV_EXCL_STOP 486 487 ierr = ctx->GetData(ctx, mem_type, data); CeedChk(ierr); 488 ctx->state += 1; 489 return CEED_ERROR_SUCCESS; 490 } 491 492 /** 493 @brief Restore data obtained using @ref CeedQFunctionContextGetData() 494 495 @param ctx CeedQFunctionContext to restore 496 @param data Data to restore 497 498 @return An error code: 0 - success, otherwise - failure 499 500 @ref User 501 **/ 502 int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) { 503 int ierr; 504 505 if (ctx->state % 2 != 1) 506 // LCOV_EXCL_START 507 return CeedError(ctx->ceed, 1, 508 "Cannot restore CeedQFunctionContext array access, " 509 "access was not granted"); 510 // LCOV_EXCL_STOP 511 512 if (ctx->RestoreData) { 513 ierr = ctx->RestoreData(ctx); CeedChk(ierr); 514 } 515 *(void **)data = NULL; 516 ctx->state += 1; 517 return CEED_ERROR_SUCCESS; 518 } 519 520 /** 521 @brief Register QFunctionContext a field holding a double precision value 522 523 @param ctx CeedQFunctionContext 524 @param field_name Name of field to register 525 @param field_offset Offset of field to register 526 @param field_description Description of field, or NULL for none 527 528 @return An error code: 0 - success, otherwise - failure 529 530 @ref User 531 **/ 532 int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, 533 const char *field_name, size_t field_offset, 534 const char *field_description) { 535 return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, 536 field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double)); 537 } 538 539 /** 540 @brief Register QFunctionContext a field holding a int32 value 541 542 @param ctx CeedQFunctionContext 543 @param field_name Name of field to register 544 @param field_offset Offset of field to register 545 @param field_description Description of field, or NULL for none 546 547 @return An error code: 0 - success, otherwise - failure 548 549 @ref User 550 **/ 551 int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, 552 const char *field_name, size_t field_offset, 553 const char *field_description) { 554 return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, 555 field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int)); 556 } 557 558 /** 559 @brief Get labels for all registered QFunctionContext fields 560 561 @param ctx CeedQFunctionContext 562 @param[out] field_labels Variable to hold array of field labels 563 @param[out] num_fields Length of field descriptions array 564 565 @return An error code: 0 - success, otherwise - failure 566 567 @ref User 568 **/ 569 int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, 570 const CeedContextFieldLabel **field_labels, CeedInt *num_fields) { 571 *field_labels = ctx->field_labels; 572 *num_fields = ctx->num_fields; 573 return CEED_ERROR_SUCCESS; 574 } 575 576 /** 577 @brief Get label for a registered QFunctionContext field, or `NULL` if no 578 field has been registered with this `field_name` 579 580 @param[in] ctx CeedQFunctionContext 581 @param[in] field_name Name of field to retrieve label 582 @param[out] field_label Variable to field label 583 584 @return An error code: 0 - success, otherwise - failure 585 586 @ref User 587 **/ 588 int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx, 589 const char *field_name, CeedContextFieldLabel *field_label) { 590 int ierr; 591 592 CeedInt field_index; 593 ierr = CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index); 594 CeedChk(ierr); 595 596 if (field_index != -1) { 597 *field_label = ctx->field_labels[field_index]; 598 } else { 599 *field_label = NULL; 600 } 601 602 return CEED_ERROR_SUCCESS; 603 } 604 605 /** 606 @brief Set QFunctionContext field holding a double precision value 607 608 @param ctx CeedQFunctionContext 609 @param field_label Label for field to register 610 @param value Value to set 611 612 @return An error code: 0 - success, otherwise - failure 613 614 @ref User 615 **/ 616 int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, 617 CeedContextFieldLabel field_label, double value) { 618 int ierr; 619 620 if (!field_label) 621 // LCOV_EXCL_START 622 return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 623 "Invalid field label"); 624 // LCOV_EXCL_STOP 625 626 ierr = CeedQFunctionContextSetGeneric(ctx, field_label, 627 CEED_CONTEXT_FIELD_DOUBLE, 628 &value); CeedChk(ierr); 629 630 return CEED_ERROR_SUCCESS; 631 } 632 633 /** 634 @brief Set QFunctionContext field holding an int32 value 635 636 @param ctx CeedQFunctionContext 637 @param field_label Label for field to register 638 @param value Value to set 639 640 @return An error code: 0 - success, otherwise - failure 641 642 @ref User 643 **/ 644 int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, 645 CeedContextFieldLabel field_label, int value) { 646 int ierr; 647 648 if (!field_label) 649 // LCOV_EXCL_START 650 return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, 651 "Invalid field label"); 652 // LCOV_EXCL_STOP 653 654 ierr = CeedQFunctionContextSetGeneric(ctx, field_label, 655 CEED_CONTEXT_FIELD_INT32, 656 &value); CeedChk(ierr); 657 658 return CEED_ERROR_SUCCESS; 659 } 660 661 /** 662 @brief Get data size for a Context 663 664 @param ctx CeedQFunctionContext 665 @param[out] ctx_size Variable to store size of context data values 666 667 @return An error code: 0 - success, otherwise - failure 668 669 @ref User 670 **/ 671 int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, 672 size_t *ctx_size) { 673 *ctx_size = ctx->ctx_size; 674 return CEED_ERROR_SUCCESS; 675 } 676 677 678 /** 679 @brief View a CeedQFunctionContext 680 681 @param[in] ctx CeedQFunctionContext to view 682 @param[in] stream Filestream to write to 683 684 @return An error code: 0 - success, otherwise - failure 685 686 @ref User 687 **/ 688 int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) { 689 fprintf(stream, "CeedQFunctionContext\n"); 690 fprintf(stream, " Context Data Size: %ld\n", ctx->ctx_size); 691 for (CeedInt i = 0; i < ctx->num_fields; i++) { 692 // LCOV_EXCL_START 693 fprintf(stream, " Labeled %s field: %s\n", 694 CeedContextFieldTypes[ctx->field_labels[i]->type], 695 ctx->field_labels[i]->name); 696 // LCOV_EXCL_STOP 697 } 698 return CEED_ERROR_SUCCESS; 699 } 700 701 /** 702 @brief Destroy a CeedQFunctionContext 703 704 @param ctx CeedQFunctionContext to destroy 705 706 @return An error code: 0 - success, otherwise - failure 707 708 @ref User 709 **/ 710 int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) { 711 int ierr; 712 713 if (!*ctx || --(*ctx)->ref_count > 0) 714 return CEED_ERROR_SUCCESS; 715 716 if ((*ctx) && ((*ctx)->state % 2) == 1) 717 // LCOV_EXCL_START 718 return CeedError((*ctx)->ceed, 1, 719 "Cannot destroy CeedQFunctionContext, the access " 720 "lock is in use"); 721 // LCOV_EXCL_STOP 722 723 if ((*ctx)->Destroy) { 724 ierr = (*ctx)->Destroy(*ctx); CeedChk(ierr); 725 } 726 for (CeedInt i=0; i<(*ctx)->num_fields; i++) { 727 ierr = CeedFree(&(*ctx)->field_labels[i]->name); CeedChk(ierr); 728 ierr = CeedFree(&(*ctx)->field_labels[i]->description); CeedChk(ierr); 729 ierr = CeedFree(&(*ctx)->field_labels[i]); CeedChk(ierr); 730 } 731 ierr = CeedFree(&(*ctx)->field_labels); CeedChk(ierr); 732 ierr = CeedDestroy(&(*ctx)->ceed); CeedChk(ierr); 733 ierr = CeedFree(ctx); CeedChk(ierr); 734 735 return CEED_ERROR_SUCCESS; 736 } 737 738 /// @} 739