xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-elemrestriction.c (revision 430758c82d46a36f0f94ae5e5cf52a5e5bc2b1e9)
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