1d7b241e6Sjeremylt // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2d7b241e6Sjeremylt // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3d7b241e6Sjeremylt // reserved. See files LICENSE and NOTICE for details. 4d7b241e6Sjeremylt // 5d7b241e6Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software 6d7b241e6Sjeremylt // libraries and APIs for efficient high-order finite element and spectral 7d7b241e6Sjeremylt // element discretizations for exascale applications. For more information and 8d7b241e6Sjeremylt // source code availability see http://github.com/ceed. 9d7b241e6Sjeremylt // 10d7b241e6Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11d7b241e6Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office 12d7b241e6Sjeremylt // of Science and the National Nuclear Security Administration) responsible for 13d7b241e6Sjeremylt // the planning and preparation of a capable exascale ecosystem, including 14d7b241e6Sjeremylt // software, applications, hardware, advanced system engineering and early 15d7b241e6Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative. 16d7b241e6Sjeremylt 17d7b241e6Sjeremylt #include <ceed-impl.h> 18d863ab9bSjeremylt #include <ceed-backend.h> 19d7b241e6Sjeremylt 207a982d89SJeremy L. Thompson /// @file 217a982d89SJeremy L. Thompson /// Implementation of CeedElemRestriction interfaces 227a982d89SJeremy L. Thompson 237a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 247a982d89SJeremy L. Thompson /// CeedElemRestriction Library Internal Functions 257a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 267a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionDeveloper 277a982d89SJeremy L. Thompson /// @{ 287a982d89SJeremy L. Thompson 297a982d89SJeremy L. Thompson /** 30d979a051Sjeremylt @brief Permute and pad offsets for a blocked restriction 317a982d89SJeremy L. Thompson 32d979a051Sjeremylt @param offsets Array of shape [@a nelem, @a elemsize]. Row i holds the 33d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 347a982d89SJeremy L. Thompson for the unknowns corresponding to element i, where 35d979a051Sjeremylt 0 <= i < @a nelem. All offsets must be in the range 36d979a051Sjeremylt [0, @a lsize - 1]. 37d979a051Sjeremylt @param blkoffsets Array of permuted and padded offsets of 387a982d89SJeremy L. Thompson shape [@a nblk, @a elemsize, @a blksize]. 397a982d89SJeremy L. Thompson @param nblk Number of blocks 407a982d89SJeremy L. Thompson @param nelem Number of elements 417a982d89SJeremy L. Thompson @param blksize Number of elements in a block 427a982d89SJeremy L. Thompson @param elemsize Size of each element 437a982d89SJeremy L. Thompson 447a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 457a982d89SJeremy L. Thompson 467a982d89SJeremy L. Thompson @ref Utility 477a982d89SJeremy L. Thompson **/ 48d979a051Sjeremylt int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blkoffsets, 497a982d89SJeremy L. Thompson CeedInt nblk, CeedInt nelem, CeedInt blksize, 507a982d89SJeremy L. Thompson CeedInt elemsize) { 517a982d89SJeremy L. Thompson for (CeedInt e = 0; e < nblk*blksize; e+=blksize) 527a982d89SJeremy L. Thompson for (int j = 0; j < blksize; j++) 537a982d89SJeremy L. Thompson for (int k = 0; k < elemsize; k++) 54d979a051Sjeremylt blkoffsets[e*elemsize + k*blksize + j] 55d979a051Sjeremylt = offsets[CeedIntMin(e+j,nelem-1)*elemsize + k]; 567a982d89SJeremy L. Thompson return 0; 577a982d89SJeremy L. Thompson } 587a982d89SJeremy L. Thompson 597a982d89SJeremy L. Thompson /// @} 607a982d89SJeremy L. Thompson 617a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 627a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 637a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 647a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 657a982d89SJeremy L. Thompson /// @{ 667a982d89SJeremy L. Thompson 677a982d89SJeremy L. Thompson /** 687a982d89SJeremy L. Thompson @brief Get the Ceed associated with a CeedElemRestriction 697a982d89SJeremy L. Thompson 707a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 717a982d89SJeremy L. Thompson @param[out] ceed Variable to store Ceed 727a982d89SJeremy L. Thompson 737a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 747a982d89SJeremy L. Thompson 757a982d89SJeremy L. Thompson @ref Backend 767a982d89SJeremy L. Thompson **/ 777a982d89SJeremy L. Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 787a982d89SJeremy L. Thompson *ceed = rstr->ceed; 797a982d89SJeremy L. Thompson return 0; 807a982d89SJeremy L. Thompson } 817a982d89SJeremy L. Thompson 827a982d89SJeremy L. Thompson /** 83a681ae63Sjeremylt 84a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 857a982d89SJeremy L. Thompson 867a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 87a681ae63Sjeremylt @param[out] strides Variable to store strides array 887a982d89SJeremy L. Thompson 897a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 907a982d89SJeremy L. Thompson 917a982d89SJeremy L. Thompson @ref Backend 927a982d89SJeremy L. Thompson **/ 93a681ae63Sjeremylt int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, 94a681ae63Sjeremylt CeedInt (*strides)[3]) { 95a681ae63Sjeremylt if (!rstr->strides) 96a681ae63Sjeremylt // LCOV_EXCL_START 97a681ae63Sjeremylt return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data"); 98a681ae63Sjeremylt // LCOV_EXCL_STOP 99a681ae63Sjeremylt 100a681ae63Sjeremylt for (int i = 0; i<3; i++) 101a681ae63Sjeremylt (*strides)[i] = rstr->strides[i]; 1027a982d89SJeremy L. Thompson return 0; 1037a982d89SJeremy L. Thompson } 1047a982d89SJeremy L. Thompson 1057a982d89SJeremy L. Thompson /** 106bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 107bd33150aSjeremylt 108bd33150aSjeremylt @param rstr CeedElemRestriction to retrieve offsets 109bd33150aSjeremylt @param mtype Memory type on which to access the array. If the backend 110bd33150aSjeremylt uses a different memory type, this will perform a copy 111bd33150aSjeremylt (possibly cached). 112bd33150aSjeremylt @param[out] offsets Array on memory type mtype 113bd33150aSjeremylt 114bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 115bd33150aSjeremylt 116bd33150aSjeremylt @ref User 117bd33150aSjeremylt **/ 118bd33150aSjeremylt int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mtype, 119bd33150aSjeremylt const CeedInt **offsets) { 120bd33150aSjeremylt int ierr; 121bd33150aSjeremylt 122bd33150aSjeremylt if (!rstr->GetOffsets) 123bd33150aSjeremylt // LCOV_EXCL_START 124bd33150aSjeremylt return CeedError(rstr->ceed, 1, "Backend does not support GetOffsets"); 125bd33150aSjeremylt // LCOV_EXCL_STOP 126bd33150aSjeremylt 127bd33150aSjeremylt ierr = rstr->GetOffsets(rstr, mtype, offsets); CeedChk(ierr); 128*430758c8SJeremy L Thompson rstr->numreaders++; 129*430758c8SJeremy L Thompson return 0; 130*430758c8SJeremy L Thompson } 131*430758c8SJeremy L Thompson 132*430758c8SJeremy L Thompson /** 133*430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 134*430758c8SJeremy L Thompson 135*430758c8SJeremy L Thompson @param rstr CeedElemRestriction to restore 136*430758c8SJeremy L Thompson @param offsets Array of offset data 137*430758c8SJeremy L Thompson 138*430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 139*430758c8SJeremy L Thompson 140*430758c8SJeremy L Thompson @ref User 141*430758c8SJeremy L Thompson **/ 142*430758c8SJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, 143*430758c8SJeremy L Thompson const CeedInt **offsets) { 144*430758c8SJeremy L Thompson *offsets = NULL; 145*430758c8SJeremy L Thompson rstr->numreaders--; 146bd33150aSjeremylt return 0; 147bd33150aSjeremylt } 148bd33150aSjeremylt 149bd33150aSjeremylt /** 150a681ae63Sjeremylt @brief Get the backend stride status of a CeedElemRestriction 1517a982d89SJeremy L. Thompson 1527a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 153a681ae63Sjeremylt @param[out] status Variable to store stride status 1547a982d89SJeremy L. Thompson 1557a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1567a982d89SJeremy L. Thompson 1577a982d89SJeremy L. Thompson @ref Backend 1587a982d89SJeremy L. Thompson **/ 159a681ae63Sjeremylt int CeedElemRestrictionGetBackendStridesStatus(CeedElemRestriction rstr, 160a681ae63Sjeremylt bool *status) { 161a681ae63Sjeremylt if (!rstr->strides) 162a681ae63Sjeremylt // LCOV_EXCL_START 163a681ae63Sjeremylt return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data"); 164a681ae63Sjeremylt // LCOV_EXCL_STOP 1657a982d89SJeremy L. Thompson 166a681ae63Sjeremylt *status = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && 167a681ae63Sjeremylt (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 168a681ae63Sjeremylt (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 1697a982d89SJeremy L. Thompson return 0; 1707a982d89SJeremy L. Thompson } 1717a982d89SJeremy L. Thompson 1727a982d89SJeremy L. Thompson /** 1737a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 1747a982d89SJeremy L. Thompson 1757a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 1767a982d89SJeremy L. Thompson @param[out] data Variable to store data 1777a982d89SJeremy L. Thompson 1787a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1797a982d89SJeremy L. Thompson 1807a982d89SJeremy L. Thompson @ref Backend 1817a982d89SJeremy L. Thompson **/ 1827a982d89SJeremy L. Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) { 1837a982d89SJeremy L. Thompson *data = rstr->data; 1847a982d89SJeremy L. Thompson return 0; 1857a982d89SJeremy L. Thompson } 1867a982d89SJeremy L. Thompson 1877a982d89SJeremy L. Thompson /** 1887a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 1897a982d89SJeremy L. Thompson 1907a982d89SJeremy L. Thompson @param[out] rstr CeedElemRestriction 1917a982d89SJeremy L. Thompson @param data Data to set 1927a982d89SJeremy L. Thompson 1937a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1947a982d89SJeremy L. Thompson 1957a982d89SJeremy L. Thompson @ref Backend 1967a982d89SJeremy L. Thompson **/ 1977a982d89SJeremy L. Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) { 1987a982d89SJeremy L. Thompson rstr->data = *data; 1997a982d89SJeremy L. Thompson return 0; 2007a982d89SJeremy L. Thompson } 2017a982d89SJeremy L. Thompson 2027a982d89SJeremy L. Thompson /// @} 2037a982d89SJeremy L. Thompson 20415910d16Sjeremylt /// @cond DOXYGEN_SKIP 20515910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 20615910d16Sjeremylt /// @endcond 20715910d16Sjeremylt 2087a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2097a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 2107a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2117a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 212d7b241e6Sjeremylt /// @{ 213d7b241e6Sjeremylt 2147a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 2157a982d89SJeremy L. Thompson const CeedInt CEED_STRIDES_BACKEND[3] = {}; 2167a982d89SJeremy L. Thompson 2177a982d89SJeremy L. Thompson /// Indicate that no ElemRestriction is provided by the user 2187a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = 2197a982d89SJeremy L. Thompson &ceed_elemrestriction_none; 2207a982d89SJeremy L. Thompson 221d7b241e6Sjeremylt /** 222b11c1e72Sjeremylt @brief Create a CeedElemRestriction 223d7b241e6Sjeremylt 224b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 225d979a051Sjeremylt @param nelem Number of elements described in the @a offsets array 226b11c1e72Sjeremylt @param elemsize Size (number of "nodes") per element 227b11c1e72Sjeremylt @param ncomp Number of field components per interpolation node 22895bb1877Svaleriabarra (1 for scalar fields) 229d979a051Sjeremylt @param compstride Stride between components for the same L-vector "node". 230d979a051Sjeremylt Data for node i, component k can be found in the L-vector 231d979a051Sjeremylt at index [offsets[i] + k*compstride]. 232d979a051Sjeremylt @param lsize The size of the L-vector. This vector may be larger than 233d979a051Sjeremylt the elements and fields given by this restriction. 234d979a051Sjeremylt @param mtype Memory type of the @a offsets array, see CeedMemType 235d979a051Sjeremylt @param cmode Copy mode for the @a offsets array, see CeedCopyMode 236d979a051Sjeremylt @param offsets Array of shape [@a nelem, @a elemsize]. Row i holds the 237d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 2388795c945Sjeremylt for the unknowns corresponding to element i, where 239d979a051Sjeremylt 0 <= i < @a nelem. All offsets must be in the range 240d979a051Sjeremylt [0, @a lsize - 1]. 2414ce2993fSjeremylt @param[out] rstr Address of the variable where the newly created 242b11c1e72Sjeremylt CeedElemRestriction will be stored 243d7b241e6Sjeremylt 244b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 245dfdf5a53Sjeremylt 2467a982d89SJeremy L. Thompson @ref User 247b11c1e72Sjeremylt **/ 248d979a051Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem, CeedInt elemsize, 249d979a051Sjeremylt CeedInt ncomp, CeedInt compstride, 250d979a051Sjeremylt CeedInt lsize, CeedMemType mtype, 251d979a051Sjeremylt CeedCopyMode cmode, const CeedInt *offsets, 2524ce2993fSjeremylt CeedElemRestriction *rstr) { 253d7b241e6Sjeremylt int ierr; 254d7b241e6Sjeremylt 2555fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 2565fe0d4faSjeremylt Ceed delegate; 257aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 258aefd8378Sjeremylt CeedChk(ierr); 2595fe0d4faSjeremylt 2605fe0d4faSjeremylt if (!delegate) 261c042f62fSJeremy L Thompson // LCOV_EXCL_START 262d7b241e6Sjeremylt return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 263c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 2645fe0d4faSjeremylt 265d979a051Sjeremylt ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize, ncomp, 266d979a051Sjeremylt compstride, lsize, mtype, cmode, 267d979a051Sjeremylt offsets, rstr); CeedChk(ierr); 2685fe0d4faSjeremylt return 0; 2695fe0d4faSjeremylt } 2705fe0d4faSjeremylt 2714ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 2724ce2993fSjeremylt (*rstr)->ceed = ceed; 273d7b241e6Sjeremylt ceed->refcount++; 2744ce2993fSjeremylt (*rstr)->refcount = 1; 2754ce2993fSjeremylt (*rstr)->nelem = nelem; 2764ce2993fSjeremylt (*rstr)->elemsize = elemsize; 2774ce2993fSjeremylt (*rstr)->ncomp = ncomp; 278d979a051Sjeremylt (*rstr)->compstride = compstride; 279d979a051Sjeremylt (*rstr)->lsize = lsize; 2804ce2993fSjeremylt (*rstr)->nblk = nelem; 2814ce2993fSjeremylt (*rstr)->blksize = 1; 282d979a051Sjeremylt ierr = ceed->ElemRestrictionCreate(mtype, cmode, offsets, *rstr); 283d979a051Sjeremylt CeedChk(ierr); 284d7b241e6Sjeremylt return 0; 285d7b241e6Sjeremylt } 286d7b241e6Sjeremylt 287d7b241e6Sjeremylt /** 2887509a596Sjeremylt @brief Create a strided CeedElemRestriction 289d7b241e6Sjeremylt 290b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 2917509a596Sjeremylt @param nelem Number of elements described by the restriction 292b11c1e72Sjeremylt @param elemsize Size (number of "nodes") per element 293b11c1e72Sjeremylt @param ncomp Number of field components per interpolation node 29495bb1877Svaleriabarra (1 for scalar fields) 295d979a051Sjeremylt @param lsize The size of the L-vector. This vector may be larger than 296d979a051Sjeremylt the elements and fields given by this restriction. 2977509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 2987509a596Sjeremylt The data for node i, component j, element k in the 2997509a596Sjeremylt L-vector is given by 3007509a596Sjeremylt i*strides[0] + j*strides[1] + k*strides[2] 3014ce2993fSjeremylt @param rstr Address of the variable where the newly created 302b11c1e72Sjeremylt CeedElemRestriction will be stored 303d7b241e6Sjeremylt 304b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 305dfdf5a53Sjeremylt 3067a982d89SJeremy L. Thompson @ref User 307b11c1e72Sjeremylt **/ 3087509a596Sjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt nelem, CeedInt elemsize, 309d979a051Sjeremylt CeedInt ncomp, CeedInt lsize, 3108621c6c6SJeremy L Thompson const CeedInt strides[3], 311f90c8643Sjeremylt CeedElemRestriction *rstr) { 312d7b241e6Sjeremylt int ierr; 313d7b241e6Sjeremylt 3145fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 3155fe0d4faSjeremylt Ceed delegate; 316aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 317aefd8378Sjeremylt CeedChk(ierr); 3185fe0d4faSjeremylt 3195fe0d4faSjeremylt if (!delegate) 320c042f62fSJeremy L Thompson // LCOV_EXCL_START 3211d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 322c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 3235fe0d4faSjeremylt 324d979a051Sjeremylt ierr = CeedElemRestrictionCreateStrided(delegate, nelem, elemsize, ncomp, 325d979a051Sjeremylt lsize, strides, rstr); 326d979a051Sjeremylt CeedChk(ierr); 3275fe0d4faSjeremylt return 0; 3285fe0d4faSjeremylt } 3295fe0d4faSjeremylt 3304ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 3314ce2993fSjeremylt (*rstr)->ceed = ceed; 332d7b241e6Sjeremylt ceed->refcount++; 3334ce2993fSjeremylt (*rstr)->refcount = 1; 3344ce2993fSjeremylt (*rstr)->nelem = nelem; 3354ce2993fSjeremylt (*rstr)->elemsize = elemsize; 3364ce2993fSjeremylt (*rstr)->ncomp = ncomp; 337d979a051Sjeremylt (*rstr)->lsize = lsize; 3384ce2993fSjeremylt (*rstr)->nblk = nelem; 3394ce2993fSjeremylt (*rstr)->blksize = 1; 3407509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 3417509a596Sjeremylt for (int i = 0; i<3; i++) 3427509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 3431dfeef1dSjeremylt ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 3441dfeef1dSjeremylt *rstr); 3454b8bea3bSJed Brown CeedChk(ierr); 346d7b241e6Sjeremylt return 0; 347d7b241e6Sjeremylt } 348d7b241e6Sjeremylt 349d7b241e6Sjeremylt /** 350b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 351d7b241e6Sjeremylt 352d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 353d979a051Sjeremylt @param nelem Number of elements described in the @a offsets array. 354b11c1e72Sjeremylt @param elemsize Size (number of unknowns) per element 355b11c1e72Sjeremylt @param blksize Number of elements in a block 35695bb1877Svaleriabarra @param ncomp Number of field components per interpolation node 35795bb1877Svaleriabarra (1 for scalar fields) 358d979a051Sjeremylt @param compstride Stride between components for the same L-vector "node". 359d979a051Sjeremylt Data for node i, component k can be found in the L-vector 360d979a051Sjeremylt at index [offsets[i] + k*compstride]. 361d979a051Sjeremylt @param lsize The size of the L-vector. This vector may be larger than 362d979a051Sjeremylt the elements and fields given by this restriction. 363d979a051Sjeremylt @param mtype Memory type of the @a offsets array, see CeedMemType 364d979a051Sjeremylt @param cmode Copy mode for the @a offsets array, see CeedCopyMode 365d979a051Sjeremylt @param offsets Array of shape [@a nelem, @a elemsize]. Row i holds the 366d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 3678795c945Sjeremylt for the unknowns corresponding to element i, where 368d979a051Sjeremylt 0 <= i < @a nelem. All offsets must be in the range 369d979a051Sjeremylt [0, @a lsize - 1]. The backend will permute and pad this 3708795c945Sjeremylt array to the desired ordering for the blocksize, which is 3718795c945Sjeremylt typically given by the backend. The default reordering is 3728795c945Sjeremylt to interlace elements. 3734ce2993fSjeremylt @param rstr Address of the variable where the newly created 374b11c1e72Sjeremylt CeedElemRestriction will be stored 375d7b241e6Sjeremylt 376b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 377dfdf5a53Sjeremylt 3787a982d89SJeremy L. Thompson @ref Backend 379b11c1e72Sjeremylt **/ 380d979a051Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize, 381d979a051Sjeremylt CeedInt blksize, CeedInt ncomp, 382d979a051Sjeremylt CeedInt compstride, CeedInt lsize, 383d979a051Sjeremylt CeedMemType mtype, CeedCopyMode cmode, 384d979a051Sjeremylt const CeedInt *offsets, 3854ce2993fSjeremylt CeedElemRestriction *rstr) { 386d7b241e6Sjeremylt int ierr; 387d979a051Sjeremylt CeedInt *blkoffsets; 388d7b241e6Sjeremylt CeedInt nblk = (nelem / blksize) + !!(nelem % blksize); 389d7b241e6Sjeremylt 3905fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 3915fe0d4faSjeremylt Ceed delegate; 392aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 393aefd8378Sjeremylt CeedChk(ierr); 3945fe0d4faSjeremylt 3955fe0d4faSjeremylt if (!delegate) 396c042f62fSJeremy L Thompson // LCOV_EXCL_START 3971d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support " 3981d102b48SJeremy L Thompson "ElemRestrictionCreateBlocked"); 399c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 4005fe0d4faSjeremylt 401d979a051Sjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize, blksize, 402d979a051Sjeremylt ncomp, compstride, lsize, mtype, 403d979a051Sjeremylt cmode, offsets, rstr); 404d979a051Sjeremylt CeedChk(ierr); 4055fe0d4faSjeremylt return 0; 4065fe0d4faSjeremylt } 407d7b241e6Sjeremylt 4084ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 409d7b241e6Sjeremylt 410d979a051Sjeremylt ierr = CeedCalloc(nblk*blksize*elemsize, &blkoffsets); CeedChk(ierr); 411d979a051Sjeremylt ierr = CeedPermutePadOffsets(offsets, blkoffsets, nblk, nelem, blksize, 4124b8bea3bSJed Brown elemsize); 413dfdf5a53Sjeremylt CeedChk(ierr); 414d7b241e6Sjeremylt 4154ce2993fSjeremylt (*rstr)->ceed = ceed; 416d7b241e6Sjeremylt ceed->refcount++; 4174ce2993fSjeremylt (*rstr)->refcount = 1; 4184ce2993fSjeremylt (*rstr)->nelem = nelem; 4194ce2993fSjeremylt (*rstr)->elemsize = elemsize; 4204ce2993fSjeremylt (*rstr)->ncomp = ncomp; 421d979a051Sjeremylt (*rstr)->compstride = compstride; 422d979a051Sjeremylt (*rstr)->lsize = lsize; 4234ce2993fSjeremylt (*rstr)->nblk = nblk; 4244ce2993fSjeremylt (*rstr)->blksize = blksize; 425667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 426d979a051Sjeremylt (const CeedInt *) blkoffsets, *rstr); CeedChk(ierr); 427d7b241e6Sjeremylt 4281d102b48SJeremy L Thompson if (cmode == CEED_OWN_POINTER) { 429d979a051Sjeremylt ierr = CeedFree(&offsets); CeedChk(ierr); 4301d102b48SJeremy L Thompson } 431d7b241e6Sjeremylt 432d7b241e6Sjeremylt return 0; 433d7b241e6Sjeremylt } 434d7b241e6Sjeremylt 435b11c1e72Sjeremylt /** 4367509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 4377509a596Sjeremylt 4387509a596Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 4397509a596Sjeremylt @param nelem Number of elements described by the restriction 4407509a596Sjeremylt @param elemsize Size (number of "nodes") per element 4417509a596Sjeremylt @param blksize Number of elements in a block 4427509a596Sjeremylt @param ncomp Number of field components per interpolation node 4437509a596Sjeremylt (1 for scalar fields) 444d979a051Sjeremylt @param lsize The size of the L-vector. This vector may be larger than 445d979a051Sjeremylt the elements and fields given by this restriction. 4467509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 4477509a596Sjeremylt The data for node i, component j, element k in the 4487509a596Sjeremylt L-vector is given by 4497509a596Sjeremylt i*strides[0] + j*strides[1] + k*strides[2] 4507509a596Sjeremylt @param rstr Address of the variable where the newly created 4517509a596Sjeremylt CeedElemRestriction will be stored 4527509a596Sjeremylt 4537509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 4547509a596Sjeremylt 4557a982d89SJeremy L. Thompson @ref User 4567509a596Sjeremylt **/ 4577509a596Sjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt nelem, 458d979a051Sjeremylt CeedInt elemsize, CeedInt blksize, CeedInt ncomp, CeedInt lsize, 4598621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 4607509a596Sjeremylt int ierr; 4617509a596Sjeremylt CeedInt nblk = (nelem / blksize) + !!(nelem % blksize); 4627509a596Sjeremylt 4637509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 4647509a596Sjeremylt Ceed delegate; 4657509a596Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 4667509a596Sjeremylt CeedChk(ierr); 4677509a596Sjeremylt 4687509a596Sjeremylt if (!delegate) 4697509a596Sjeremylt // LCOV_EXCL_START 4707509a596Sjeremylt return CeedError(ceed, 1, "Backend does not support " 4717509a596Sjeremylt "ElemRestrictionCreateBlocked"); 4727509a596Sjeremylt // LCOV_EXCL_STOP 4737509a596Sjeremylt 4747509a596Sjeremylt ierr = CeedElemRestrictionCreateBlockedStrided(delegate, nelem, elemsize, 475d979a051Sjeremylt blksize, ncomp, lsize, strides, rstr); 4767509a596Sjeremylt CeedChk(ierr); 4777509a596Sjeremylt return 0; 4787509a596Sjeremylt } 4797509a596Sjeremylt 4807509a596Sjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 4817509a596Sjeremylt 4827509a596Sjeremylt (*rstr)->ceed = ceed; 4837509a596Sjeremylt ceed->refcount++; 4847509a596Sjeremylt (*rstr)->refcount = 1; 4857509a596Sjeremylt (*rstr)->nelem = nelem; 4867509a596Sjeremylt (*rstr)->elemsize = elemsize; 4877509a596Sjeremylt (*rstr)->ncomp = ncomp; 488d979a051Sjeremylt (*rstr)->lsize = lsize; 4897509a596Sjeremylt (*rstr)->nblk = nblk; 4907509a596Sjeremylt (*rstr)->blksize = blksize; 4917509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 4927509a596Sjeremylt for (int i = 0; i<3; i++) 4937509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 4947509a596Sjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 4957509a596Sjeremylt NULL, *rstr); CeedChk(ierr); 4967509a596Sjeremylt 4977509a596Sjeremylt return 0; 4987509a596Sjeremylt } 4997509a596Sjeremylt 5007509a596Sjeremylt /** 501b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 502b11c1e72Sjeremylt 5034ce2993fSjeremylt @param rstr CeedElemRestriction 504b11c1e72Sjeremylt @param lvec The address of the L-vector to be created, or NULL 505b11c1e72Sjeremylt @param evec The address of the E-vector to be created, or NULL 506b11c1e72Sjeremylt 507b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 508dfdf5a53Sjeremylt 5097a982d89SJeremy L. Thompson @ref User 510b11c1e72Sjeremylt **/ 5114ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec, 512d7b241e6Sjeremylt CeedVector *evec) { 513d7b241e6Sjeremylt int ierr; 514d7b241e6Sjeremylt CeedInt n, m; 515d979a051Sjeremylt m = rstr->lsize; 5164ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 517d7b241e6Sjeremylt if (lvec) { 5184ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr); 519d7b241e6Sjeremylt } 520d7b241e6Sjeremylt if (evec) { 5214ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr); 522d7b241e6Sjeremylt } 523d7b241e6Sjeremylt return 0; 524d7b241e6Sjeremylt } 525d7b241e6Sjeremylt 526d7b241e6Sjeremylt /** 527d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 528d7b241e6Sjeremylt 5294ce2993fSjeremylt @param rstr CeedElemRestriction 530d7b241e6Sjeremylt @param tmode Apply restriction or transpose 531d979a051Sjeremylt @param u Input vector (of size @a lsize when tmode=CEED_NOTRANSPOSE) 532a8d32208Sjeremylt @param ru Output vector (of shape [@a nelem * @a elemsize] when 5337aaeacdcSjeremylt tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided 5347aaeacdcSjeremylt by the backend. 535d7b241e6Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 536b11c1e72Sjeremylt 537b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 538dfdf5a53Sjeremylt 5397a982d89SJeremy L. Thompson @ref User 540b11c1e72Sjeremylt **/ 5414ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode, 542a8d32208Sjeremylt CeedVector u, CeedVector ru, 543a8d32208Sjeremylt CeedRequest *request) { 544d7b241e6Sjeremylt CeedInt m,n; 545d7b241e6Sjeremylt int ierr; 546d7b241e6Sjeremylt 547d7b241e6Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 5484ce2993fSjeremylt m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 549d979a051Sjeremylt n = rstr->lsize; 550d7b241e6Sjeremylt } else { 551d979a051Sjeremylt m = rstr->lsize; 5524ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 553d7b241e6Sjeremylt } 554d7b241e6Sjeremylt if (n != u->length) 555c042f62fSJeremy L Thompson // LCOV_EXCL_START 5561d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 5571d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 558c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 559a8d32208Sjeremylt if (m != ru->length) 560c042f62fSJeremy L Thompson // LCOV_EXCL_START 5611d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 562a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 563c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 564074cb416Sjeremylt ierr = rstr->Apply(rstr, tmode, u, ru, request); CeedChk(ierr); 565d7b241e6Sjeremylt 566d7b241e6Sjeremylt return 0; 567d7b241e6Sjeremylt } 568d7b241e6Sjeremylt 569d7b241e6Sjeremylt /** 570d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 571be9261b7Sjeremylt 572be9261b7Sjeremylt @param rstr CeedElemRestriction 5731f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 5741f37b403Sjeremylt elements [0 : blksize] and block=3 will handle elements 5751f37b403Sjeremylt [3*blksize : 4*blksize] 576be9261b7Sjeremylt @param tmode Apply restriction or transpose 577d979a051Sjeremylt @param u Input vector (of size @a lsize when tmode=CEED_NOTRANSPOSE) 578a8d32208Sjeremylt @param ru Output vector (of shape [@a blksize * @a elemsize] when 5797aaeacdcSjeremylt tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided 5807aaeacdcSjeremylt by the backend. 581be9261b7Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 582be9261b7Sjeremylt 583be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 584be9261b7Sjeremylt 5857a982d89SJeremy L. Thompson @ref Backend 586be9261b7Sjeremylt **/ 587be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 588a8d32208Sjeremylt CeedTransposeMode tmode, CeedVector u, 589a8d32208Sjeremylt CeedVector ru, CeedRequest *request) { 590be9261b7Sjeremylt CeedInt m,n; 591be9261b7Sjeremylt int ierr; 592be9261b7Sjeremylt 593be9261b7Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 594be9261b7Sjeremylt m = rstr->blksize * rstr->elemsize * rstr->ncomp; 595d979a051Sjeremylt n = rstr->lsize; 596be9261b7Sjeremylt } else { 597d979a051Sjeremylt m = rstr->lsize; 598be9261b7Sjeremylt n = rstr->blksize * rstr->elemsize * rstr->ncomp; 599be9261b7Sjeremylt } 600be9261b7Sjeremylt if (n != u->length) 601c042f62fSJeremy L Thompson // LCOV_EXCL_START 6021d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 6031d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 604c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 605a8d32208Sjeremylt if (m != ru->length) 606c042f62fSJeremy L Thompson // LCOV_EXCL_START 6071d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 608a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 609c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 610be9261b7Sjeremylt if (rstr->blksize*block > rstr->nelem) 611c042f62fSJeremy L Thompson // LCOV_EXCL_START 6121d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > " 6131d102b48SJeremy L Thompson "total elements %d", block, rstr->blksize*block, 6141d102b48SJeremy L Thompson rstr->nelem); 615c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 616074cb416Sjeremylt ierr = rstr->ApplyBlock(rstr, block, tmode, u, ru, request); 617be9261b7Sjeremylt CeedChk(ierr); 618be9261b7Sjeremylt 619be9261b7Sjeremylt return 0; 620be9261b7Sjeremylt } 621be9261b7Sjeremylt 622be9261b7Sjeremylt /** 623d979a051Sjeremylt @brief Get the L-vector component stride 624a681ae63Sjeremylt 625a681ae63Sjeremylt @param rstr CeedElemRestriction 626d979a051Sjeremylt @param[out] compstride Variable to store component stride 627a681ae63Sjeremylt 628a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 629a681ae63Sjeremylt 630a681ae63Sjeremylt @ref Backend 631a681ae63Sjeremylt **/ 632d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, 633d979a051Sjeremylt CeedInt *compstride) { 634d979a051Sjeremylt *compstride = rstr->compstride; 635a681ae63Sjeremylt return 0; 636a681ae63Sjeremylt } 637a681ae63Sjeremylt 638a681ae63Sjeremylt /** 639a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 640a681ae63Sjeremylt 641a681ae63Sjeremylt @param rstr CeedElemRestriction 642a681ae63Sjeremylt @param[out] numelem Variable to store number of elements 643a681ae63Sjeremylt 644a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 645a681ae63Sjeremylt 646a681ae63Sjeremylt @ref Backend 647a681ae63Sjeremylt **/ 648a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 649a681ae63Sjeremylt CeedInt *numelem) { 650a681ae63Sjeremylt *numelem = rstr->nelem; 651a681ae63Sjeremylt return 0; 652a681ae63Sjeremylt } 653a681ae63Sjeremylt 654a681ae63Sjeremylt /** 655a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 656a681ae63Sjeremylt 657a681ae63Sjeremylt @param rstr CeedElemRestriction 658a681ae63Sjeremylt @param[out] elemsize Variable to store size of elements 659a681ae63Sjeremylt 660a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 661a681ae63Sjeremylt 662a681ae63Sjeremylt @ref Backend 663a681ae63Sjeremylt **/ 664a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 665a681ae63Sjeremylt CeedInt *elemsize) { 666a681ae63Sjeremylt *elemsize = rstr->elemsize; 667a681ae63Sjeremylt return 0; 668a681ae63Sjeremylt } 669a681ae63Sjeremylt 670a681ae63Sjeremylt /** 671d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 672a681ae63Sjeremylt 673a681ae63Sjeremylt @param rstr CeedElemRestriction 674a681ae63Sjeremylt @param[out] numnodes Variable to store number of nodes 675a681ae63Sjeremylt 676a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 677a681ae63Sjeremylt 678a681ae63Sjeremylt @ref Backend 679a681ae63Sjeremylt **/ 680d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, 681d979a051Sjeremylt CeedInt *lsize) { 682d979a051Sjeremylt *lsize = rstr->lsize; 683a681ae63Sjeremylt return 0; 684a681ae63Sjeremylt } 685a681ae63Sjeremylt 686a681ae63Sjeremylt /** 687a681ae63Sjeremylt @brief Get the number of components in the elements of a 688a681ae63Sjeremylt CeedElemRestriction 689a681ae63Sjeremylt 690a681ae63Sjeremylt @param rstr CeedElemRestriction 691a681ae63Sjeremylt @param[out] numcomp Variable to store number of components 692a681ae63Sjeremylt 693a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 694a681ae63Sjeremylt 695a681ae63Sjeremylt @ref Backend 696a681ae63Sjeremylt **/ 697a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 698a681ae63Sjeremylt CeedInt *numcomp) { 699a681ae63Sjeremylt *numcomp = rstr->ncomp; 700a681ae63Sjeremylt return 0; 701a681ae63Sjeremylt } 702a681ae63Sjeremylt 703a681ae63Sjeremylt /** 704a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 705a681ae63Sjeremylt 706a681ae63Sjeremylt @param rstr CeedElemRestriction 707a681ae63Sjeremylt @param[out] numblock Variable to store number of blocks 708a681ae63Sjeremylt 709a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 710a681ae63Sjeremylt 711a681ae63Sjeremylt @ref Backend 712a681ae63Sjeremylt **/ 713a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 714a681ae63Sjeremylt CeedInt *numblock) { 715a681ae63Sjeremylt *numblock = rstr->nblk; 716a681ae63Sjeremylt return 0; 717a681ae63Sjeremylt } 718a681ae63Sjeremylt 719a681ae63Sjeremylt /** 720a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 721a681ae63Sjeremylt 722a681ae63Sjeremylt @param rstr CeedElemRestriction 723a681ae63Sjeremylt @param[out] blksize Variable to store size of blocks 724a681ae63Sjeremylt 725a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 726a681ae63Sjeremylt 727a681ae63Sjeremylt @ref Backend 728a681ae63Sjeremylt **/ 729a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 730a681ae63Sjeremylt CeedInt *blksize) { 731a681ae63Sjeremylt *blksize = rstr->blksize; 732a681ae63Sjeremylt return 0; 733a681ae63Sjeremylt } 734a681ae63Sjeremylt 735a681ae63Sjeremylt /** 736d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 7371469ee4dSjeremylt 7381469ee4dSjeremylt @param rstr CeedElemRestriction 739d979a051Sjeremylt @param[out] mult Vector to store multiplicity (of size lsize) 7401469ee4dSjeremylt 7411469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 7421469ee4dSjeremylt 7437a982d89SJeremy L. Thompson @ref User 7441469ee4dSjeremylt **/ 7451469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 7461469ee4dSjeremylt CeedVector mult) { 7471469ee4dSjeremylt int ierr; 7481469ee4dSjeremylt CeedVector evec; 7491469ee4dSjeremylt 7501469ee4dSjeremylt // Create and set evec 7511469ee4dSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr); 7521469ee4dSjeremylt ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr); 753fa9eac48SJed Brown ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr); 7541469ee4dSjeremylt 7551469ee4dSjeremylt // Apply to get multiplicity 756a8d32208Sjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult, 757efc78312Sjeremylt CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 7581469ee4dSjeremylt 7591469ee4dSjeremylt // Cleanup 7601469ee4dSjeremylt ierr = CeedVectorDestroy(&evec); CeedChk(ierr); 7611469ee4dSjeremylt 7621469ee4dSjeremylt return 0; 7631469ee4dSjeremylt } 7641469ee4dSjeremylt 7651469ee4dSjeremylt /** 766f02ca4a2SJed Brown @brief View a CeedElemRestriction 767f02ca4a2SJed Brown 768f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 769f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 770f02ca4a2SJed Brown 771f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 772f02ca4a2SJed Brown 7737a982d89SJeremy L. Thompson @ref User 774f02ca4a2SJed Brown **/ 775f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 7767509a596Sjeremylt char stridesstr[500]; 7777509a596Sjeremylt if (rstr->strides) 7787509a596Sjeremylt sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1], 7797509a596Sjeremylt rstr->strides[2]); 780d979a051Sjeremylt else 781d979a051Sjeremylt sprintf(stridesstr, "%d", rstr->compstride); 7827509a596Sjeremylt 7830036de2cSjeremylt fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d " 7840036de2cSjeremylt "nodes each and %s %s\n", rstr->blksize > 1 ? "Blocked " : "", 785d979a051Sjeremylt rstr->lsize, rstr->ncomp, rstr->nelem, rstr->elemsize, 786d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 787f02ca4a2SJed Brown return 0; 788f02ca4a2SJed Brown } 789f02ca4a2SJed Brown 790f02ca4a2SJed Brown /** 791b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 792b11c1e72Sjeremylt 7934ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 794b11c1e72Sjeremylt 795b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 796dfdf5a53Sjeremylt 7977a982d89SJeremy L. Thompson @ref User 798b11c1e72Sjeremylt **/ 7994ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 800d7b241e6Sjeremylt int ierr; 801d7b241e6Sjeremylt 8021d102b48SJeremy L Thompson if (!*rstr || --(*rstr)->refcount > 0) 8031d102b48SJeremy L Thompson return 0; 804*430758c8SJeremy L Thompson if ((*rstr)->numreaders) 805*430758c8SJeremy L Thompson return CeedError((*rstr)->ceed, 1, "Cannot destroy CeedElemRestriction, " 806*430758c8SJeremy L Thompson "a process has read access to the offset data"); 8074ce2993fSjeremylt if ((*rstr)->Destroy) { 8084ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 809d7b241e6Sjeremylt } 8107509a596Sjeremylt ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr); 8114ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 8124ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 813d7b241e6Sjeremylt return 0; 814d7b241e6Sjeremylt } 815d7b241e6Sjeremylt 816d7b241e6Sjeremylt /// @} 817