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