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