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