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 const 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, CeedInt nnodes, CeedInt ncomp, 313 const CeedInt strides[3], CeedElemRestriction *rstr) { 314 int ierr; 315 CeedInt nblk = (nelem / blksize) + !!(nelem % blksize); 316 317 if (!ceed->ElemRestrictionCreateBlocked) { 318 Ceed delegate; 319 ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 320 CeedChk(ierr); 321 322 if (!delegate) 323 // LCOV_EXCL_START 324 return CeedError(ceed, 1, "Backend does not support " 325 "ElemRestrictionCreateBlocked"); 326 // LCOV_EXCL_STOP 327 328 ierr = CeedElemRestrictionCreateBlockedStrided(delegate, nelem, elemsize, 329 blksize, nnodes, ncomp, strides, rstr); 330 CeedChk(ierr); 331 return 0; 332 } 333 334 ierr = CeedCalloc(1, rstr); CeedChk(ierr); 335 336 (*rstr)->ceed = ceed; 337 ceed->refcount++; 338 (*rstr)->refcount = 1; 339 (*rstr)->nelem = nelem; 340 (*rstr)->elemsize = elemsize; 341 (*rstr)->nnodes = nnodes; 342 (*rstr)->ncomp = ncomp; 343 (*rstr)->nblk = nblk; 344 (*rstr)->blksize = blksize; 345 ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 346 for (int i = 0; i<3; i++) 347 (*rstr)->strides[i] = strides[i]; 348 ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 349 NULL, *rstr); CeedChk(ierr); 350 351 return 0; 352 } 353 354 /** 355 @brief Create CeedVectors associated with a CeedElemRestriction 356 357 @param rstr CeedElemRestriction 358 @param lvec The address of the L-vector to be created, or NULL 359 @param evec The address of the E-vector to be created, or NULL 360 361 @return An error code: 0 - success, otherwise - failure 362 363 @ref Advanced 364 **/ 365 int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec, 366 CeedVector *evec) { 367 int ierr; 368 CeedInt n, m; 369 m = rstr->nnodes * rstr->ncomp; 370 n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 371 if (lvec) { 372 ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr); 373 } 374 if (evec) { 375 ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr); 376 } 377 return 0; 378 } 379 380 /** 381 @brief Restrict an L-vector to an E-vector or apply its transpose 382 383 @param rstr CeedElemRestriction 384 @param tmode Apply restriction or transpose 385 @param u Input vector (of shape [@a nnodes, @a ncomp] when 386 tmode=CEED_NOTRANSPOSE, imode=CEED_INTERLACED) 387 @param ru Output vector (of shape [@a nelem * @a elemsize] when 388 tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided 389 by the backend. 390 @param request Request or CEED_REQUEST_IMMEDIATE 391 392 @return An error code: 0 - success, otherwise - failure 393 394 @ref Advanced 395 **/ 396 int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode, 397 CeedVector u, CeedVector ru, 398 CeedRequest *request) { 399 CeedInt m,n; 400 int ierr; 401 402 if (tmode == CEED_NOTRANSPOSE) { 403 m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 404 n = rstr->nnodes * rstr->ncomp; 405 } else { 406 m = rstr->nnodes * rstr->ncomp; 407 n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 408 } 409 if (n != u->length) 410 // LCOV_EXCL_START 411 return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 412 "element restriction (%d, %d)", u->length, m, n); 413 // LCOV_EXCL_STOP 414 if (m != ru->length) 415 // LCOV_EXCL_START 416 return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 417 "element restriction (%d, %d)", ru->length, m, n); 418 // LCOV_EXCL_STOP 419 ierr = rstr->Apply(rstr, tmode, u, ru, request); CeedChk(ierr); 420 421 return 0; 422 } 423 424 /** 425 @brief Restrict an L-vector to a block of an E-vector or apply its transpose 426 427 @param rstr CeedElemRestriction 428 @param block Block number to restrict to/from, i.e. block=0 will handle 429 elements [0 : blksize] and block=3 will handle elements 430 [3*blksize : 4*blksize] 431 @param tmode Apply restriction or transpose 432 @param u Input vector (of shape [@a nnodes, @a ncomp] when 433 tmode=CEED_NOTRANSPOSE, imode=CEED_INTERLACED) 434 @param ru Output vector (of shape [@a blksize * @a elemsize] when 435 tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided 436 by the backend. 437 @param request Request or CEED_REQUEST_IMMEDIATE 438 439 @return An error code: 0 - success, otherwise - failure 440 441 @ref Advanced 442 **/ 443 int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 444 CeedTransposeMode tmode, CeedVector u, 445 CeedVector ru, CeedRequest *request) { 446 CeedInt m,n; 447 int ierr; 448 449 if (tmode == CEED_NOTRANSPOSE) { 450 m = rstr->blksize * rstr->elemsize * rstr->ncomp; 451 n = rstr->nnodes * rstr->ncomp; 452 } else { 453 m = rstr->nnodes * rstr->ncomp; 454 n = rstr->blksize * rstr->elemsize * rstr->ncomp; 455 } 456 if (n != u->length) 457 // LCOV_EXCL_START 458 return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 459 "element restriction (%d, %d)", u->length, m, n); 460 // LCOV_EXCL_STOP 461 if (m != ru->length) 462 // LCOV_EXCL_START 463 return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 464 "element restriction (%d, %d)", ru->length, m, n); 465 // LCOV_EXCL_STOP 466 if (rstr->blksize*block > rstr->nelem) 467 // LCOV_EXCL_START 468 return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > " 469 "total elements %d", block, rstr->blksize*block, 470 rstr->nelem); 471 // LCOV_EXCL_STOP 472 ierr = rstr->ApplyBlock(rstr, block, tmode, u, ru, request); 473 CeedChk(ierr); 474 475 return 0; 476 } 477 478 /** 479 @brief Get the multiplicity of nodes in a CeedElemRestriction 480 481 @param rstr CeedElemRestriction 482 @param[out] mult Vector to store multiplicity (of size nnodes*ncomp) 483 484 @return An error code: 0 - success, otherwise - failure 485 486 @ref Advanced 487 **/ 488 int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 489 CeedVector mult) { 490 int ierr; 491 CeedVector evec; 492 493 // Create and set evec 494 ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr); 495 ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr); 496 ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr); 497 498 // Apply to get multiplicity 499 ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult, 500 CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 501 502 // Cleanup 503 ierr = CeedVectorDestroy(&evec); CeedChk(ierr); 504 505 return 0; 506 } 507 508 /** 509 @brief Get the Ceed associated with a CeedElemRestriction 510 511 @param rstr CeedElemRestriction 512 @param[out] ceed Variable to store Ceed 513 514 @return An error code: 0 - success, otherwise - failure 515 516 @ref Advanced 517 **/ 518 int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 519 *ceed = rstr->ceed; 520 return 0; 521 } 522 523 /** 524 @brief Get the L-vector interlaced mode of a CeedElemRestriction 525 526 @param rstr CeedElemRestriction 527 @param[out] imode Variable to store imode 528 529 @return An error code: 0 - success, otherwise - failure 530 531 @ref Advanced 532 **/ 533 int CeedElemRestrictionGetIMode(CeedElemRestriction rstr, 534 CeedInterlaceMode *imode) { 535 if (rstr->strides) 536 // LCOV_EXCL_START 537 return CeedError(rstr->ceed, 1, "Strided ElemRestriction has no interlace " 538 "mode"); 539 // LCOV_EXCL_STOP 540 541 *imode = rstr->imode; 542 return 0; 543 } 544 545 /** 546 @brief Get the total number of elements in the range of a CeedElemRestriction 547 548 @param rstr CeedElemRestriction 549 @param[out] numelem Variable to store number of elements 550 551 @return An error code: 0 - success, otherwise - failure 552 553 @ref Advanced 554 **/ 555 int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 556 CeedInt *numelem) { 557 *numelem = rstr->nelem; 558 return 0; 559 } 560 561 /** 562 @brief Get the size of elements in the CeedElemRestriction 563 564 @param rstr CeedElemRestriction 565 @param[out] elemsize Variable to store size of elements 566 567 @return An error code: 0 - success, otherwise - failure 568 569 @ref Advanced 570 **/ 571 int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 572 CeedInt *elemsize) { 573 *elemsize = rstr->elemsize; 574 return 0; 575 } 576 577 /** 578 @brief Get the number of degrees of freedom in the range of a 579 CeedElemRestriction 580 581 @param rstr CeedElemRestriction 582 @param[out] numnodes Variable to store number of nodes 583 584 @return An error code: 0 - success, otherwise - failure 585 586 @ref Advanced 587 **/ 588 int CeedElemRestrictionGetNumNodes(CeedElemRestriction rstr, 589 CeedInt *numnodes) { 590 *numnodes = rstr->nnodes; 591 return 0; 592 } 593 594 /** 595 @brief Get the number of components in the elements of a 596 CeedElemRestriction 597 598 @param rstr CeedElemRestriction 599 @param[out] numcomp Variable to store number of components 600 601 @return An error code: 0 - success, otherwise - failure 602 603 @ref Advanced 604 **/ 605 int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 606 CeedInt *numcomp) { 607 *numcomp = rstr->ncomp; 608 return 0; 609 } 610 611 /** 612 @brief Get the number of blocks in a CeedElemRestriction 613 614 @param rstr CeedElemRestriction 615 @param[out] numblock Variable to store number of blocks 616 617 @return An error code: 0 - success, otherwise - failure 618 619 @ref Advanced 620 **/ 621 int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 622 CeedInt *numblock) { 623 *numblock = rstr->nblk; 624 return 0; 625 } 626 627 /** 628 @brief Get the size of blocks in the CeedElemRestriction 629 630 @param rstr CeedElemRestriction 631 @param[out] blksize Variable to store size of blocks 632 633 @return An error code: 0 - success, otherwise - failure 634 635 @ref Advanced 636 **/ 637 int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 638 CeedInt *blksize) { 639 *blksize = rstr->blksize; 640 return 0; 641 } 642 643 /** 644 @brief Get the strides of a strided CeedElemRestriction 645 646 @param rstr CeedElemRestriction 647 @param[out] strides Variable to store strides array 648 649 @return An error code: 0 - success, otherwise - failure 650 651 @ref Advanced 652 **/ 653 int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, 654 CeedInt (*strides)[3]) { 655 if (!rstr->strides) 656 // LCOV_EXCL_START 657 return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data"); 658 // LCOV_EXCL_STOP 659 660 for (int i = 0; i<3; i++) 661 (*strides)[i] = rstr->strides[i]; 662 return 0; 663 } 664 665 /** 666 @brief Get the backend stride status of a CeedElemRestriction 667 668 @param rstr CeedElemRestriction 669 @param[out] bool Variable to store stride status 670 671 @return An error code: 0 - success, otherwise - failure 672 673 @ref Advanced 674 **/ 675 int CeedElemRestrictionGetBackendStridesStatus(CeedElemRestriction rstr, 676 bool *status) { 677 if (!rstr->strides) 678 // LCOV_EXCL_START 679 return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data"); 680 // LCOV_EXCL_STOP 681 682 *status = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && 683 (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 684 (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 685 return 0; 686 } 687 688 /** 689 @brief Get the backend data of a CeedElemRestriction 690 691 @param rstr CeedElemRestriction 692 @param[out] data Variable to store data 693 694 @return An error code: 0 - success, otherwise - failure 695 696 @ref Advanced 697 **/ 698 int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) { 699 *data = rstr->data; 700 return 0; 701 } 702 703 /** 704 @brief Set the backend data of a CeedElemRestriction 705 706 @param[out] rstr CeedElemRestriction 707 @param data Data to set 708 709 @return An error code: 0 - success, otherwise - failure 710 711 @ref Advanced 712 **/ 713 int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) { 714 rstr->data = *data; 715 return 0; 716 } 717 718 /** 719 @brief View a CeedElemRestriction 720 721 @param[in] rstr CeedElemRestriction to view 722 @param[in] stream Stream to write; typically stdout/stderr or a file 723 724 @return Error code: 0 - success, otherwise - failure 725 726 @ref Utility 727 **/ 728 int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 729 char stridesstr[500]; 730 if (rstr->strides) 731 sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1], 732 rstr->strides[2]); 733 734 fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d " 735 "nodes each and %s %s\n", rstr->blksize > 1 ? "Blocked " : "", 736 rstr->nnodes, rstr->ncomp, rstr->nelem, rstr->elemsize, 737 rstr->strides ? "strides" : "L-vector components", 738 rstr->strides ? stridesstr : CeedInterlaceModes[rstr->imode]); 739 return 0; 740 } 741 742 /** 743 @brief Destroy a CeedElemRestriction 744 745 @param rstr CeedElemRestriction to destroy 746 747 @return An error code: 0 - success, otherwise - failure 748 749 @ref Basic 750 **/ 751 int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 752 int ierr; 753 754 if (!*rstr || --(*rstr)->refcount > 0) 755 return 0; 756 if ((*rstr)->Destroy) { 757 ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 758 } 759 ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr); 760 ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 761 ierr = CeedFree(rstr); CeedChk(ierr); 762 return 0; 763 } 764 765 /// @cond DOXYGEN_SKIP 766 // Indicate that the stride is determined by the backend 767 CeedInt CEED_STRIDES_BACKEND[3] = {}; 768 769 // Indicate that no ElemRestriction is provided by the user 770 CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 771 /// @endcond 772 773 /// @} 774