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 if (indices) { 258 ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr); 259 ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize, 260 elemsize); 261 CeedChk(ierr); 262 } else { 263 blkindices = NULL; 264 } 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 data of a CeedElemRestriction 670 671 @param rstr CeedElemRestriction 672 @param[out] data Variable to store data 673 674 @return An error code: 0 - success, otherwise - failure 675 676 @ref Advanced 677 **/ 678 int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) { 679 *data = rstr->data; 680 return 0; 681 } 682 683 /** 684 @brief Set the backend data of a CeedElemRestriction 685 686 @param[out] rstr CeedElemRestriction 687 @param data Data to set 688 689 @return An error code: 0 - success, otherwise - failure 690 691 @ref Advanced 692 **/ 693 int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) { 694 rstr->data = *data; 695 return 0; 696 } 697 698 /** 699 @brief View a CeedElemRestriction 700 701 @param[in] rstr CeedElemRestriction to view 702 @param[in] stream Stream to write; typically stdout/stderr or a file 703 704 @return Error code: 0 - success, otherwise - failure 705 706 @ref Utility 707 **/ 708 int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 709 char stridesstr[500]; 710 if (rstr->strides) 711 sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1], 712 rstr->strides[2]); 713 714 fprintf(stream, "CeedElemRestriction from (%d, %d) to %d elements with %d " 715 "nodes each and %s %s\n", rstr->nnodes, rstr->ncomp, rstr->nelem, 716 rstr->elemsize, rstr->strides ? "strides" : "L-vector components", 717 rstr->strides ? stridesstr : CeedInterlaceModes[rstr->imode]); 718 return 0; 719 } 720 721 /** 722 @brief Destroy a CeedElemRestriction 723 724 @param rstr CeedElemRestriction to destroy 725 726 @return An error code: 0 - success, otherwise - failure 727 728 @ref Basic 729 **/ 730 int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 731 int ierr; 732 733 if (!*rstr || --(*rstr)->refcount > 0) 734 return 0; 735 if ((*rstr)->Destroy) { 736 ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 737 } 738 ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr); 739 ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 740 ierr = CeedFree(rstr); CeedChk(ierr); 741 return 0; 742 } 743 744 /// @} 745