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