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-impl.h> 18 #include <ceed-backend.h> 19 20 /// @file 21 /// Implementation of CeedElemRestriction interfaces 22 23 /// ---------------------------------------------------------------------------- 24 /// CeedElemRestriction Library Internal Functions 25 /// ---------------------------------------------------------------------------- 26 /// @addtogroup CeedElemRestrictionDeveloper 27 /// @{ 28 29 /** 30 @brief Permute and pad offsets for a blocked restriction 31 32 @param offsets Array of shape [@a nelem, @a elemsize]. Row i holds the 33 ordered list of the offsets (into the input CeedVector) 34 for the unknowns corresponding to element i, where 35 0 <= i < @a nelem. All offsets must be in the range 36 [0, @a lsize - 1]. 37 @param blkoffsets Array of permuted and padded offsets of 38 shape [@a nblk, @a elemsize, @a blksize]. 39 @param nblk Number of blocks 40 @param nelem Number of elements 41 @param blksize Number of elements in a block 42 @param elemsize Size of each element 43 44 @return An error code: 0 - success, otherwise - failure 45 46 @ref Utility 47 **/ 48 int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blkoffsets, 49 CeedInt nblk, CeedInt nelem, CeedInt blksize, 50 CeedInt elemsize) { 51 for (CeedInt e = 0; e < nblk*blksize; e+=blksize) 52 for (int j = 0; j < blksize; j++) 53 for (int k = 0; k < elemsize; k++) 54 blkoffsets[e*elemsize + k*blksize + j] 55 = offsets[CeedIntMin(e+j,nelem-1)*elemsize + k]; 56 return 0; 57 } 58 59 /// @} 60 61 /// ---------------------------------------------------------------------------- 62 /// CeedElemRestriction Backend API 63 /// ---------------------------------------------------------------------------- 64 /// @addtogroup CeedElemRestrictionBackend 65 /// @{ 66 67 /** 68 @brief Get the Ceed associated with a CeedElemRestriction 69 70 @param rstr CeedElemRestriction 71 @param[out] ceed Variable to store Ceed 72 73 @return An error code: 0 - success, otherwise - failure 74 75 @ref Backend 76 **/ 77 int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 78 *ceed = rstr->ceed; 79 return 0; 80 } 81 82 /** 83 84 @brief Get the strides of a strided CeedElemRestriction 85 86 @param rstr CeedElemRestriction 87 @param[out] strides Variable to store strides array 88 89 @return An error code: 0 - success, otherwise - failure 90 91 @ref Backend 92 **/ 93 int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, 94 CeedInt (*strides)[3]) { 95 if (!rstr->strides) 96 // LCOV_EXCL_START 97 return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data"); 98 // LCOV_EXCL_STOP 99 100 for (int i = 0; i<3; i++) 101 (*strides)[i] = rstr->strides[i]; 102 return 0; 103 } 104 105 /** 106 @brief Get read-only access to a CeedElemRestriction offsets array by memtype 107 108 @param rstr CeedElemRestriction to retrieve offsets 109 @param mtype Memory type on which to access the array. If the backend 110 uses a different memory type, this will perform a copy 111 (possibly cached). 112 @param[out] offsets Array on memory type mtype 113 114 @return An error code: 0 - success, otherwise - failure 115 116 @ref User 117 **/ 118 int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mtype, 119 const CeedInt **offsets) { 120 int ierr; 121 122 if (!rstr->GetOffsets) 123 // LCOV_EXCL_START 124 return CeedError(rstr->ceed, 1, "Backend does not support GetOffsets"); 125 // LCOV_EXCL_STOP 126 127 ierr = rstr->GetOffsets(rstr, mtype, offsets); CeedChk(ierr); 128 rstr->numreaders++; 129 return 0; 130 } 131 132 /** 133 @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 134 135 @param rstr CeedElemRestriction to restore 136 @param offsets Array of offset data 137 138 @return An error code: 0 - success, otherwise - failure 139 140 @ref User 141 **/ 142 int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, 143 const CeedInt **offsets) { 144 *offsets = NULL; 145 rstr->numreaders--; 146 return 0; 147 } 148 149 /** 150 @brief Get the backend stride status of a CeedElemRestriction 151 152 @param rstr CeedElemRestriction 153 @param[out] status Variable to store stride status 154 155 @return An error code: 0 - success, otherwise - failure 156 157 @ref Backend 158 **/ 159 int CeedElemRestrictionGetBackendStridesStatus(CeedElemRestriction rstr, 160 bool *status) { 161 if (!rstr->strides) 162 // LCOV_EXCL_START 163 return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data"); 164 // LCOV_EXCL_STOP 165 166 *status = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && 167 (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 168 (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 169 return 0; 170 } 171 172 /** 173 @brief Get the backend data of a CeedElemRestriction 174 175 @param rstr CeedElemRestriction 176 @param[out] data Variable to store data 177 178 @return An error code: 0 - success, otherwise - failure 179 180 @ref Backend 181 **/ 182 int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) { 183 *data = rstr->data; 184 return 0; 185 } 186 187 /** 188 @brief Set the backend data of a CeedElemRestriction 189 190 @param[out] rstr CeedElemRestriction 191 @param data Data to set 192 193 @return An error code: 0 - success, otherwise - failure 194 195 @ref Backend 196 **/ 197 int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) { 198 rstr->data = *data; 199 return 0; 200 } 201 202 /// @} 203 204 /// @cond DOXYGEN_SKIP 205 static struct CeedElemRestriction_private ceed_elemrestriction_none; 206 /// @endcond 207 208 /// ---------------------------------------------------------------------------- 209 /// CeedElemRestriction Public API 210 /// ---------------------------------------------------------------------------- 211 /// @addtogroup CeedElemRestrictionUser 212 /// @{ 213 214 /// Indicate that the stride is determined by the backend 215 const CeedInt CEED_STRIDES_BACKEND[3] = {}; 216 217 /// Indicate that no ElemRestriction is provided by the user 218 const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = 219 &ceed_elemrestriction_none; 220 221 /** 222 @brief Create a CeedElemRestriction 223 224 @param ceed A Ceed object where the CeedElemRestriction will be created 225 @param nelem Number of elements described in the @a offsets array 226 @param elemsize Size (number of "nodes") per element 227 @param ncomp Number of field components per interpolation node 228 (1 for scalar fields) 229 @param compstride Stride between components for the same L-vector "node". 230 Data for node i, component k can be found in the L-vector 231 at index [offsets[i] + k*compstride]. 232 @param lsize The size of the L-vector. This vector may be larger than 233 the elements and fields given by this restriction. 234 @param mtype Memory type of the @a offsets array, see CeedMemType 235 @param cmode Copy mode for the @a offsets array, see CeedCopyMode 236 @param offsets Array of shape [@a nelem, @a elemsize]. Row i holds the 237 ordered list of the offsets (into the input CeedVector) 238 for the unknowns corresponding to element i, where 239 0 <= i < @a nelem. All offsets must be in the range 240 [0, @a lsize - 1]. 241 @param[out] rstr Address of the variable where the newly created 242 CeedElemRestriction will be stored 243 244 @return An error code: 0 - success, otherwise - failure 245 246 @ref User 247 **/ 248 int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem, CeedInt elemsize, 249 CeedInt ncomp, CeedInt compstride, 250 CeedInt lsize, CeedMemType mtype, 251 CeedCopyMode cmode, const CeedInt *offsets, 252 CeedElemRestriction *rstr) { 253 int ierr; 254 255 if (!ceed->ElemRestrictionCreate) { 256 Ceed delegate; 257 ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 258 CeedChk(ierr); 259 260 if (!delegate) 261 // LCOV_EXCL_START 262 return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 263 // LCOV_EXCL_STOP 264 265 ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize, ncomp, 266 compstride, lsize, mtype, cmode, 267 offsets, rstr); CeedChk(ierr); 268 return 0; 269 } 270 271 ierr = CeedCalloc(1, rstr); CeedChk(ierr); 272 (*rstr)->ceed = ceed; 273 ceed->refcount++; 274 (*rstr)->refcount = 1; 275 (*rstr)->nelem = nelem; 276 (*rstr)->elemsize = elemsize; 277 (*rstr)->ncomp = ncomp; 278 (*rstr)->compstride = compstride; 279 (*rstr)->lsize = lsize; 280 (*rstr)->nblk = nelem; 281 (*rstr)->blksize = 1; 282 ierr = ceed->ElemRestrictionCreate(mtype, cmode, offsets, *rstr); 283 CeedChk(ierr); 284 return 0; 285 } 286 287 /** 288 @brief Create a strided CeedElemRestriction 289 290 @param ceed A Ceed object where the CeedElemRestriction will be created 291 @param nelem Number of elements described by the restriction 292 @param elemsize Size (number of "nodes") per element 293 @param ncomp Number of field components per interpolation node 294 (1 for scalar fields) 295 @param lsize The size of the L-vector. This vector may be larger than 296 the elements and fields given by this restriction. 297 @param strides Array for strides between [nodes, components, elements]. 298 The data for node i, component j, element k in the 299 L-vector is given by 300 i*strides[0] + j*strides[1] + k*strides[2] 301 @param rstr Address of the variable where the newly created 302 CeedElemRestriction will be stored 303 304 @return An error code: 0 - success, otherwise - failure 305 306 @ref User 307 **/ 308 int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt nelem, CeedInt elemsize, 309 CeedInt ncomp, CeedInt lsize, 310 const CeedInt strides[3], 311 CeedElemRestriction *rstr) { 312 int ierr; 313 314 if (!ceed->ElemRestrictionCreate) { 315 Ceed delegate; 316 ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 317 CeedChk(ierr); 318 319 if (!delegate) 320 // LCOV_EXCL_START 321 return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 322 // LCOV_EXCL_STOP 323 324 ierr = CeedElemRestrictionCreateStrided(delegate, nelem, elemsize, ncomp, 325 lsize, strides, rstr); 326 CeedChk(ierr); 327 return 0; 328 } 329 330 ierr = CeedCalloc(1, rstr); CeedChk(ierr); 331 (*rstr)->ceed = ceed; 332 ceed->refcount++; 333 (*rstr)->refcount = 1; 334 (*rstr)->nelem = nelem; 335 (*rstr)->elemsize = elemsize; 336 (*rstr)->ncomp = ncomp; 337 (*rstr)->lsize = lsize; 338 (*rstr)->nblk = nelem; 339 (*rstr)->blksize = 1; 340 ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 341 for (int i = 0; i<3; i++) 342 (*rstr)->strides[i] = strides[i]; 343 ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 344 *rstr); 345 CeedChk(ierr); 346 return 0; 347 } 348 349 /** 350 @brief Create a blocked CeedElemRestriction, typically only called by backends 351 352 @param ceed A Ceed object where the CeedElemRestriction will be created. 353 @param nelem Number of elements described in the @a offsets array. 354 @param elemsize Size (number of unknowns) per element 355 @param blksize Number of elements in a block 356 @param ncomp Number of field components per interpolation node 357 (1 for scalar fields) 358 @param compstride Stride between components for the same L-vector "node". 359 Data for node i, component k can be found in the L-vector 360 at index [offsets[i] + k*compstride]. 361 @param lsize The size of the L-vector. This vector may be larger than 362 the elements and fields given by this restriction. 363 @param mtype Memory type of the @a offsets array, see CeedMemType 364 @param cmode Copy mode for the @a offsets array, see CeedCopyMode 365 @param offsets Array of shape [@a nelem, @a elemsize]. Row i holds the 366 ordered list of the offsets (into the input CeedVector) 367 for the unknowns corresponding to element i, where 368 0 <= i < @a nelem. All offsets must be in the range 369 [0, @a lsize - 1]. The backend will permute and pad this 370 array to the desired ordering for the blocksize, which is 371 typically given by the backend. The default reordering is 372 to interlace elements. 373 @param rstr Address of the variable where the newly created 374 CeedElemRestriction will be stored 375 376 @return An error code: 0 - success, otherwise - failure 377 378 @ref Backend 379 **/ 380 int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize, 381 CeedInt blksize, CeedInt ncomp, 382 CeedInt compstride, CeedInt lsize, 383 CeedMemType mtype, CeedCopyMode cmode, 384 const CeedInt *offsets, 385 CeedElemRestriction *rstr) { 386 int ierr; 387 CeedInt *blkoffsets; 388 CeedInt nblk = (nelem / blksize) + !!(nelem % blksize); 389 390 if (!ceed->ElemRestrictionCreateBlocked) { 391 Ceed delegate; 392 ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 393 CeedChk(ierr); 394 395 if (!delegate) 396 // LCOV_EXCL_START 397 return CeedError(ceed, 1, "Backend does not support " 398 "ElemRestrictionCreateBlocked"); 399 // LCOV_EXCL_STOP 400 401 ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize, blksize, 402 ncomp, compstride, lsize, mtype, 403 cmode, offsets, rstr); 404 CeedChk(ierr); 405 return 0; 406 } 407 408 ierr = CeedCalloc(1, rstr); CeedChk(ierr); 409 410 ierr = CeedCalloc(nblk*blksize*elemsize, &blkoffsets); CeedChk(ierr); 411 ierr = CeedPermutePadOffsets(offsets, blkoffsets, nblk, nelem, blksize, 412 elemsize); 413 CeedChk(ierr); 414 415 (*rstr)->ceed = ceed; 416 ceed->refcount++; 417 (*rstr)->refcount = 1; 418 (*rstr)->nelem = nelem; 419 (*rstr)->elemsize = elemsize; 420 (*rstr)->ncomp = ncomp; 421 (*rstr)->compstride = compstride; 422 (*rstr)->lsize = lsize; 423 (*rstr)->nblk = nblk; 424 (*rstr)->blksize = blksize; 425 ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 426 (const CeedInt *) blkoffsets, *rstr); CeedChk(ierr); 427 428 if (cmode == CEED_OWN_POINTER) { 429 ierr = CeedFree(&offsets); CeedChk(ierr); 430 } 431 432 return 0; 433 } 434 435 /** 436 @brief Create a blocked strided CeedElemRestriction 437 438 @param ceed A Ceed object where the CeedElemRestriction will be created 439 @param nelem Number of elements described by the restriction 440 @param elemsize Size (number of "nodes") per element 441 @param blksize Number of elements in a block 442 @param ncomp Number of field components per interpolation node 443 (1 for scalar fields) 444 @param lsize The size of the L-vector. This vector may be larger than 445 the elements and fields given by this restriction. 446 @param strides Array for strides between [nodes, components, elements]. 447 The data for node i, component j, element k in the 448 L-vector is given by 449 i*strides[0] + j*strides[1] + k*strides[2] 450 @param rstr Address of the variable where the newly created 451 CeedElemRestriction will be stored 452 453 @return An error code: 0 - success, otherwise - failure 454 455 @ref User 456 **/ 457 int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt nelem, 458 CeedInt elemsize, CeedInt blksize, CeedInt ncomp, CeedInt lsize, 459 const CeedInt strides[3], CeedElemRestriction *rstr) { 460 int ierr; 461 CeedInt nblk = (nelem / blksize) + !!(nelem % blksize); 462 463 if (!ceed->ElemRestrictionCreateBlocked) { 464 Ceed delegate; 465 ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 466 CeedChk(ierr); 467 468 if (!delegate) 469 // LCOV_EXCL_START 470 return CeedError(ceed, 1, "Backend does not support " 471 "ElemRestrictionCreateBlocked"); 472 // LCOV_EXCL_STOP 473 474 ierr = CeedElemRestrictionCreateBlockedStrided(delegate, nelem, elemsize, 475 blksize, ncomp, lsize, strides, rstr); 476 CeedChk(ierr); 477 return 0; 478 } 479 480 ierr = CeedCalloc(1, rstr); CeedChk(ierr); 481 482 (*rstr)->ceed = ceed; 483 ceed->refcount++; 484 (*rstr)->refcount = 1; 485 (*rstr)->nelem = nelem; 486 (*rstr)->elemsize = elemsize; 487 (*rstr)->ncomp = ncomp; 488 (*rstr)->lsize = lsize; 489 (*rstr)->nblk = nblk; 490 (*rstr)->blksize = blksize; 491 ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 492 for (int i = 0; i<3; i++) 493 (*rstr)->strides[i] = strides[i]; 494 ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 495 NULL, *rstr); CeedChk(ierr); 496 497 return 0; 498 } 499 500 /** 501 @brief Create CeedVectors associated with a CeedElemRestriction 502 503 @param rstr CeedElemRestriction 504 @param lvec The address of the L-vector to be created, or NULL 505 @param evec The address of the E-vector to be created, or NULL 506 507 @return An error code: 0 - success, otherwise - failure 508 509 @ref User 510 **/ 511 int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec, 512 CeedVector *evec) { 513 int ierr; 514 CeedInt n, m; 515 m = rstr->lsize; 516 n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 517 if (lvec) { 518 ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr); 519 } 520 if (evec) { 521 ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr); 522 } 523 return 0; 524 } 525 526 /** 527 @brief Restrict an L-vector to an E-vector or apply its transpose 528 529 @param rstr CeedElemRestriction 530 @param tmode Apply restriction or transpose 531 @param u Input vector (of size @a lsize when tmode=CEED_NOTRANSPOSE) 532 @param ru Output vector (of shape [@a nelem * @a elemsize] when 533 tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided 534 by the backend. 535 @param request Request or CEED_REQUEST_IMMEDIATE 536 537 @return An error code: 0 - success, otherwise - failure 538 539 @ref User 540 **/ 541 int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode, 542 CeedVector u, CeedVector ru, 543 CeedRequest *request) { 544 CeedInt m,n; 545 int ierr; 546 547 if (tmode == CEED_NOTRANSPOSE) { 548 m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 549 n = rstr->lsize; 550 } else { 551 m = rstr->lsize; 552 n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 553 } 554 if (n != u->length) 555 // LCOV_EXCL_START 556 return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 557 "element restriction (%d, %d)", u->length, m, n); 558 // LCOV_EXCL_STOP 559 if (m != ru->length) 560 // LCOV_EXCL_START 561 return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 562 "element restriction (%d, %d)", ru->length, m, n); 563 // LCOV_EXCL_STOP 564 ierr = rstr->Apply(rstr, tmode, u, ru, request); CeedChk(ierr); 565 566 return 0; 567 } 568 569 /** 570 @brief Restrict an L-vector to a block of an E-vector or apply its transpose 571 572 @param rstr CeedElemRestriction 573 @param block Block number to restrict to/from, i.e. block=0 will handle 574 elements [0 : blksize] and block=3 will handle elements 575 [3*blksize : 4*blksize] 576 @param tmode Apply restriction or transpose 577 @param u Input vector (of size @a lsize when tmode=CEED_NOTRANSPOSE) 578 @param ru Output vector (of shape [@a blksize * @a elemsize] when 579 tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided 580 by the backend. 581 @param request Request or CEED_REQUEST_IMMEDIATE 582 583 @return An error code: 0 - success, otherwise - failure 584 585 @ref Backend 586 **/ 587 int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 588 CeedTransposeMode tmode, CeedVector u, 589 CeedVector ru, CeedRequest *request) { 590 CeedInt m,n; 591 int ierr; 592 593 if (tmode == CEED_NOTRANSPOSE) { 594 m = rstr->blksize * rstr->elemsize * rstr->ncomp; 595 n = rstr->lsize; 596 } else { 597 m = rstr->lsize; 598 n = rstr->blksize * rstr->elemsize * rstr->ncomp; 599 } 600 if (n != u->length) 601 // LCOV_EXCL_START 602 return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 603 "element restriction (%d, %d)", u->length, m, n); 604 // LCOV_EXCL_STOP 605 if (m != ru->length) 606 // LCOV_EXCL_START 607 return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 608 "element restriction (%d, %d)", ru->length, m, n); 609 // LCOV_EXCL_STOP 610 if (rstr->blksize*block > rstr->nelem) 611 // LCOV_EXCL_START 612 return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > " 613 "total elements %d", block, rstr->blksize*block, 614 rstr->nelem); 615 // LCOV_EXCL_STOP 616 ierr = rstr->ApplyBlock(rstr, block, tmode, u, ru, request); 617 CeedChk(ierr); 618 619 return 0; 620 } 621 622 /** 623 @brief Get the L-vector component stride 624 625 @param rstr CeedElemRestriction 626 @param[out] compstride Variable to store component stride 627 628 @return An error code: 0 - success, otherwise - failure 629 630 @ref Backend 631 **/ 632 int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, 633 CeedInt *compstride) { 634 *compstride = rstr->compstride; 635 return 0; 636 } 637 638 /** 639 @brief Get the total number of elements in the range of a CeedElemRestriction 640 641 @param rstr CeedElemRestriction 642 @param[out] numelem Variable to store number of elements 643 644 @return An error code: 0 - success, otherwise - failure 645 646 @ref Backend 647 **/ 648 int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 649 CeedInt *numelem) { 650 *numelem = rstr->nelem; 651 return 0; 652 } 653 654 /** 655 @brief Get the size of elements in the CeedElemRestriction 656 657 @param rstr CeedElemRestriction 658 @param[out] elemsize Variable to store size of elements 659 660 @return An error code: 0 - success, otherwise - failure 661 662 @ref Backend 663 **/ 664 int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 665 CeedInt *elemsize) { 666 *elemsize = rstr->elemsize; 667 return 0; 668 } 669 670 /** 671 @brief Get the size of the l-vector for a CeedElemRestriction 672 673 @param rstr CeedElemRestriction 674 @param[out] numnodes Variable to store number of nodes 675 676 @return An error code: 0 - success, otherwise - failure 677 678 @ref Backend 679 **/ 680 int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, 681 CeedInt *lsize) { 682 *lsize = rstr->lsize; 683 return 0; 684 } 685 686 /** 687 @brief Get the number of components in the elements of a 688 CeedElemRestriction 689 690 @param rstr CeedElemRestriction 691 @param[out] numcomp Variable to store number of components 692 693 @return An error code: 0 - success, otherwise - failure 694 695 @ref Backend 696 **/ 697 int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 698 CeedInt *numcomp) { 699 *numcomp = rstr->ncomp; 700 return 0; 701 } 702 703 /** 704 @brief Get the number of blocks in a CeedElemRestriction 705 706 @param rstr CeedElemRestriction 707 @param[out] numblock Variable to store number of blocks 708 709 @return An error code: 0 - success, otherwise - failure 710 711 @ref Backend 712 **/ 713 int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 714 CeedInt *numblock) { 715 *numblock = rstr->nblk; 716 return 0; 717 } 718 719 /** 720 @brief Get the size of blocks in the CeedElemRestriction 721 722 @param rstr CeedElemRestriction 723 @param[out] blksize Variable to store size of blocks 724 725 @return An error code: 0 - success, otherwise - failure 726 727 @ref Backend 728 **/ 729 int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 730 CeedInt *blksize) { 731 *blksize = rstr->blksize; 732 return 0; 733 } 734 735 /** 736 @brief Get the multiplicity of nodes in a CeedElemRestriction 737 738 @param rstr CeedElemRestriction 739 @param[out] mult Vector to store multiplicity (of size lsize) 740 741 @return An error code: 0 - success, otherwise - failure 742 743 @ref User 744 **/ 745 int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 746 CeedVector mult) { 747 int ierr; 748 CeedVector evec; 749 750 // Create and set evec 751 ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr); 752 ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr); 753 ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr); 754 755 // Apply to get multiplicity 756 ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult, 757 CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 758 759 // Cleanup 760 ierr = CeedVectorDestroy(&evec); CeedChk(ierr); 761 762 return 0; 763 } 764 765 /** 766 @brief View a CeedElemRestriction 767 768 @param[in] rstr CeedElemRestriction to view 769 @param[in] stream Stream to write; typically stdout/stderr or a file 770 771 @return Error code: 0 - success, otherwise - failure 772 773 @ref User 774 **/ 775 int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 776 char stridesstr[500]; 777 if (rstr->strides) 778 sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1], 779 rstr->strides[2]); 780 else 781 sprintf(stridesstr, "%d", rstr->compstride); 782 783 fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d " 784 "nodes each and %s %s\n", rstr->blksize > 1 ? "Blocked " : "", 785 rstr->lsize, rstr->ncomp, rstr->nelem, rstr->elemsize, 786 rstr->strides ? "strides" : "component stride", stridesstr); 787 return 0; 788 } 789 790 /** 791 @brief Destroy a CeedElemRestriction 792 793 @param rstr CeedElemRestriction to destroy 794 795 @return An error code: 0 - success, otherwise - failure 796 797 @ref User 798 **/ 799 int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 800 int ierr; 801 802 if (!*rstr || --(*rstr)->refcount > 0) 803 return 0; 804 if ((*rstr)->numreaders) 805 return CeedError((*rstr)->ceed, 1, "Cannot destroy CeedElemRestriction, " 806 "a process has read access to the offset data"); 807 if ((*rstr)->Destroy) { 808 ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 809 } 810 ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr); 811 ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 812 ierr = CeedFree(rstr); CeedChk(ierr); 813 return 0; 814 } 815 816 /// @} 817