xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-elemrestriction.c (revision 4cc79fe70fe13506f62e0311519fe21991219aa8)
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);
128430758c8SJeremy L Thompson   rstr->numreaders++;
129430758c8SJeremy L Thompson   return 0;
130430758c8SJeremy L Thompson }
131430758c8SJeremy L Thompson 
132430758c8SJeremy L Thompson /**
133430758c8SJeremy L Thompson   @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets()
134430758c8SJeremy L Thompson 
135430758c8SJeremy L Thompson   @param rstr    CeedElemRestriction to restore
136430758c8SJeremy L Thompson   @param offsets Array of offset data
137430758c8SJeremy L Thompson 
138430758c8SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
139430758c8SJeremy L Thompson 
140430758c8SJeremy L Thompson   @ref User
141430758c8SJeremy L Thompson **/
142430758c8SJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr,
143430758c8SJeremy L Thompson                                       const CeedInt **offsets) {
144430758c8SJeremy L Thompson   *offsets = NULL;
145430758c8SJeremy L Thompson   rstr->numreaders--;
146bd33150aSjeremylt   return 0;
147bd33150aSjeremylt }
148bd33150aSjeremylt 
149bd33150aSjeremylt /**
1503ac43b2cSJeremy L Thompson   @brief Get the strided status of a CeedElemRestriction
1513ac43b2cSJeremy L Thompson 
1523ac43b2cSJeremy L Thompson   @param rstr             CeedElemRestriction
1533ac43b2cSJeremy L Thompson   @param[out] status      Variable to store strided status, 1 if strided else 0
1543ac43b2cSJeremy L Thompson 
1553ac43b2cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1563ac43b2cSJeremy L Thompson 
1573ac43b2cSJeremy L Thompson   @ref Backend
1583ac43b2cSJeremy L Thompson **/
1593ac43b2cSJeremy L Thompson int CeedElemRestrictionGetStridedStatus(CeedElemRestriction rstr,
1603ac43b2cSJeremy L Thompson                                         bool *status) {
1613ac43b2cSJeremy L Thompson   *status = rstr->strides ? 1 : 0;
1623ac43b2cSJeremy L Thompson   return 0;
1633ac43b2cSJeremy L Thompson }
1643ac43b2cSJeremy L Thompson 
1653ac43b2cSJeremy L Thompson /**
166a681ae63Sjeremylt   @brief Get the backend stride status of a CeedElemRestriction
1677a982d89SJeremy L. Thompson 
1687a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
169a681ae63Sjeremylt   @param[out] status      Variable to store stride status
1707a982d89SJeremy L. Thompson 
1717a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
1727a982d89SJeremy L. Thompson 
1737a982d89SJeremy L. Thompson   @ref Backend
1747a982d89SJeremy L. Thompson **/
175a681ae63Sjeremylt int CeedElemRestrictionGetBackendStridesStatus(CeedElemRestriction rstr,
176a681ae63Sjeremylt     bool *status) {
177a681ae63Sjeremylt   if (!rstr->strides)
178a681ae63Sjeremylt     // LCOV_EXCL_START
179a681ae63Sjeremylt     return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data");
180a681ae63Sjeremylt   // LCOV_EXCL_STOP
1817a982d89SJeremy L. Thompson 
182a681ae63Sjeremylt   *status = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) &&
183a681ae63Sjeremylt              (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) &&
184a681ae63Sjeremylt              (rstr->strides[2] == CEED_STRIDES_BACKEND[2]));
1857a982d89SJeremy L. Thompson   return 0;
1867a982d89SJeremy L. Thompson }
1877a982d89SJeremy L. Thompson 
1887a982d89SJeremy L. Thompson /**
1897a982d89SJeremy L. Thompson   @brief Get the backend data of a CeedElemRestriction
1907a982d89SJeremy L. Thompson 
1917a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
1927a982d89SJeremy L. Thompson   @param[out] data        Variable to store data
1937a982d89SJeremy L. Thompson 
1947a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
1957a982d89SJeremy L. Thompson 
1967a982d89SJeremy L. Thompson   @ref Backend
1977a982d89SJeremy L. Thompson **/
1987a982d89SJeremy L. Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) {
1997a982d89SJeremy L. Thompson   *data = rstr->data;
2007a982d89SJeremy L. Thompson   return 0;
2017a982d89SJeremy L. Thompson }
2027a982d89SJeremy L. Thompson 
2037a982d89SJeremy L. Thompson /**
2047a982d89SJeremy L. Thompson   @brief Set the backend data of a CeedElemRestriction
2057a982d89SJeremy L. Thompson 
2067a982d89SJeremy L. Thompson   @param[out] rstr        CeedElemRestriction
2077a982d89SJeremy L. Thompson   @param data             Data to set
2087a982d89SJeremy L. Thompson 
2097a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
2107a982d89SJeremy L. Thompson 
2117a982d89SJeremy L. Thompson   @ref Backend
2127a982d89SJeremy L. Thompson **/
2137a982d89SJeremy L. Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) {
2147a982d89SJeremy L. Thompson   rstr->data = *data;
2157a982d89SJeremy L. Thompson   return 0;
2167a982d89SJeremy L. Thompson }
2177a982d89SJeremy L. Thompson 
2187a982d89SJeremy L. Thompson /// @}
2197a982d89SJeremy L. Thompson 
22015910d16Sjeremylt /// @cond DOXYGEN_SKIP
22115910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none;
22215910d16Sjeremylt /// @endcond
22315910d16Sjeremylt 
2247a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2257a982d89SJeremy L. Thompson /// CeedElemRestriction Public API
2267a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2277a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser
228d7b241e6Sjeremylt /// @{
229d7b241e6Sjeremylt 
2307a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend
2317a982d89SJeremy L. Thompson const CeedInt CEED_STRIDES_BACKEND[3] = {};
2327a982d89SJeremy L. Thompson 
233*4cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user
2347a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE =
2357a982d89SJeremy L. Thompson   &ceed_elemrestriction_none;
2367a982d89SJeremy L. Thompson 
237d7b241e6Sjeremylt /**
238b11c1e72Sjeremylt   @brief Create a CeedElemRestriction
239d7b241e6Sjeremylt 
240b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
241d979a051Sjeremylt   @param nelem      Number of elements described in the @a offsets array
242b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
243b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
24495bb1877Svaleriabarra                       (1 for scalar fields)
245d979a051Sjeremylt   @param compstride Stride between components for the same L-vector "node".
246d979a051Sjeremylt                       Data for node i, component k can be found in the L-vector
247d979a051Sjeremylt                       at index [offsets[i] + k*compstride].
248d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
249d979a051Sjeremylt                       the elements and fields given by this restriction.
250d979a051Sjeremylt   @param mtype      Memory type of the @a offsets array, see CeedMemType
251d979a051Sjeremylt   @param cmode      Copy mode for the @a offsets array, see CeedCopyMode
252d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
253d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
2548795c945Sjeremylt                       for the unknowns corresponding to element i, where
255d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
256d979a051Sjeremylt                       [0, @a lsize - 1].
2574ce2993fSjeremylt   @param[out] rstr  Address of the variable where the newly created
258b11c1e72Sjeremylt                       CeedElemRestriction will be stored
259d7b241e6Sjeremylt 
260b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
261dfdf5a53Sjeremylt 
2627a982d89SJeremy L. Thompson   @ref User
263b11c1e72Sjeremylt **/
264d979a051Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem, CeedInt elemsize,
265d979a051Sjeremylt                               CeedInt ncomp, CeedInt compstride,
266d979a051Sjeremylt                               CeedInt lsize, CeedMemType mtype,
267d979a051Sjeremylt                               CeedCopyMode cmode, const CeedInt *offsets,
2684ce2993fSjeremylt                               CeedElemRestriction *rstr) {
269d7b241e6Sjeremylt   int ierr;
270d7b241e6Sjeremylt 
2715fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
2725fe0d4faSjeremylt     Ceed delegate;
273aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
274aefd8378Sjeremylt     CeedChk(ierr);
2755fe0d4faSjeremylt 
2765fe0d4faSjeremylt     if (!delegate)
277c042f62fSJeremy L Thompson       // LCOV_EXCL_START
278d7b241e6Sjeremylt       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
279c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
2805fe0d4faSjeremylt 
281d979a051Sjeremylt     ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize, ncomp,
282d979a051Sjeremylt                                      compstride, lsize, mtype, cmode,
283d979a051Sjeremylt                                      offsets, rstr); CeedChk(ierr);
2845fe0d4faSjeremylt     return 0;
2855fe0d4faSjeremylt   }
2865fe0d4faSjeremylt 
2874ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
2884ce2993fSjeremylt   (*rstr)->ceed = ceed;
289d7b241e6Sjeremylt   ceed->refcount++;
2904ce2993fSjeremylt   (*rstr)->refcount = 1;
2914ce2993fSjeremylt   (*rstr)->nelem = nelem;
2924ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
2934ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
294d979a051Sjeremylt   (*rstr)->compstride = compstride;
295d979a051Sjeremylt   (*rstr)->lsize = lsize;
2964ce2993fSjeremylt   (*rstr)->nblk = nelem;
2974ce2993fSjeremylt   (*rstr)->blksize = 1;
298d979a051Sjeremylt   ierr = ceed->ElemRestrictionCreate(mtype, cmode, offsets, *rstr);
299d979a051Sjeremylt   CeedChk(ierr);
300d7b241e6Sjeremylt   return 0;
301d7b241e6Sjeremylt }
302d7b241e6Sjeremylt 
303d7b241e6Sjeremylt /**
3047509a596Sjeremylt   @brief Create a strided CeedElemRestriction
305d7b241e6Sjeremylt 
306b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
3077509a596Sjeremylt   @param nelem      Number of elements described by the restriction
308b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
309b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
31095bb1877Svaleriabarra                       (1 for scalar fields)
311d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
312d979a051Sjeremylt                       the elements and fields given by this restriction.
3137509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
3147509a596Sjeremylt                       The data for node i, component j, element k in the
3157509a596Sjeremylt                       L-vector is given by
3167509a596Sjeremylt                         i*strides[0] + j*strides[1] + k*strides[2]
3174ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
318b11c1e72Sjeremylt                       CeedElemRestriction will be stored
319d7b241e6Sjeremylt 
320b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
321dfdf5a53Sjeremylt 
3227a982d89SJeremy L. Thompson   @ref User
323b11c1e72Sjeremylt **/
3247509a596Sjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt nelem, CeedInt elemsize,
325d979a051Sjeremylt                                      CeedInt ncomp, CeedInt lsize,
3268621c6c6SJeremy L Thompson                                      const CeedInt strides[3],
327f90c8643Sjeremylt                                      CeedElemRestriction *rstr) {
328d7b241e6Sjeremylt   int ierr;
329d7b241e6Sjeremylt 
3305fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
3315fe0d4faSjeremylt     Ceed delegate;
332aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
333aefd8378Sjeremylt     CeedChk(ierr);
3345fe0d4faSjeremylt 
3355fe0d4faSjeremylt     if (!delegate)
336c042f62fSJeremy L Thompson       // LCOV_EXCL_START
3371d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
338c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3395fe0d4faSjeremylt 
340d979a051Sjeremylt     ierr = CeedElemRestrictionCreateStrided(delegate, nelem, elemsize, ncomp,
341d979a051Sjeremylt                                             lsize, strides, rstr);
342d979a051Sjeremylt     CeedChk(ierr);
3435fe0d4faSjeremylt     return 0;
3445fe0d4faSjeremylt   }
3455fe0d4faSjeremylt 
3464ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
3474ce2993fSjeremylt   (*rstr)->ceed = ceed;
348d7b241e6Sjeremylt   ceed->refcount++;
3494ce2993fSjeremylt   (*rstr)->refcount = 1;
3504ce2993fSjeremylt   (*rstr)->nelem = nelem;
3514ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
3524ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
353d979a051Sjeremylt   (*rstr)->lsize = lsize;
3544ce2993fSjeremylt   (*rstr)->nblk = nelem;
3554ce2993fSjeremylt   (*rstr)->blksize = 1;
3567509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
3577509a596Sjeremylt   for (int i = 0; i<3; i++)
3587509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
3591dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
3601dfeef1dSjeremylt                                      *rstr);
3614b8bea3bSJed Brown   CeedChk(ierr);
362d7b241e6Sjeremylt   return 0;
363d7b241e6Sjeremylt }
364d7b241e6Sjeremylt 
365d7b241e6Sjeremylt /**
366b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
367d7b241e6Sjeremylt 
368d7b241e6Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created.
369d979a051Sjeremylt   @param nelem      Number of elements described in the @a offsets array.
370b11c1e72Sjeremylt   @param elemsize   Size (number of unknowns) per element
371b11c1e72Sjeremylt   @param blksize    Number of elements in a block
37295bb1877Svaleriabarra   @param ncomp      Number of field components per interpolation node
37395bb1877Svaleriabarra                       (1 for scalar fields)
374d979a051Sjeremylt   @param compstride Stride between components for the same L-vector "node".
375d979a051Sjeremylt                       Data for node i, component k can be found in the L-vector
376d979a051Sjeremylt                       at index [offsets[i] + k*compstride].
377d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
378d979a051Sjeremylt                       the elements and fields given by this restriction.
379d979a051Sjeremylt   @param mtype      Memory type of the @a offsets array, see CeedMemType
380d979a051Sjeremylt   @param cmode      Copy mode for the @a offsets array, see CeedCopyMode
381d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
382d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
3838795c945Sjeremylt                       for the unknowns corresponding to element i, where
384d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
385d979a051Sjeremylt                       [0, @a lsize - 1]. The backend will permute and pad this
3868795c945Sjeremylt                       array to the desired ordering for the blocksize, which is
3878795c945Sjeremylt                       typically given by the backend. The default reordering is
3888795c945Sjeremylt                       to interlace elements.
3894ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
390b11c1e72Sjeremylt                       CeedElemRestriction will be stored
391d7b241e6Sjeremylt 
392b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
393dfdf5a53Sjeremylt 
3947a982d89SJeremy L. Thompson   @ref Backend
395b11c1e72Sjeremylt  **/
396d979a051Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize,
397d979a051Sjeremylt                                      CeedInt blksize, CeedInt ncomp,
398d979a051Sjeremylt                                      CeedInt compstride, CeedInt lsize,
399d979a051Sjeremylt                                      CeedMemType mtype, CeedCopyMode cmode,
400d979a051Sjeremylt                                      const CeedInt *offsets,
4014ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
402d7b241e6Sjeremylt   int ierr;
403d979a051Sjeremylt   CeedInt *blkoffsets;
404d7b241e6Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
405d7b241e6Sjeremylt 
4065fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
4075fe0d4faSjeremylt     Ceed delegate;
408aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
409aefd8378Sjeremylt     CeedChk(ierr);
4105fe0d4faSjeremylt 
4115fe0d4faSjeremylt     if (!delegate)
412c042f62fSJeremy L Thompson       // LCOV_EXCL_START
4131d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support "
4141d102b48SJeremy L Thompson                        "ElemRestrictionCreateBlocked");
415c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
4165fe0d4faSjeremylt 
417d979a051Sjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize, blksize,
418d979a051Sjeremylt                                             ncomp, compstride, lsize, mtype,
419d979a051Sjeremylt                                             cmode, offsets, rstr);
420d979a051Sjeremylt     CeedChk(ierr);
4215fe0d4faSjeremylt     return 0;
4225fe0d4faSjeremylt   }
423d7b241e6Sjeremylt 
4244ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
425d7b241e6Sjeremylt 
426d979a051Sjeremylt   ierr = CeedCalloc(nblk*blksize*elemsize, &blkoffsets); CeedChk(ierr);
427d979a051Sjeremylt   ierr = CeedPermutePadOffsets(offsets, blkoffsets, nblk, nelem, blksize,
4284b8bea3bSJed Brown                                elemsize);
429dfdf5a53Sjeremylt   CeedChk(ierr);
430d7b241e6Sjeremylt 
4314ce2993fSjeremylt   (*rstr)->ceed = ceed;
432d7b241e6Sjeremylt   ceed->refcount++;
4334ce2993fSjeremylt   (*rstr)->refcount = 1;
4344ce2993fSjeremylt   (*rstr)->nelem = nelem;
4354ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
4364ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
437d979a051Sjeremylt   (*rstr)->compstride = compstride;
438d979a051Sjeremylt   (*rstr)->lsize = lsize;
4394ce2993fSjeremylt   (*rstr)->nblk = nblk;
4404ce2993fSjeremylt   (*rstr)->blksize = blksize;
441667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
442d979a051Sjeremylt          (const CeedInt *) blkoffsets, *rstr); CeedChk(ierr);
443d7b241e6Sjeremylt 
4441d102b48SJeremy L Thompson   if (cmode == CEED_OWN_POINTER) {
445d979a051Sjeremylt     ierr = CeedFree(&offsets); CeedChk(ierr);
4461d102b48SJeremy L Thompson   }
447d7b241e6Sjeremylt 
448d7b241e6Sjeremylt   return 0;
449d7b241e6Sjeremylt }
450d7b241e6Sjeremylt 
451b11c1e72Sjeremylt /**
4527509a596Sjeremylt   @brief Create a blocked strided CeedElemRestriction
4537509a596Sjeremylt 
4547509a596Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
4557509a596Sjeremylt   @param nelem      Number of elements described by the restriction
4567509a596Sjeremylt   @param elemsize   Size (number of "nodes") per element
4577509a596Sjeremylt   @param blksize    Number of elements in a block
4587509a596Sjeremylt   @param ncomp      Number of field components per interpolation node
4597509a596Sjeremylt                       (1 for scalar fields)
460d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
461d979a051Sjeremylt                       the elements and fields given by this restriction.
4627509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
4637509a596Sjeremylt                       The data for node i, component j, element k in the
4647509a596Sjeremylt                       L-vector is given by
4657509a596Sjeremylt                         i*strides[0] + j*strides[1] + k*strides[2]
4667509a596Sjeremylt   @param rstr       Address of the variable where the newly created
4677509a596Sjeremylt                       CeedElemRestriction will be stored
4687509a596Sjeremylt 
4697509a596Sjeremylt   @return An error code: 0 - success, otherwise - failure
4707509a596Sjeremylt 
4717a982d89SJeremy L. Thompson   @ref User
4727509a596Sjeremylt **/
4737509a596Sjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt nelem,
474d979a051Sjeremylt     CeedInt elemsize, CeedInt blksize, CeedInt ncomp, CeedInt lsize,
4758621c6c6SJeremy L Thompson     const CeedInt strides[3], CeedElemRestriction *rstr) {
4767509a596Sjeremylt   int ierr;
4777509a596Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
4787509a596Sjeremylt 
4797509a596Sjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
4807509a596Sjeremylt     Ceed delegate;
4817509a596Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
4827509a596Sjeremylt     CeedChk(ierr);
4837509a596Sjeremylt 
4847509a596Sjeremylt     if (!delegate)
4857509a596Sjeremylt       // LCOV_EXCL_START
4867509a596Sjeremylt       return CeedError(ceed, 1, "Backend does not support "
4877509a596Sjeremylt                        "ElemRestrictionCreateBlocked");
4887509a596Sjeremylt     // LCOV_EXCL_STOP
4897509a596Sjeremylt 
4907509a596Sjeremylt     ierr = CeedElemRestrictionCreateBlockedStrided(delegate, nelem, elemsize,
491d979a051Sjeremylt            blksize, ncomp, lsize, strides, rstr);
4927509a596Sjeremylt     CeedChk(ierr);
4937509a596Sjeremylt     return 0;
4947509a596Sjeremylt   }
4957509a596Sjeremylt 
4967509a596Sjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
4977509a596Sjeremylt 
4987509a596Sjeremylt   (*rstr)->ceed = ceed;
4997509a596Sjeremylt   ceed->refcount++;
5007509a596Sjeremylt   (*rstr)->refcount = 1;
5017509a596Sjeremylt   (*rstr)->nelem = nelem;
5027509a596Sjeremylt   (*rstr)->elemsize = elemsize;
5037509a596Sjeremylt   (*rstr)->ncomp = ncomp;
504d979a051Sjeremylt   (*rstr)->lsize = lsize;
5057509a596Sjeremylt   (*rstr)->nblk = nblk;
5067509a596Sjeremylt   (*rstr)->blksize = blksize;
5077509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
5087509a596Sjeremylt   for (int i = 0; i<3; i++)
5097509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
5107509a596Sjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
5117509a596Sjeremylt          NULL, *rstr); CeedChk(ierr);
5127509a596Sjeremylt 
5137509a596Sjeremylt   return 0;
5147509a596Sjeremylt }
5157509a596Sjeremylt 
5167509a596Sjeremylt /**
517b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
518b11c1e72Sjeremylt 
5194ce2993fSjeremylt   @param rstr  CeedElemRestriction
520b11c1e72Sjeremylt   @param lvec  The address of the L-vector to be created, or NULL
521b11c1e72Sjeremylt   @param evec  The address of the E-vector to be created, or NULL
522b11c1e72Sjeremylt 
523b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
524dfdf5a53Sjeremylt 
5257a982d89SJeremy L. Thompson   @ref User
526b11c1e72Sjeremylt **/
5274ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec,
528d7b241e6Sjeremylt                                     CeedVector *evec) {
529d7b241e6Sjeremylt   int ierr;
530d7b241e6Sjeremylt   CeedInt n, m;
531d979a051Sjeremylt   m = rstr->lsize;
5324ce2993fSjeremylt   n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
533d7b241e6Sjeremylt   if (lvec) {
5344ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr);
535d7b241e6Sjeremylt   }
536d7b241e6Sjeremylt   if (evec) {
5374ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr);
538d7b241e6Sjeremylt   }
539d7b241e6Sjeremylt   return 0;
540d7b241e6Sjeremylt }
541d7b241e6Sjeremylt 
542d7b241e6Sjeremylt /**
543d9e1f99aSValeria Barra   @brief Restrict an L-vector to an E-vector or apply its transpose
544d7b241e6Sjeremylt 
5454ce2993fSjeremylt   @param rstr    CeedElemRestriction
546d7b241e6Sjeremylt   @param tmode   Apply restriction or transpose
547*4cc79fe7SJed Brown   @param u       Input vector (of size @a lsize when tmode=@ref CEED_NOTRANSPOSE)
548a8d32208Sjeremylt   @param ru      Output vector (of shape [@a nelem * @a elemsize] when
549*4cc79fe7SJed Brown                    tmode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
5507aaeacdcSjeremylt                    by the backend.
551*4cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
552b11c1e72Sjeremylt 
553b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
554dfdf5a53Sjeremylt 
5557a982d89SJeremy L. Thompson   @ref User
556b11c1e72Sjeremylt **/
5574ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode,
558a8d32208Sjeremylt                              CeedVector u, CeedVector ru,
559a8d32208Sjeremylt                              CeedRequest *request) {
560d7b241e6Sjeremylt   CeedInt m,n;
561d7b241e6Sjeremylt   int ierr;
562d7b241e6Sjeremylt 
563d7b241e6Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
5644ce2993fSjeremylt     m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
565d979a051Sjeremylt     n = rstr->lsize;
566d7b241e6Sjeremylt   } else {
567d979a051Sjeremylt     m = rstr->lsize;
5684ce2993fSjeremylt     n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
569d7b241e6Sjeremylt   }
570d7b241e6Sjeremylt   if (n != u->length)
571c042f62fSJeremy L Thompson     // LCOV_EXCL_START
5721d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
5731d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
574c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
575a8d32208Sjeremylt   if (m != ru->length)
576c042f62fSJeremy L Thompson     // LCOV_EXCL_START
5771d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
578a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
579c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
580074cb416Sjeremylt   ierr = rstr->Apply(rstr, tmode, u, ru, request); CeedChk(ierr);
581d7b241e6Sjeremylt 
582d7b241e6Sjeremylt   return 0;
583d7b241e6Sjeremylt }
584d7b241e6Sjeremylt 
585d7b241e6Sjeremylt /**
586d9e1f99aSValeria Barra   @brief Restrict an L-vector to a block of an E-vector or apply its transpose
587be9261b7Sjeremylt 
588be9261b7Sjeremylt   @param rstr    CeedElemRestriction
5891f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
5901f37b403Sjeremylt                    elements [0 : blksize] and block=3 will handle elements
5911f37b403Sjeremylt                    [3*blksize : 4*blksize]
592be9261b7Sjeremylt   @param tmode   Apply restriction or transpose
593*4cc79fe7SJed Brown   @param u       Input vector (of size @a lsize when tmode=@ref CEED_NOTRANSPOSE)
594a8d32208Sjeremylt   @param ru      Output vector (of shape [@a blksize * @a elemsize] when
595*4cc79fe7SJed Brown                    tmode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
5967aaeacdcSjeremylt                    by the backend.
597*4cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
598be9261b7Sjeremylt 
599be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
600be9261b7Sjeremylt 
6017a982d89SJeremy L. Thompson   @ref Backend
602be9261b7Sjeremylt **/
603be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
604a8d32208Sjeremylt                                   CeedTransposeMode tmode, CeedVector u,
605a8d32208Sjeremylt                                   CeedVector ru, CeedRequest *request) {
606be9261b7Sjeremylt   CeedInt m,n;
607be9261b7Sjeremylt   int ierr;
608be9261b7Sjeremylt 
609be9261b7Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
610be9261b7Sjeremylt     m = rstr->blksize * rstr->elemsize * rstr->ncomp;
611d979a051Sjeremylt     n = rstr->lsize;
612be9261b7Sjeremylt   } else {
613d979a051Sjeremylt     m = rstr->lsize;
614be9261b7Sjeremylt     n = rstr->blksize * rstr->elemsize * rstr->ncomp;
615be9261b7Sjeremylt   }
616be9261b7Sjeremylt   if (n != u->length)
617c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6181d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
6191d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
620c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
621a8d32208Sjeremylt   if (m != ru->length)
622c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6231d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
624a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
625c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
626be9261b7Sjeremylt   if (rstr->blksize*block > rstr->nelem)
627c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6281d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > "
6291d102b48SJeremy L Thompson                      "total elements %d", block, rstr->blksize*block,
6301d102b48SJeremy L Thompson                      rstr->nelem);
631c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
632074cb416Sjeremylt   ierr = rstr->ApplyBlock(rstr, block, tmode, u, ru, request);
633be9261b7Sjeremylt   CeedChk(ierr);
634be9261b7Sjeremylt 
635be9261b7Sjeremylt   return 0;
636be9261b7Sjeremylt }
637be9261b7Sjeremylt 
638be9261b7Sjeremylt /**
639d979a051Sjeremylt   @brief Get the L-vector component stride
640a681ae63Sjeremylt 
641a681ae63Sjeremylt   @param rstr             CeedElemRestriction
642d979a051Sjeremylt   @param[out] compstride  Variable to store component stride
643a681ae63Sjeremylt 
644a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
645a681ae63Sjeremylt 
646a681ae63Sjeremylt   @ref Backend
647a681ae63Sjeremylt **/
648d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr,
649d979a051Sjeremylt                                      CeedInt *compstride) {
650d979a051Sjeremylt   *compstride = rstr->compstride;
651a681ae63Sjeremylt   return 0;
652a681ae63Sjeremylt }
653a681ae63Sjeremylt 
654a681ae63Sjeremylt /**
655a681ae63Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
656a681ae63Sjeremylt 
657a681ae63Sjeremylt   @param rstr             CeedElemRestriction
658a681ae63Sjeremylt   @param[out] numelem     Variable to store number of elements
659a681ae63Sjeremylt 
660a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
661a681ae63Sjeremylt 
662a681ae63Sjeremylt   @ref Backend
663a681ae63Sjeremylt **/
664a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
665a681ae63Sjeremylt                                       CeedInt *numelem) {
666a681ae63Sjeremylt   *numelem = rstr->nelem;
667a681ae63Sjeremylt   return 0;
668a681ae63Sjeremylt }
669a681ae63Sjeremylt 
670a681ae63Sjeremylt /**
671a681ae63Sjeremylt   @brief Get the size of elements in the CeedElemRestriction
672a681ae63Sjeremylt 
673a681ae63Sjeremylt   @param rstr             CeedElemRestriction
674a681ae63Sjeremylt   @param[out] elemsize    Variable to store size of elements
675a681ae63Sjeremylt 
676a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
677a681ae63Sjeremylt 
678a681ae63Sjeremylt   @ref Backend
679a681ae63Sjeremylt **/
680a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
681a681ae63Sjeremylt                                       CeedInt *elemsize) {
682a681ae63Sjeremylt   *elemsize = rstr->elemsize;
683a681ae63Sjeremylt   return 0;
684a681ae63Sjeremylt }
685a681ae63Sjeremylt 
686a681ae63Sjeremylt /**
687d979a051Sjeremylt   @brief Get the size of the l-vector for a CeedElemRestriction
688a681ae63Sjeremylt 
689a681ae63Sjeremylt   @param rstr             CeedElemRestriction
690a681ae63Sjeremylt   @param[out] numnodes    Variable to store number of nodes
691a681ae63Sjeremylt 
692a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
693a681ae63Sjeremylt 
694a681ae63Sjeremylt   @ref Backend
695a681ae63Sjeremylt **/
696d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr,
697d979a051Sjeremylt                                       CeedInt *lsize) {
698d979a051Sjeremylt   *lsize = rstr->lsize;
699a681ae63Sjeremylt   return 0;
700a681ae63Sjeremylt }
701a681ae63Sjeremylt 
702a681ae63Sjeremylt /**
703a681ae63Sjeremylt   @brief Get the number of components in the elements of a
704a681ae63Sjeremylt          CeedElemRestriction
705a681ae63Sjeremylt 
706a681ae63Sjeremylt   @param rstr             CeedElemRestriction
707a681ae63Sjeremylt   @param[out] numcomp     Variable to store number of components
708a681ae63Sjeremylt 
709a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
710a681ae63Sjeremylt 
711a681ae63Sjeremylt   @ref Backend
712a681ae63Sjeremylt **/
713a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
714a681ae63Sjeremylt                                         CeedInt *numcomp) {
715a681ae63Sjeremylt   *numcomp = rstr->ncomp;
716a681ae63Sjeremylt   return 0;
717a681ae63Sjeremylt }
718a681ae63Sjeremylt 
719a681ae63Sjeremylt /**
720a681ae63Sjeremylt   @brief Get the number of blocks in a CeedElemRestriction
721a681ae63Sjeremylt 
722a681ae63Sjeremylt   @param rstr             CeedElemRestriction
723a681ae63Sjeremylt   @param[out] numblock    Variable to store number of blocks
724a681ae63Sjeremylt 
725a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
726a681ae63Sjeremylt 
727a681ae63Sjeremylt   @ref Backend
728a681ae63Sjeremylt **/
729a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
730a681ae63Sjeremylt                                     CeedInt *numblock) {
731a681ae63Sjeremylt   *numblock = rstr->nblk;
732a681ae63Sjeremylt   return 0;
733a681ae63Sjeremylt }
734a681ae63Sjeremylt 
735a681ae63Sjeremylt /**
736a681ae63Sjeremylt   @brief Get the size of blocks in the CeedElemRestriction
737a681ae63Sjeremylt 
738a681ae63Sjeremylt   @param rstr             CeedElemRestriction
739a681ae63Sjeremylt   @param[out] blksize     Variable to store size of blocks
740a681ae63Sjeremylt 
741a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
742a681ae63Sjeremylt 
743a681ae63Sjeremylt   @ref Backend
744a681ae63Sjeremylt **/
745a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
746a681ae63Sjeremylt                                     CeedInt *blksize) {
747a681ae63Sjeremylt   *blksize = rstr->blksize;
748a681ae63Sjeremylt   return 0;
749a681ae63Sjeremylt }
750a681ae63Sjeremylt 
751a681ae63Sjeremylt /**
752d9e1f99aSValeria Barra   @brief Get the multiplicity of nodes in a CeedElemRestriction
7531469ee4dSjeremylt 
7541469ee4dSjeremylt   @param rstr             CeedElemRestriction
755d979a051Sjeremylt   @param[out] mult        Vector to store multiplicity (of size lsize)
7561469ee4dSjeremylt 
7571469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
7581469ee4dSjeremylt 
7597a982d89SJeremy L. Thompson   @ref User
7601469ee4dSjeremylt **/
7611469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
7621469ee4dSjeremylt                                        CeedVector mult) {
7631469ee4dSjeremylt   int ierr;
7641469ee4dSjeremylt   CeedVector evec;
7651469ee4dSjeremylt 
7661469ee4dSjeremylt   // Create and set evec
7671469ee4dSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr);
7681469ee4dSjeremylt   ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr);
769fa9eac48SJed Brown   ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr);
7701469ee4dSjeremylt 
7711469ee4dSjeremylt   // Apply to get multiplicity
772a8d32208Sjeremylt   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult,
773efc78312Sjeremylt                                   CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
7741469ee4dSjeremylt 
7751469ee4dSjeremylt   // Cleanup
7761469ee4dSjeremylt   ierr = CeedVectorDestroy(&evec); CeedChk(ierr);
7771469ee4dSjeremylt 
7781469ee4dSjeremylt   return 0;
7791469ee4dSjeremylt }
7801469ee4dSjeremylt 
7811469ee4dSjeremylt /**
782f02ca4a2SJed Brown   @brief View a CeedElemRestriction
783f02ca4a2SJed Brown 
784f02ca4a2SJed Brown   @param[in] rstr    CeedElemRestriction to view
785f02ca4a2SJed Brown   @param[in] stream  Stream to write; typically stdout/stderr or a file
786f02ca4a2SJed Brown 
787f02ca4a2SJed Brown   @return Error code: 0 - success, otherwise - failure
788f02ca4a2SJed Brown 
7897a982d89SJeremy L. Thompson   @ref User
790f02ca4a2SJed Brown **/
791f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
7927509a596Sjeremylt   char stridesstr[500];
7937509a596Sjeremylt   if (rstr->strides)
7947509a596Sjeremylt     sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1],
7957509a596Sjeremylt             rstr->strides[2]);
796d979a051Sjeremylt   else
797d979a051Sjeremylt     sprintf(stridesstr, "%d", rstr->compstride);
7987509a596Sjeremylt 
7990036de2cSjeremylt   fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d "
8000036de2cSjeremylt           "nodes each and %s %s\n", rstr->blksize > 1 ? "Blocked " : "",
801d979a051Sjeremylt           rstr->lsize, rstr->ncomp, rstr->nelem, rstr->elemsize,
802d979a051Sjeremylt           rstr->strides ? "strides" : "component stride", stridesstr);
803f02ca4a2SJed Brown   return 0;
804f02ca4a2SJed Brown }
805f02ca4a2SJed Brown 
806f02ca4a2SJed Brown /**
807b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
808b11c1e72Sjeremylt 
8094ce2993fSjeremylt   @param rstr  CeedElemRestriction to destroy
810b11c1e72Sjeremylt 
811b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
812dfdf5a53Sjeremylt 
8137a982d89SJeremy L. Thompson   @ref User
814b11c1e72Sjeremylt **/
8154ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
816d7b241e6Sjeremylt   int ierr;
817d7b241e6Sjeremylt 
8181d102b48SJeremy L Thompson   if (!*rstr || --(*rstr)->refcount > 0)
8191d102b48SJeremy L Thompson     return 0;
820430758c8SJeremy L Thompson   if ((*rstr)->numreaders)
821430758c8SJeremy L Thompson     return CeedError((*rstr)->ceed, 1, "Cannot destroy CeedElemRestriction, "
822430758c8SJeremy L Thompson                      "a process has read access to the offset data");
8234ce2993fSjeremylt   if ((*rstr)->Destroy) {
8244ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
825d7b241e6Sjeremylt   }
8267509a596Sjeremylt   ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr);
8274ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
8284ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
829d7b241e6Sjeremylt   return 0;
830d7b241e6Sjeremylt }
831d7b241e6Sjeremylt 
832d7b241e6Sjeremylt /// @}
833