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