xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-elemrestriction.c (revision d979a0510f6353f9b8b50621433d53955a3f350a)
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 /**
30*d979a051Sjeremylt   @brief Permute and pad offsets for a blocked restriction
317a982d89SJeremy L. Thompson 
32*d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
33*d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
347a982d89SJeremy L. Thompson                       for the unknowns corresponding to element i, where
35*d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
36*d979a051Sjeremylt                       [0, @a lsize - 1].
37*d979a051Sjeremylt   @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 **/
48*d979a051Sjeremylt 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++)
54*d979a051Sjeremylt         blkoffsets[e*elemsize + k*blksize + j]
55*d979a051Sjeremylt           = 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 /**
106a681ae63Sjeremylt   @brief Get the backend stride status of a CeedElemRestriction
1077a982d89SJeremy L. Thompson 
1087a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
109a681ae63Sjeremylt   @param[out] status      Variable to store stride status
1107a982d89SJeremy L. Thompson 
1117a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
1127a982d89SJeremy L. Thompson 
1137a982d89SJeremy L. Thompson   @ref Backend
1147a982d89SJeremy L. Thompson **/
115a681ae63Sjeremylt int CeedElemRestrictionGetBackendStridesStatus(CeedElemRestriction rstr,
116a681ae63Sjeremylt     bool *status) {
117a681ae63Sjeremylt   if (!rstr->strides)
118a681ae63Sjeremylt     // LCOV_EXCL_START
119a681ae63Sjeremylt     return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data");
120a681ae63Sjeremylt   // LCOV_EXCL_STOP
1217a982d89SJeremy L. Thompson 
122a681ae63Sjeremylt   *status = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) &&
123a681ae63Sjeremylt              (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) &&
124a681ae63Sjeremylt              (rstr->strides[2] == CEED_STRIDES_BACKEND[2]));
1257a982d89SJeremy L. Thompson   return 0;
1267a982d89SJeremy L. Thompson }
1277a982d89SJeremy L. Thompson 
1287a982d89SJeremy L. Thompson /**
1297a982d89SJeremy L. Thompson   @brief Get the backend data of a CeedElemRestriction
1307a982d89SJeremy L. Thompson 
1317a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
1327a982d89SJeremy L. Thompson   @param[out] data        Variable to store data
1337a982d89SJeremy L. Thompson 
1347a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
1357a982d89SJeremy L. Thompson 
1367a982d89SJeremy L. Thompson   @ref Backend
1377a982d89SJeremy L. Thompson **/
1387a982d89SJeremy L. Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) {
1397a982d89SJeremy L. Thompson   *data = rstr->data;
1407a982d89SJeremy L. Thompson   return 0;
1417a982d89SJeremy L. Thompson }
1427a982d89SJeremy L. Thompson 
1437a982d89SJeremy L. Thompson /**
1447a982d89SJeremy L. Thompson   @brief Set the backend data of a CeedElemRestriction
1457a982d89SJeremy L. Thompson 
1467a982d89SJeremy L. Thompson   @param[out] rstr        CeedElemRestriction
1477a982d89SJeremy L. Thompson   @param data             Data to set
1487a982d89SJeremy L. Thompson 
1497a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
1507a982d89SJeremy L. Thompson 
1517a982d89SJeremy L. Thompson   @ref Backend
1527a982d89SJeremy L. Thompson **/
1537a982d89SJeremy L. Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) {
1547a982d89SJeremy L. Thompson   rstr->data = *data;
1557a982d89SJeremy L. Thompson   return 0;
1567a982d89SJeremy L. Thompson }
1577a982d89SJeremy L. Thompson 
1587a982d89SJeremy L. Thompson /// @}
1597a982d89SJeremy L. Thompson 
16015910d16Sjeremylt /// @cond DOXYGEN_SKIP
16115910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none;
16215910d16Sjeremylt /// @endcond
16315910d16Sjeremylt 
1647a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
1657a982d89SJeremy L. Thompson /// CeedElemRestriction Public API
1667a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
1677a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser
168d7b241e6Sjeremylt /// @{
169d7b241e6Sjeremylt 
1707a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend
1717a982d89SJeremy L. Thompson const CeedInt CEED_STRIDES_BACKEND[3] = {};
1727a982d89SJeremy L. Thompson 
1737a982d89SJeremy L. Thompson /// Indicate that no ElemRestriction is provided by the user
1747a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE =
1757a982d89SJeremy L. Thompson   &ceed_elemrestriction_none;
1767a982d89SJeremy L. Thompson 
177d7b241e6Sjeremylt /**
178b11c1e72Sjeremylt   @brief Create a CeedElemRestriction
179d7b241e6Sjeremylt 
180b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
181*d979a051Sjeremylt   @param nelem      Number of elements described in the @a offsets array
182b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
183b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
18495bb1877Svaleriabarra                       (1 for scalar fields)
185*d979a051Sjeremylt   @param compstride Stride between components for the same L-vector "node".
186*d979a051Sjeremylt                       Data for node i, component k can be found in the L-vector
187*d979a051Sjeremylt                       at index [offsets[i] + k*compstride].
188*d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
189*d979a051Sjeremylt                       the elements and fields given by this restriction.
190*d979a051Sjeremylt   @param mtype      Memory type of the @a offsets array, see CeedMemType
191*d979a051Sjeremylt   @param cmode      Copy mode for the @a offsets array, see CeedCopyMode
192*d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
193*d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
1948795c945Sjeremylt                       for the unknowns corresponding to element i, where
195*d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
196*d979a051Sjeremylt                       [0, @a lsize - 1].
1974ce2993fSjeremylt   @param[out] rstr  Address of the variable where the newly created
198b11c1e72Sjeremylt                       CeedElemRestriction will be stored
199d7b241e6Sjeremylt 
200b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
201dfdf5a53Sjeremylt 
2027a982d89SJeremy L. Thompson   @ref User
203b11c1e72Sjeremylt **/
204*d979a051Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem, CeedInt elemsize,
205*d979a051Sjeremylt                               CeedInt ncomp, CeedInt compstride,
206*d979a051Sjeremylt                               CeedInt lsize, CeedMemType mtype,
207*d979a051Sjeremylt                               CeedCopyMode cmode, const CeedInt *offsets,
2084ce2993fSjeremylt                               CeedElemRestriction *rstr) {
209d7b241e6Sjeremylt   int ierr;
210d7b241e6Sjeremylt 
2115fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
2125fe0d4faSjeremylt     Ceed delegate;
213aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
214aefd8378Sjeremylt     CeedChk(ierr);
2155fe0d4faSjeremylt 
2165fe0d4faSjeremylt     if (!delegate)
217c042f62fSJeremy L Thompson       // LCOV_EXCL_START
218d7b241e6Sjeremylt       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
219c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
2205fe0d4faSjeremylt 
221*d979a051Sjeremylt     ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize, ncomp,
222*d979a051Sjeremylt                                      compstride, lsize, mtype, cmode,
223*d979a051Sjeremylt                                      offsets, rstr); CeedChk(ierr);
2245fe0d4faSjeremylt     return 0;
2255fe0d4faSjeremylt   }
2265fe0d4faSjeremylt 
2274ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
2284ce2993fSjeremylt   (*rstr)->ceed = ceed;
229d7b241e6Sjeremylt   ceed->refcount++;
2304ce2993fSjeremylt   (*rstr)->refcount = 1;
2314ce2993fSjeremylt   (*rstr)->nelem = nelem;
2324ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
2334ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
234*d979a051Sjeremylt   (*rstr)->compstride = compstride;
235*d979a051Sjeremylt   (*rstr)->lsize = lsize;
2364ce2993fSjeremylt   (*rstr)->nblk = nelem;
2374ce2993fSjeremylt   (*rstr)->blksize = 1;
238*d979a051Sjeremylt   ierr = ceed->ElemRestrictionCreate(mtype, cmode, offsets, *rstr);
239*d979a051Sjeremylt   CeedChk(ierr);
240d7b241e6Sjeremylt   return 0;
241d7b241e6Sjeremylt }
242d7b241e6Sjeremylt 
243d7b241e6Sjeremylt /**
2447509a596Sjeremylt   @brief Create a strided CeedElemRestriction
245d7b241e6Sjeremylt 
246b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
2477509a596Sjeremylt   @param nelem      Number of elements described by the restriction
248b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
249b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
25095bb1877Svaleriabarra                       (1 for scalar fields)
251*d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
252*d979a051Sjeremylt                       the elements and fields given by this restriction.
2537509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
2547509a596Sjeremylt                       The data for node i, component j, element k in the
2557509a596Sjeremylt                       L-vector is given by
2567509a596Sjeremylt                         i*strides[0] + j*strides[1] + k*strides[2]
2574ce2993fSjeremylt   @param 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 **/
2647509a596Sjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt nelem, CeedInt elemsize,
265*d979a051Sjeremylt                                      CeedInt ncomp, CeedInt lsize,
2668621c6c6SJeremy L Thompson                                      const CeedInt strides[3],
267f90c8643Sjeremylt                                      CeedElemRestriction *rstr) {
268d7b241e6Sjeremylt   int ierr;
269d7b241e6Sjeremylt 
2705fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
2715fe0d4faSjeremylt     Ceed delegate;
272aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
273aefd8378Sjeremylt     CeedChk(ierr);
2745fe0d4faSjeremylt 
2755fe0d4faSjeremylt     if (!delegate)
276c042f62fSJeremy L Thompson       // LCOV_EXCL_START
2771d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
278c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
2795fe0d4faSjeremylt 
280*d979a051Sjeremylt     ierr = CeedElemRestrictionCreateStrided(delegate, nelem, elemsize, ncomp,
281*d979a051Sjeremylt                                             lsize, strides, rstr);
282*d979a051Sjeremylt     CeedChk(ierr);
2835fe0d4faSjeremylt     return 0;
2845fe0d4faSjeremylt   }
2855fe0d4faSjeremylt 
2864ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
2874ce2993fSjeremylt   (*rstr)->ceed = ceed;
288d7b241e6Sjeremylt   ceed->refcount++;
2894ce2993fSjeremylt   (*rstr)->refcount = 1;
2904ce2993fSjeremylt   (*rstr)->nelem = nelem;
2914ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
2924ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
293*d979a051Sjeremylt   (*rstr)->lsize = lsize;
2944ce2993fSjeremylt   (*rstr)->nblk = nelem;
2954ce2993fSjeremylt   (*rstr)->blksize = 1;
2967509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
2977509a596Sjeremylt   for (int i = 0; i<3; i++)
2987509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
2991dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
3001dfeef1dSjeremylt                                      *rstr);
3014b8bea3bSJed Brown   CeedChk(ierr);
302d7b241e6Sjeremylt   return 0;
303d7b241e6Sjeremylt }
304d7b241e6Sjeremylt 
305d7b241e6Sjeremylt /**
306b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
307d7b241e6Sjeremylt 
308d7b241e6Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created.
309*d979a051Sjeremylt   @param nelem      Number of elements described in the @a offsets array.
310b11c1e72Sjeremylt   @param elemsize   Size (number of unknowns) per element
311b11c1e72Sjeremylt   @param blksize    Number of elements in a block
31295bb1877Svaleriabarra   @param ncomp      Number of field components per interpolation node
31395bb1877Svaleriabarra                       (1 for scalar fields)
314*d979a051Sjeremylt   @param compstride Stride between components for the same L-vector "node".
315*d979a051Sjeremylt                       Data for node i, component k can be found in the L-vector
316*d979a051Sjeremylt                       at index [offsets[i] + k*compstride].
317*d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
318*d979a051Sjeremylt                       the elements and fields given by this restriction.
319*d979a051Sjeremylt   @param mtype      Memory type of the @a offsets array, see CeedMemType
320*d979a051Sjeremylt   @param cmode      Copy mode for the @a offsets array, see CeedCopyMode
321*d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
322*d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
3238795c945Sjeremylt                       for the unknowns corresponding to element i, where
324*d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
325*d979a051Sjeremylt                       [0, @a lsize - 1]. The backend will permute and pad this
3268795c945Sjeremylt                       array to the desired ordering for the blocksize, which is
3278795c945Sjeremylt                       typically given by the backend. The default reordering is
3288795c945Sjeremylt                       to interlace elements.
3294ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
330b11c1e72Sjeremylt                       CeedElemRestriction will be stored
331d7b241e6Sjeremylt 
332b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
333dfdf5a53Sjeremylt 
3347a982d89SJeremy L. Thompson   @ref Backend
335b11c1e72Sjeremylt  **/
336*d979a051Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize,
337*d979a051Sjeremylt                                      CeedInt blksize, CeedInt ncomp,
338*d979a051Sjeremylt                                      CeedInt compstride, CeedInt lsize,
339*d979a051Sjeremylt                                      CeedMemType mtype, CeedCopyMode cmode,
340*d979a051Sjeremylt                                      const CeedInt *offsets,
3414ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
342d7b241e6Sjeremylt   int ierr;
343*d979a051Sjeremylt   CeedInt *blkoffsets;
344d7b241e6Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
345d7b241e6Sjeremylt 
3465fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
3475fe0d4faSjeremylt     Ceed delegate;
348aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
349aefd8378Sjeremylt     CeedChk(ierr);
3505fe0d4faSjeremylt 
3515fe0d4faSjeremylt     if (!delegate)
352c042f62fSJeremy L Thompson       // LCOV_EXCL_START
3531d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support "
3541d102b48SJeremy L Thompson                        "ElemRestrictionCreateBlocked");
355c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3565fe0d4faSjeremylt 
357*d979a051Sjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize, blksize,
358*d979a051Sjeremylt                                             ncomp, compstride, lsize, mtype,
359*d979a051Sjeremylt                                             cmode, offsets, rstr);
360*d979a051Sjeremylt     CeedChk(ierr);
3615fe0d4faSjeremylt     return 0;
3625fe0d4faSjeremylt   }
363d7b241e6Sjeremylt 
3644ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
365d7b241e6Sjeremylt 
366*d979a051Sjeremylt   ierr = CeedCalloc(nblk*blksize*elemsize, &blkoffsets); CeedChk(ierr);
367*d979a051Sjeremylt   ierr = CeedPermutePadOffsets(offsets, blkoffsets, nblk, nelem, blksize,
3684b8bea3bSJed Brown                                elemsize);
369dfdf5a53Sjeremylt   CeedChk(ierr);
370d7b241e6Sjeremylt 
3714ce2993fSjeremylt   (*rstr)->ceed = ceed;
372d7b241e6Sjeremylt   ceed->refcount++;
3734ce2993fSjeremylt   (*rstr)->refcount = 1;
3744ce2993fSjeremylt   (*rstr)->nelem = nelem;
3754ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
3764ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
377*d979a051Sjeremylt   (*rstr)->compstride = compstride;
378*d979a051Sjeremylt   (*rstr)->lsize = lsize;
3794ce2993fSjeremylt   (*rstr)->nblk = nblk;
3804ce2993fSjeremylt   (*rstr)->blksize = blksize;
381667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
382*d979a051Sjeremylt          (const CeedInt *) blkoffsets, *rstr); CeedChk(ierr);
383d7b241e6Sjeremylt 
3841d102b48SJeremy L Thompson   if (cmode == CEED_OWN_POINTER) {
385*d979a051Sjeremylt     ierr = CeedFree(&offsets); CeedChk(ierr);
3861d102b48SJeremy L Thompson   }
387d7b241e6Sjeremylt 
388d7b241e6Sjeremylt   return 0;
389d7b241e6Sjeremylt }
390d7b241e6Sjeremylt 
391b11c1e72Sjeremylt /**
3927509a596Sjeremylt   @brief Create a blocked strided CeedElemRestriction
3937509a596Sjeremylt 
3947509a596Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
3957509a596Sjeremylt   @param nelem      Number of elements described by the restriction
3967509a596Sjeremylt   @param elemsize   Size (number of "nodes") per element
3977509a596Sjeremylt   @param blksize    Number of elements in a block
3987509a596Sjeremylt   @param ncomp      Number of field components per interpolation node
3997509a596Sjeremylt                       (1 for scalar fields)
400*d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
401*d979a051Sjeremylt                       the elements and fields given by this restriction.
4027509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
4037509a596Sjeremylt                       The data for node i, component j, element k in the
4047509a596Sjeremylt                       L-vector is given by
4057509a596Sjeremylt                         i*strides[0] + j*strides[1] + k*strides[2]
4067509a596Sjeremylt   @param rstr       Address of the variable where the newly created
4077509a596Sjeremylt                       CeedElemRestriction will be stored
4087509a596Sjeremylt 
4097509a596Sjeremylt   @return An error code: 0 - success, otherwise - failure
4107509a596Sjeremylt 
4117a982d89SJeremy L. Thompson   @ref User
4127509a596Sjeremylt **/
4137509a596Sjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt nelem,
414*d979a051Sjeremylt     CeedInt elemsize, CeedInt blksize, CeedInt ncomp, CeedInt lsize,
4158621c6c6SJeremy L Thompson     const CeedInt strides[3], CeedElemRestriction *rstr) {
4167509a596Sjeremylt   int ierr;
4177509a596Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
4187509a596Sjeremylt 
4197509a596Sjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
4207509a596Sjeremylt     Ceed delegate;
4217509a596Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
4227509a596Sjeremylt     CeedChk(ierr);
4237509a596Sjeremylt 
4247509a596Sjeremylt     if (!delegate)
4257509a596Sjeremylt       // LCOV_EXCL_START
4267509a596Sjeremylt       return CeedError(ceed, 1, "Backend does not support "
4277509a596Sjeremylt                        "ElemRestrictionCreateBlocked");
4287509a596Sjeremylt     // LCOV_EXCL_STOP
4297509a596Sjeremylt 
4307509a596Sjeremylt     ierr = CeedElemRestrictionCreateBlockedStrided(delegate, nelem, elemsize,
431*d979a051Sjeremylt            blksize, ncomp, lsize, strides, rstr);
4327509a596Sjeremylt     CeedChk(ierr);
4337509a596Sjeremylt     return 0;
4347509a596Sjeremylt   }
4357509a596Sjeremylt 
4367509a596Sjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
4377509a596Sjeremylt 
4387509a596Sjeremylt   (*rstr)->ceed = ceed;
4397509a596Sjeremylt   ceed->refcount++;
4407509a596Sjeremylt   (*rstr)->refcount = 1;
4417509a596Sjeremylt   (*rstr)->nelem = nelem;
4427509a596Sjeremylt   (*rstr)->elemsize = elemsize;
4437509a596Sjeremylt   (*rstr)->ncomp = ncomp;
444*d979a051Sjeremylt   (*rstr)->lsize = lsize;
4457509a596Sjeremylt   (*rstr)->nblk = nblk;
4467509a596Sjeremylt   (*rstr)->blksize = blksize;
4477509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
4487509a596Sjeremylt   for (int i = 0; i<3; i++)
4497509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
4507509a596Sjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
4517509a596Sjeremylt          NULL, *rstr); CeedChk(ierr);
4527509a596Sjeremylt 
4537509a596Sjeremylt   return 0;
4547509a596Sjeremylt }
4557509a596Sjeremylt 
4567509a596Sjeremylt /**
457b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
458b11c1e72Sjeremylt 
4594ce2993fSjeremylt   @param rstr  CeedElemRestriction
460b11c1e72Sjeremylt   @param lvec  The address of the L-vector to be created, or NULL
461b11c1e72Sjeremylt   @param evec  The address of the E-vector to be created, or NULL
462b11c1e72Sjeremylt 
463b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
464dfdf5a53Sjeremylt 
4657a982d89SJeremy L. Thompson   @ref User
466b11c1e72Sjeremylt **/
4674ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec,
468d7b241e6Sjeremylt                                     CeedVector *evec) {
469d7b241e6Sjeremylt   int ierr;
470d7b241e6Sjeremylt   CeedInt n, m;
471*d979a051Sjeremylt   m = rstr->lsize;
4724ce2993fSjeremylt   n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
473d7b241e6Sjeremylt   if (lvec) {
4744ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr);
475d7b241e6Sjeremylt   }
476d7b241e6Sjeremylt   if (evec) {
4774ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr);
478d7b241e6Sjeremylt   }
479d7b241e6Sjeremylt   return 0;
480d7b241e6Sjeremylt }
481d7b241e6Sjeremylt 
482d7b241e6Sjeremylt /**
483d9e1f99aSValeria Barra   @brief Restrict an L-vector to an E-vector or apply its transpose
484d7b241e6Sjeremylt 
4854ce2993fSjeremylt   @param rstr    CeedElemRestriction
486d7b241e6Sjeremylt   @param tmode   Apply restriction or transpose
487*d979a051Sjeremylt   @param u       Input vector (of size @a lsize when tmode=CEED_NOTRANSPOSE)
488a8d32208Sjeremylt   @param ru      Output vector (of shape [@a nelem * @a elemsize] when
4897aaeacdcSjeremylt                    tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided
4907aaeacdcSjeremylt                    by the backend.
491d7b241e6Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
492b11c1e72Sjeremylt 
493b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
494dfdf5a53Sjeremylt 
4957a982d89SJeremy L. Thompson   @ref User
496b11c1e72Sjeremylt **/
4974ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode,
498a8d32208Sjeremylt                              CeedVector u, CeedVector ru,
499a8d32208Sjeremylt                              CeedRequest *request) {
500d7b241e6Sjeremylt   CeedInt m,n;
501d7b241e6Sjeremylt   int ierr;
502d7b241e6Sjeremylt 
503d7b241e6Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
5044ce2993fSjeremylt     m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
505*d979a051Sjeremylt     n = rstr->lsize;
506d7b241e6Sjeremylt   } else {
507*d979a051Sjeremylt     m = rstr->lsize;
5084ce2993fSjeremylt     n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
509d7b241e6Sjeremylt   }
510d7b241e6Sjeremylt   if (n != u->length)
511c042f62fSJeremy L Thompson     // LCOV_EXCL_START
5121d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
5131d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
514c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
515a8d32208Sjeremylt   if (m != ru->length)
516c042f62fSJeremy L Thompson     // LCOV_EXCL_START
5171d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
518a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
519c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
520074cb416Sjeremylt   ierr = rstr->Apply(rstr, tmode, u, ru, request); CeedChk(ierr);
521d7b241e6Sjeremylt 
522d7b241e6Sjeremylt   return 0;
523d7b241e6Sjeremylt }
524d7b241e6Sjeremylt 
525d7b241e6Sjeremylt /**
526d9e1f99aSValeria Barra   @brief Restrict an L-vector to a block of an E-vector or apply its transpose
527be9261b7Sjeremylt 
528be9261b7Sjeremylt   @param rstr    CeedElemRestriction
5291f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
5301f37b403Sjeremylt                    elements [0 : blksize] and block=3 will handle elements
5311f37b403Sjeremylt                    [3*blksize : 4*blksize]
532be9261b7Sjeremylt   @param tmode   Apply restriction or transpose
533*d979a051Sjeremylt   @param u       Input vector (of size @a lsize when tmode=CEED_NOTRANSPOSE)
534a8d32208Sjeremylt   @param ru      Output vector (of shape [@a blksize * @a elemsize] when
5357aaeacdcSjeremylt                    tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided
5367aaeacdcSjeremylt                    by the backend.
537be9261b7Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
538be9261b7Sjeremylt 
539be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
540be9261b7Sjeremylt 
5417a982d89SJeremy L. Thompson   @ref Backend
542be9261b7Sjeremylt **/
543be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
544a8d32208Sjeremylt                                   CeedTransposeMode tmode, CeedVector u,
545a8d32208Sjeremylt                                   CeedVector ru, CeedRequest *request) {
546be9261b7Sjeremylt   CeedInt m,n;
547be9261b7Sjeremylt   int ierr;
548be9261b7Sjeremylt 
549be9261b7Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
550be9261b7Sjeremylt     m = rstr->blksize * rstr->elemsize * rstr->ncomp;
551*d979a051Sjeremylt     n = rstr->lsize;
552be9261b7Sjeremylt   } else {
553*d979a051Sjeremylt     m = rstr->lsize;
554be9261b7Sjeremylt     n = rstr->blksize * rstr->elemsize * rstr->ncomp;
555be9261b7Sjeremylt   }
556be9261b7Sjeremylt   if (n != u->length)
557c042f62fSJeremy L Thompson     // LCOV_EXCL_START
5581d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
5591d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
560c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
561a8d32208Sjeremylt   if (m != ru->length)
562c042f62fSJeremy L Thompson     // LCOV_EXCL_START
5631d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
564a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
565c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
566be9261b7Sjeremylt   if (rstr->blksize*block > rstr->nelem)
567c042f62fSJeremy L Thompson     // LCOV_EXCL_START
5681d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > "
5691d102b48SJeremy L Thompson                      "total elements %d", block, rstr->blksize*block,
5701d102b48SJeremy L Thompson                      rstr->nelem);
571c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
572074cb416Sjeremylt   ierr = rstr->ApplyBlock(rstr, block, tmode, u, ru, request);
573be9261b7Sjeremylt   CeedChk(ierr);
574be9261b7Sjeremylt 
575be9261b7Sjeremylt   return 0;
576be9261b7Sjeremylt }
577be9261b7Sjeremylt 
578be9261b7Sjeremylt /**
579*d979a051Sjeremylt   @brief Get the L-vector component stride
580a681ae63Sjeremylt 
581a681ae63Sjeremylt   @param rstr             CeedElemRestriction
582*d979a051Sjeremylt   @param[out] compstride  Variable to store component stride
583a681ae63Sjeremylt 
584a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
585a681ae63Sjeremylt 
586a681ae63Sjeremylt   @ref Backend
587a681ae63Sjeremylt **/
588*d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr,
589*d979a051Sjeremylt                                      CeedInt *compstride) {
590*d979a051Sjeremylt   *compstride = rstr->compstride;
591a681ae63Sjeremylt   return 0;
592a681ae63Sjeremylt }
593a681ae63Sjeremylt 
594a681ae63Sjeremylt /**
595a681ae63Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
596a681ae63Sjeremylt 
597a681ae63Sjeremylt   @param rstr             CeedElemRestriction
598a681ae63Sjeremylt   @param[out] numelem     Variable to store number of elements
599a681ae63Sjeremylt 
600a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
601a681ae63Sjeremylt 
602a681ae63Sjeremylt   @ref Backend
603a681ae63Sjeremylt **/
604a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
605a681ae63Sjeremylt                                       CeedInt *numelem) {
606a681ae63Sjeremylt   *numelem = rstr->nelem;
607a681ae63Sjeremylt   return 0;
608a681ae63Sjeremylt }
609a681ae63Sjeremylt 
610a681ae63Sjeremylt /**
611a681ae63Sjeremylt   @brief Get the size of elements in the CeedElemRestriction
612a681ae63Sjeremylt 
613a681ae63Sjeremylt   @param rstr             CeedElemRestriction
614a681ae63Sjeremylt   @param[out] elemsize    Variable to store size of elements
615a681ae63Sjeremylt 
616a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
617a681ae63Sjeremylt 
618a681ae63Sjeremylt   @ref Backend
619a681ae63Sjeremylt **/
620a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
621a681ae63Sjeremylt                                       CeedInt *elemsize) {
622a681ae63Sjeremylt   *elemsize = rstr->elemsize;
623a681ae63Sjeremylt   return 0;
624a681ae63Sjeremylt }
625a681ae63Sjeremylt 
626a681ae63Sjeremylt /**
627*d979a051Sjeremylt   @brief Get the size of the l-vector for a CeedElemRestriction
628a681ae63Sjeremylt 
629a681ae63Sjeremylt   @param rstr             CeedElemRestriction
630a681ae63Sjeremylt   @param[out] numnodes    Variable to store number of nodes
631a681ae63Sjeremylt 
632a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
633a681ae63Sjeremylt 
634a681ae63Sjeremylt   @ref Backend
635a681ae63Sjeremylt **/
636*d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr,
637*d979a051Sjeremylt                                       CeedInt *lsize) {
638*d979a051Sjeremylt   *lsize = rstr->lsize;
639a681ae63Sjeremylt   return 0;
640a681ae63Sjeremylt }
641a681ae63Sjeremylt 
642a681ae63Sjeremylt /**
643a681ae63Sjeremylt   @brief Get the number of components in the elements of a
644a681ae63Sjeremylt          CeedElemRestriction
645a681ae63Sjeremylt 
646a681ae63Sjeremylt   @param rstr             CeedElemRestriction
647a681ae63Sjeremylt   @param[out] numcomp     Variable to store number of components
648a681ae63Sjeremylt 
649a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
650a681ae63Sjeremylt 
651a681ae63Sjeremylt   @ref Backend
652a681ae63Sjeremylt **/
653a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
654a681ae63Sjeremylt                                         CeedInt *numcomp) {
655a681ae63Sjeremylt   *numcomp = rstr->ncomp;
656a681ae63Sjeremylt   return 0;
657a681ae63Sjeremylt }
658a681ae63Sjeremylt 
659a681ae63Sjeremylt /**
660a681ae63Sjeremylt   @brief Get the number of blocks in a CeedElemRestriction
661a681ae63Sjeremylt 
662a681ae63Sjeremylt   @param rstr             CeedElemRestriction
663a681ae63Sjeremylt   @param[out] numblock    Variable to store number of blocks
664a681ae63Sjeremylt 
665a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
666a681ae63Sjeremylt 
667a681ae63Sjeremylt   @ref Backend
668a681ae63Sjeremylt **/
669a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
670a681ae63Sjeremylt                                     CeedInt *numblock) {
671a681ae63Sjeremylt   *numblock = rstr->nblk;
672a681ae63Sjeremylt   return 0;
673a681ae63Sjeremylt }
674a681ae63Sjeremylt 
675a681ae63Sjeremylt /**
676a681ae63Sjeremylt   @brief Get the size of blocks in the CeedElemRestriction
677a681ae63Sjeremylt 
678a681ae63Sjeremylt   @param rstr             CeedElemRestriction
679a681ae63Sjeremylt   @param[out] blksize     Variable to store size of blocks
680a681ae63Sjeremylt 
681a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
682a681ae63Sjeremylt 
683a681ae63Sjeremylt   @ref Backend
684a681ae63Sjeremylt **/
685a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
686a681ae63Sjeremylt                                     CeedInt *blksize) {
687a681ae63Sjeremylt   *blksize = rstr->blksize;
688a681ae63Sjeremylt   return 0;
689a681ae63Sjeremylt }
690a681ae63Sjeremylt 
691a681ae63Sjeremylt /**
692d9e1f99aSValeria Barra   @brief Get the multiplicity of nodes in a CeedElemRestriction
6931469ee4dSjeremylt 
6941469ee4dSjeremylt   @param rstr             CeedElemRestriction
695*d979a051Sjeremylt   @param[out] mult        Vector to store multiplicity (of size lsize)
6961469ee4dSjeremylt 
6971469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
6981469ee4dSjeremylt 
6997a982d89SJeremy L. Thompson   @ref User
7001469ee4dSjeremylt **/
7011469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
7021469ee4dSjeremylt                                        CeedVector mult) {
7031469ee4dSjeremylt   int ierr;
7041469ee4dSjeremylt   CeedVector evec;
7051469ee4dSjeremylt 
7061469ee4dSjeremylt   // Create and set evec
7071469ee4dSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr);
7081469ee4dSjeremylt   ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr);
709fa9eac48SJed Brown   ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr);
7101469ee4dSjeremylt 
7111469ee4dSjeremylt   // Apply to get multiplicity
712a8d32208Sjeremylt   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult,
713efc78312Sjeremylt                                   CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
7141469ee4dSjeremylt 
7151469ee4dSjeremylt   // Cleanup
7161469ee4dSjeremylt   ierr = CeedVectorDestroy(&evec); CeedChk(ierr);
7171469ee4dSjeremylt 
7181469ee4dSjeremylt   return 0;
7191469ee4dSjeremylt }
7201469ee4dSjeremylt 
7211469ee4dSjeremylt /**
722f02ca4a2SJed Brown   @brief View a CeedElemRestriction
723f02ca4a2SJed Brown 
724f02ca4a2SJed Brown   @param[in] rstr    CeedElemRestriction to view
725f02ca4a2SJed Brown   @param[in] stream  Stream to write; typically stdout/stderr or a file
726f02ca4a2SJed Brown 
727f02ca4a2SJed Brown   @return Error code: 0 - success, otherwise - failure
728f02ca4a2SJed Brown 
7297a982d89SJeremy L. Thompson   @ref User
730f02ca4a2SJed Brown **/
731f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
7327509a596Sjeremylt   char stridesstr[500];
7337509a596Sjeremylt   if (rstr->strides)
7347509a596Sjeremylt     sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1],
7357509a596Sjeremylt             rstr->strides[2]);
736*d979a051Sjeremylt   else
737*d979a051Sjeremylt     sprintf(stridesstr, "%d", rstr->compstride);
7387509a596Sjeremylt 
7390036de2cSjeremylt   fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d "
7400036de2cSjeremylt           "nodes each and %s %s\n", rstr->blksize > 1 ? "Blocked " : "",
741*d979a051Sjeremylt           rstr->lsize, rstr->ncomp, rstr->nelem, rstr->elemsize,
742*d979a051Sjeremylt           rstr->strides ? "strides" : "component stride", stridesstr);
743f02ca4a2SJed Brown   return 0;
744f02ca4a2SJed Brown }
745f02ca4a2SJed Brown 
746f02ca4a2SJed Brown /**
747b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
748b11c1e72Sjeremylt 
7494ce2993fSjeremylt   @param rstr  CeedElemRestriction to destroy
750b11c1e72Sjeremylt 
751b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
752dfdf5a53Sjeremylt 
7537a982d89SJeremy L. Thompson   @ref User
754b11c1e72Sjeremylt **/
7554ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
756d7b241e6Sjeremylt   int ierr;
757d7b241e6Sjeremylt 
7581d102b48SJeremy L Thompson   if (!*rstr || --(*rstr)->refcount > 0)
7591d102b48SJeremy L Thompson     return 0;
7604ce2993fSjeremylt   if ((*rstr)->Destroy) {
7614ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
762d7b241e6Sjeremylt   }
7637509a596Sjeremylt   ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr);
7644ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
7654ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
766d7b241e6Sjeremylt   return 0;
767d7b241e6Sjeremylt }
768d7b241e6Sjeremylt 
769d7b241e6Sjeremylt /// @}
770