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