xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-elemrestriction.c (revision a681ae63fc3ab1c02b4a9accd00627e374296e0d)
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 /**
307a982d89SJeremy L. Thompson   @brief Permute and pad indices for a blocked restriction
317a982d89SJeremy L. Thompson 
327a982d89SJeremy L. Thompson   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the
337a982d89SJeremy L. Thompson                       ordered list of the indices (into the input CeedVector)
347a982d89SJeremy L. Thompson                       for the unknowns corresponding to element i, where
357a982d89SJeremy L. Thompson                       0 <= i < @a nelem. All indices must be in the range
367a982d89SJeremy L. Thompson                       [0, @a nnodes).
377a982d89SJeremy L. Thompson   @param blkindices Array of permuted and padded indices 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 **/
487a982d89SJeremy L. Thompson int CeedPermutePadIndices(const CeedInt *indices, CeedInt *blkindices,
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++)
547a982d89SJeremy L. Thompson         blkindices[e*elemsize + k*blksize + j]
557a982d89SJeremy L. Thompson           = indices[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 /**
83*a681ae63Sjeremylt 
84*a681ae63Sjeremylt   @brief Get the strides of a strided CeedElemRestriction
857a982d89SJeremy L. Thompson 
867a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
87*a681ae63Sjeremylt   @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 **/
93*a681ae63Sjeremylt int CeedElemRestrictionGetStrides(CeedElemRestriction rstr,
94*a681ae63Sjeremylt                                   CeedInt (*strides)[3]) {
95*a681ae63Sjeremylt   if (!rstr->strides)
96*a681ae63Sjeremylt     // LCOV_EXCL_START
97*a681ae63Sjeremylt     return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data");
98*a681ae63Sjeremylt   // LCOV_EXCL_STOP
99*a681ae63Sjeremylt 
100*a681ae63Sjeremylt   for (int i = 0; i<3; i++)
101*a681ae63Sjeremylt     (*strides)[i] = rstr->strides[i];
1027a982d89SJeremy L. Thompson   return 0;
1037a982d89SJeremy L. Thompson }
1047a982d89SJeremy L. Thompson 
1057a982d89SJeremy L. Thompson /**
106*a681ae63Sjeremylt   @brief Get the backend stride status of a CeedElemRestriction
1077a982d89SJeremy L. Thompson 
1087a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
109*a681ae63Sjeremylt   @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 **/
115*a681ae63Sjeremylt int CeedElemRestrictionGetBackendStridesStatus(CeedElemRestriction rstr,
116*a681ae63Sjeremylt     bool *status) {
117*a681ae63Sjeremylt   if (!rstr->strides)
118*a681ae63Sjeremylt     // LCOV_EXCL_START
119*a681ae63Sjeremylt     return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data");
120*a681ae63Sjeremylt   // LCOV_EXCL_STOP
1217a982d89SJeremy L. Thompson 
122*a681ae63Sjeremylt   *status = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) &&
123*a681ae63Sjeremylt              (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) &&
124*a681ae63Sjeremylt              (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
18161dbc9d2Sjeremylt   @param imode      Ordering of the ncomp components, i.e. it specifies
182a8d32208Sjeremylt                       the ordering of the components of the L-vector used
18361dbc9d2Sjeremylt                       by this CeedElemRestriction. CEED_NONINTERLACED indicates
18461dbc9d2Sjeremylt                       the component is the outermost index and CEED_INTERLACED
185a8d32208Sjeremylt                       indicates the component is the innermost index in
186a8d32208Sjeremylt                       ordering of the L-vector.
187b11c1e72Sjeremylt   @param nelem      Number of elements described in the @a indices array
188b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
1898795c945Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
1908795c945Sjeremylt                       to which the restriction will be applied is of size
1918795c945Sjeremylt                       @a nnodes * @a ncomp. This size may include data
192d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
193d7b241e6Sjeremylt                       different types of elements.
194b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
19595bb1877Svaleriabarra                       (1 for scalar fields)
196b11c1e72Sjeremylt   @param mtype      Memory type of the @a indices array, see CeedMemType
197b11c1e72Sjeremylt   @param cmode      Copy mode for the @a indices array, see CeedCopyMode
1988795c945Sjeremylt   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the
1998795c945Sjeremylt                       ordered list of the indices (into the input CeedVector)
2008795c945Sjeremylt                       for the unknowns corresponding to element i, where
20134138859Sjeremylt                       0 <= i < @a nelem. All indices must be in the range
20223e8ed12Sjeremylt                       [0, @a nnodes - 1].
2034ce2993fSjeremylt   @param[out] rstr  Address of the variable where the newly created
204b11c1e72Sjeremylt                       CeedElemRestriction will be stored
205d7b241e6Sjeremylt 
206b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
207dfdf5a53Sjeremylt 
2087a982d89SJeremy L. Thompson   @ref User
209b11c1e72Sjeremylt **/
21061dbc9d2Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInterlaceMode imode,
2117509a596Sjeremylt                               CeedInt nelem, CeedInt elemsize, CeedInt nnodes,
2127509a596Sjeremylt                               CeedInt ncomp, CeedMemType mtype,
2137509a596Sjeremylt                               CeedCopyMode cmode, const CeedInt *indices,
2144ce2993fSjeremylt                               CeedElemRestriction *rstr) {
215d7b241e6Sjeremylt   int ierr;
216d7b241e6Sjeremylt 
2175fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
2185fe0d4faSjeremylt     Ceed delegate;
219aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
220aefd8378Sjeremylt     CeedChk(ierr);
2215fe0d4faSjeremylt 
2225fe0d4faSjeremylt     if (!delegate)
223c042f62fSJeremy L Thompson       // LCOV_EXCL_START
224d7b241e6Sjeremylt       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
225c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
2265fe0d4faSjeremylt 
22761dbc9d2Sjeremylt     ierr = CeedElemRestrictionCreate(delegate, imode, nelem, elemsize,
2288795c945Sjeremylt                                      nnodes, ncomp, mtype, cmode,
2294ce2993fSjeremylt                                      indices, rstr); CeedChk(ierr);
2305fe0d4faSjeremylt     return 0;
2315fe0d4faSjeremylt   }
2325fe0d4faSjeremylt 
2334ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
2344ce2993fSjeremylt   (*rstr)->ceed = ceed;
235d7b241e6Sjeremylt   ceed->refcount++;
2364ce2993fSjeremylt   (*rstr)->refcount = 1;
23761dbc9d2Sjeremylt   (*rstr)->imode = imode;
2384ce2993fSjeremylt   (*rstr)->nelem = nelem;
2394ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
2408795c945Sjeremylt   (*rstr)->nnodes = nnodes;
2414ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
2424ce2993fSjeremylt   (*rstr)->nblk = nelem;
2434ce2993fSjeremylt   (*rstr)->blksize = 1;
2444ce2993fSjeremylt   ierr = ceed->ElemRestrictionCreate(mtype, cmode, indices, *rstr); CeedChk(ierr);
245d7b241e6Sjeremylt   return 0;
246d7b241e6Sjeremylt }
247d7b241e6Sjeremylt 
248d7b241e6Sjeremylt /**
2497509a596Sjeremylt   @brief Create a strided CeedElemRestriction
250d7b241e6Sjeremylt 
251b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
2527509a596Sjeremylt   @param nelem      Number of elements described by the restriction
253b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
2548795c945Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
2558795c945Sjeremylt                       to which the restriction will be applied is of size
2568795c945Sjeremylt                       @a nnodes * @a ncomp. This size may include data
257d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
2588795c945Sjeremylt                       different types of elements.
259b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
26095bb1877Svaleriabarra                       (1 for scalar fields)
2617509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
2627509a596Sjeremylt                       The data for node i, component j, element k in the
2637509a596Sjeremylt                       L-vector is given by
2647509a596Sjeremylt                         i*strides[0] + j*strides[1] + k*strides[2]
2654ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
266b11c1e72Sjeremylt                       CeedElemRestriction will be stored
267d7b241e6Sjeremylt 
268b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
269dfdf5a53Sjeremylt 
2707a982d89SJeremy L. Thompson   @ref User
271b11c1e72Sjeremylt **/
2727509a596Sjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt nelem, CeedInt elemsize,
273a8d32208Sjeremylt                                      CeedInt nnodes, CeedInt ncomp,
2748621c6c6SJeremy L Thompson                                      const CeedInt strides[3],
275f90c8643Sjeremylt                                      CeedElemRestriction *rstr) {
276d7b241e6Sjeremylt   int ierr;
277d7b241e6Sjeremylt 
2785fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
2795fe0d4faSjeremylt     Ceed delegate;
280aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
281aefd8378Sjeremylt     CeedChk(ierr);
2825fe0d4faSjeremylt 
2835fe0d4faSjeremylt     if (!delegate)
284c042f62fSJeremy L Thompson       // LCOV_EXCL_START
2851d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
286c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
2875fe0d4faSjeremylt 
2887509a596Sjeremylt     ierr = CeedElemRestrictionCreateStrided(delegate, nelem, elemsize, nnodes,
2897509a596Sjeremylt                                             ncomp, strides, rstr); CeedChk(ierr);
2905fe0d4faSjeremylt     return 0;
2915fe0d4faSjeremylt   }
2925fe0d4faSjeremylt 
2934ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
2944ce2993fSjeremylt   (*rstr)->ceed = ceed;
295d7b241e6Sjeremylt   ceed->refcount++;
2964ce2993fSjeremylt   (*rstr)->refcount = 1;
2974ce2993fSjeremylt   (*rstr)->nelem = nelem;
2984ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
2998795c945Sjeremylt   (*rstr)->nnodes = nnodes;
3004ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
3014ce2993fSjeremylt   (*rstr)->nblk = nelem;
3024ce2993fSjeremylt   (*rstr)->blksize = 1;
3037509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
3047509a596Sjeremylt   for (int i = 0; i<3; i++)
3057509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
3061dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
3071dfeef1dSjeremylt                                      *rstr);
3084b8bea3bSJed Brown   CeedChk(ierr);
309d7b241e6Sjeremylt   return 0;
310d7b241e6Sjeremylt }
311d7b241e6Sjeremylt 
312d7b241e6Sjeremylt /**
313b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
314d7b241e6Sjeremylt 
315d7b241e6Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created.
31661dbc9d2Sjeremylt   @param imode      Ordering of the ncomp components, i.e. it specifies
317a8d32208Sjeremylt                       the ordering of the components of the L-vector used
31861dbc9d2Sjeremylt                       by this CeedElemRestriction. CEED_NONINTERLACED indicates
31961dbc9d2Sjeremylt                       the component is the outermost index and CEED_INTERLACED
320a8d32208Sjeremylt                       indicates the component is the innermost index in
321a8d32208Sjeremylt                       ordering of the L-vector.
322d7b241e6Sjeremylt   @param nelem      Number of elements described in the @a indices array.
323b11c1e72Sjeremylt   @param elemsize   Size (number of unknowns) per element
324b11c1e72Sjeremylt   @param blksize    Number of elements in a block
3258795c945Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
3268795c945Sjeremylt                       to which the restriction will be applied is of size
3278795c945Sjeremylt                       @a nnodes * @a ncomp. This size may include data
328d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
329d7b241e6Sjeremylt                       different types of elements.
33095bb1877Svaleriabarra   @param ncomp      Number of field components per interpolation node
33195bb1877Svaleriabarra                       (1 for scalar fields)
332b11c1e72Sjeremylt   @param mtype      Memory type of the @a indices array, see CeedMemType
333b11c1e72Sjeremylt   @param cmode      Copy mode for the @a indices array, see CeedCopyMode
3348795c945Sjeremylt   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the
3358795c945Sjeremylt                       ordered list of the indices (into the input CeedVector)
3368795c945Sjeremylt                       for the unknowns corresponding to element i, where
33734138859Sjeremylt                       0 <= i < @a nelem. All indices must be in the range
3388795c945Sjeremylt                       [0, @a nnodes). The backend will permute and pad this
3398795c945Sjeremylt                       array to the desired ordering for the blocksize, which is
3408795c945Sjeremylt                       typically given by the backend. The default reordering is
3418795c945Sjeremylt                       to interlace elements.
3424ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
343b11c1e72Sjeremylt                       CeedElemRestriction will be stored
344d7b241e6Sjeremylt 
345b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
346dfdf5a53Sjeremylt 
3477a982d89SJeremy L. Thompson   @ref Backend
348b11c1e72Sjeremylt  **/
34961dbc9d2Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed,  CeedInterlaceMode imode,
350a8d32208Sjeremylt                                      CeedInt nelem, CeedInt elemsize,
3518795c945Sjeremylt                                      CeedInt blksize, CeedInt nnodes,
3528795c945Sjeremylt                                      CeedInt ncomp, CeedMemType mtype,
3538795c945Sjeremylt                                      CeedCopyMode cmode, const CeedInt *indices,
3544ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
355d7b241e6Sjeremylt   int ierr;
356d7b241e6Sjeremylt   CeedInt *blkindices;
357d7b241e6Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
358d7b241e6Sjeremylt 
3595fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
3605fe0d4faSjeremylt     Ceed delegate;
361aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
362aefd8378Sjeremylt     CeedChk(ierr);
3635fe0d4faSjeremylt 
3645fe0d4faSjeremylt     if (!delegate)
365c042f62fSJeremy L Thompson       // LCOV_EXCL_START
3661d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support "
3671d102b48SJeremy L Thompson                        "ElemRestrictionCreateBlocked");
368c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3695fe0d4faSjeremylt 
37061dbc9d2Sjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, imode, nelem, elemsize,
3718795c945Sjeremylt                                             blksize, nnodes, ncomp, mtype, cmode,
3724ce2993fSjeremylt                                             indices, rstr); CeedChk(ierr);
3735fe0d4faSjeremylt     return 0;
3745fe0d4faSjeremylt   }
375d7b241e6Sjeremylt 
3764ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
377d7b241e6Sjeremylt 
378de686571SJeremy L Thompson   ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr);
3794b8bea3bSJed Brown   ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize,
3804b8bea3bSJed Brown                                elemsize);
381dfdf5a53Sjeremylt   CeedChk(ierr);
382d7b241e6Sjeremylt 
3834ce2993fSjeremylt   (*rstr)->ceed = ceed;
384d7b241e6Sjeremylt   ceed->refcount++;
3854ce2993fSjeremylt   (*rstr)->refcount = 1;
38661dbc9d2Sjeremylt   (*rstr)->imode = imode;
3874ce2993fSjeremylt   (*rstr)->nelem = nelem;
3884ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
3898795c945Sjeremylt   (*rstr)->nnodes = nnodes;
3904ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
3914ce2993fSjeremylt   (*rstr)->nblk = nblk;
3924ce2993fSjeremylt   (*rstr)->blksize = blksize;
393667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
3947f823360Sjeremylt          (const CeedInt *) blkindices, *rstr); CeedChk(ierr);
395d7b241e6Sjeremylt 
3961d102b48SJeremy L Thompson   if (cmode == CEED_OWN_POINTER) {
397d7b241e6Sjeremylt     ierr = CeedFree(&indices); CeedChk(ierr);
3981d102b48SJeremy L Thompson   }
399d7b241e6Sjeremylt 
400d7b241e6Sjeremylt   return 0;
401d7b241e6Sjeremylt }
402d7b241e6Sjeremylt 
403b11c1e72Sjeremylt /**
4047509a596Sjeremylt   @brief Create a blocked strided CeedElemRestriction
4057509a596Sjeremylt 
4067509a596Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
4077509a596Sjeremylt   @param nelem      Number of elements described by the restriction
4087509a596Sjeremylt   @param elemsize   Size (number of "nodes") per element
4097509a596Sjeremylt   @param blksize    Number of elements in a block
4107509a596Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
4117509a596Sjeremylt                       to which the restriction will be applied is of size
4127509a596Sjeremylt                       @a nnodes * @a ncomp. This size may include data
4137509a596Sjeremylt                       used by other CeedElemRestriction objects describing
4147509a596Sjeremylt                       different types of elements.
4157509a596Sjeremylt   @param ncomp      Number of field components per interpolation node
4167509a596Sjeremylt                       (1 for scalar fields)
4177509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
4187509a596Sjeremylt                       The data for node i, component j, element k in the
4197509a596Sjeremylt                       L-vector is given by
4207509a596Sjeremylt                         i*strides[0] + j*strides[1] + k*strides[2]
4217509a596Sjeremylt   @param rstr       Address of the variable where the newly created
4227509a596Sjeremylt                       CeedElemRestriction will be stored
4237509a596Sjeremylt 
4247509a596Sjeremylt   @return An error code: 0 - success, otherwise - failure
4257509a596Sjeremylt 
4267a982d89SJeremy L. Thompson   @ref User
4277509a596Sjeremylt **/
4287509a596Sjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt nelem,
4298621c6c6SJeremy L Thompson     CeedInt elemsize, CeedInt blksize, CeedInt nnodes, CeedInt ncomp,
4308621c6c6SJeremy L Thompson     const CeedInt strides[3], CeedElemRestriction *rstr) {
4317509a596Sjeremylt   int ierr;
4327509a596Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
4337509a596Sjeremylt 
4347509a596Sjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
4357509a596Sjeremylt     Ceed delegate;
4367509a596Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
4377509a596Sjeremylt     CeedChk(ierr);
4387509a596Sjeremylt 
4397509a596Sjeremylt     if (!delegate)
4407509a596Sjeremylt       // LCOV_EXCL_START
4417509a596Sjeremylt       return CeedError(ceed, 1, "Backend does not support "
4427509a596Sjeremylt                        "ElemRestrictionCreateBlocked");
4437509a596Sjeremylt     // LCOV_EXCL_STOP
4447509a596Sjeremylt 
4457509a596Sjeremylt     ierr = CeedElemRestrictionCreateBlockedStrided(delegate, nelem, elemsize,
4468621c6c6SJeremy L Thompson            blksize, nnodes, ncomp, strides, rstr);
4477509a596Sjeremylt     CeedChk(ierr);
4487509a596Sjeremylt     return 0;
4497509a596Sjeremylt   }
4507509a596Sjeremylt 
4517509a596Sjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
4527509a596Sjeremylt 
4537509a596Sjeremylt   (*rstr)->ceed = ceed;
4547509a596Sjeremylt   ceed->refcount++;
4557509a596Sjeremylt   (*rstr)->refcount = 1;
4567509a596Sjeremylt   (*rstr)->nelem = nelem;
4577509a596Sjeremylt   (*rstr)->elemsize = elemsize;
4587509a596Sjeremylt   (*rstr)->nnodes = nnodes;
4597509a596Sjeremylt   (*rstr)->ncomp = ncomp;
4607509a596Sjeremylt   (*rstr)->nblk = nblk;
4617509a596Sjeremylt   (*rstr)->blksize = blksize;
4627509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
4637509a596Sjeremylt   for (int i = 0; i<3; i++)
4647509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
4657509a596Sjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
4667509a596Sjeremylt          NULL, *rstr); CeedChk(ierr);
4677509a596Sjeremylt 
4687509a596Sjeremylt   return 0;
4697509a596Sjeremylt }
4707509a596Sjeremylt 
4717509a596Sjeremylt /**
472b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
473b11c1e72Sjeremylt 
4744ce2993fSjeremylt   @param rstr  CeedElemRestriction
475b11c1e72Sjeremylt   @param lvec  The address of the L-vector to be created, or NULL
476b11c1e72Sjeremylt   @param evec  The address of the E-vector to be created, or NULL
477b11c1e72Sjeremylt 
478b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
479dfdf5a53Sjeremylt 
4807a982d89SJeremy L. Thompson   @ref User
481b11c1e72Sjeremylt **/
4824ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec,
483d7b241e6Sjeremylt                                     CeedVector *evec) {
484d7b241e6Sjeremylt   int ierr;
485d7b241e6Sjeremylt   CeedInt n, m;
4868795c945Sjeremylt   m = rstr->nnodes * rstr->ncomp;
4874ce2993fSjeremylt   n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
488d7b241e6Sjeremylt   if (lvec) {
4894ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr);
490d7b241e6Sjeremylt   }
491d7b241e6Sjeremylt   if (evec) {
4924ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr);
493d7b241e6Sjeremylt   }
494d7b241e6Sjeremylt   return 0;
495d7b241e6Sjeremylt }
496d7b241e6Sjeremylt 
497d7b241e6Sjeremylt /**
498d9e1f99aSValeria Barra   @brief Restrict an L-vector to an E-vector or apply its transpose
499d7b241e6Sjeremylt 
5004ce2993fSjeremylt   @param rstr    CeedElemRestriction
501d7b241e6Sjeremylt   @param tmode   Apply restriction or transpose
5027aaeacdcSjeremylt   @param u       Input vector (of shape [@a nnodes, @a ncomp] when
50361dbc9d2Sjeremylt                    tmode=CEED_NOTRANSPOSE, imode=CEED_INTERLACED)
504a8d32208Sjeremylt   @param ru      Output vector (of shape [@a nelem * @a elemsize] when
5057aaeacdcSjeremylt                    tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided
5067aaeacdcSjeremylt                    by the backend.
507d7b241e6Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
508b11c1e72Sjeremylt 
509b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
510dfdf5a53Sjeremylt 
5117a982d89SJeremy L. Thompson   @ref User
512b11c1e72Sjeremylt **/
5134ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode,
514a8d32208Sjeremylt                              CeedVector u, CeedVector ru,
515a8d32208Sjeremylt                              CeedRequest *request) {
516d7b241e6Sjeremylt   CeedInt m,n;
517d7b241e6Sjeremylt   int ierr;
518d7b241e6Sjeremylt 
519d7b241e6Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
5204ce2993fSjeremylt     m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
5218795c945Sjeremylt     n = rstr->nnodes * rstr->ncomp;
522d7b241e6Sjeremylt   } else {
5238795c945Sjeremylt     m = rstr->nnodes * rstr->ncomp;
5244ce2993fSjeremylt     n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
525d7b241e6Sjeremylt   }
526d7b241e6Sjeremylt   if (n != u->length)
527c042f62fSJeremy L Thompson     // LCOV_EXCL_START
5281d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
5291d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
530c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
531a8d32208Sjeremylt   if (m != ru->length)
532c042f62fSJeremy L Thompson     // LCOV_EXCL_START
5331d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
534a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
535c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
536074cb416Sjeremylt   ierr = rstr->Apply(rstr, tmode, u, ru, request); CeedChk(ierr);
537d7b241e6Sjeremylt 
538d7b241e6Sjeremylt   return 0;
539d7b241e6Sjeremylt }
540d7b241e6Sjeremylt 
541d7b241e6Sjeremylt /**
542d9e1f99aSValeria Barra   @brief Restrict an L-vector to a block of an E-vector or apply its transpose
543be9261b7Sjeremylt 
544be9261b7Sjeremylt   @param rstr    CeedElemRestriction
5451f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
5461f37b403Sjeremylt                    elements [0 : blksize] and block=3 will handle elements
5471f37b403Sjeremylt                    [3*blksize : 4*blksize]
548be9261b7Sjeremylt   @param tmode   Apply restriction or transpose
5497aaeacdcSjeremylt   @param u       Input vector (of shape [@a nnodes, @a ncomp] when
55061dbc9d2Sjeremylt                    tmode=CEED_NOTRANSPOSE, imode=CEED_INTERLACED)
551a8d32208Sjeremylt   @param ru      Output vector (of shape [@a blksize * @a elemsize] when
5527aaeacdcSjeremylt                    tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided
5537aaeacdcSjeremylt                    by the backend.
554be9261b7Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
555be9261b7Sjeremylt 
556be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
557be9261b7Sjeremylt 
5587a982d89SJeremy L. Thompson   @ref Backend
559be9261b7Sjeremylt **/
560be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
561a8d32208Sjeremylt                                   CeedTransposeMode tmode, CeedVector u,
562a8d32208Sjeremylt                                   CeedVector ru, CeedRequest *request) {
563be9261b7Sjeremylt   CeedInt m,n;
564be9261b7Sjeremylt   int ierr;
565be9261b7Sjeremylt 
566be9261b7Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
567be9261b7Sjeremylt     m = rstr->blksize * rstr->elemsize * rstr->ncomp;
5688795c945Sjeremylt     n = rstr->nnodes * rstr->ncomp;
569be9261b7Sjeremylt   } else {
5708795c945Sjeremylt     m = rstr->nnodes * rstr->ncomp;
571be9261b7Sjeremylt     n = rstr->blksize * rstr->elemsize * rstr->ncomp;
572be9261b7Sjeremylt   }
573be9261b7Sjeremylt   if (n != u->length)
574c042f62fSJeremy L Thompson     // LCOV_EXCL_START
5751d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
5761d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
577c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
578a8d32208Sjeremylt   if (m != ru->length)
579c042f62fSJeremy L Thompson     // LCOV_EXCL_START
5801d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
581a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
582c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
583be9261b7Sjeremylt   if (rstr->blksize*block > rstr->nelem)
584c042f62fSJeremy L Thompson     // LCOV_EXCL_START
5851d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > "
5861d102b48SJeremy L Thompson                      "total elements %d", block, rstr->blksize*block,
5871d102b48SJeremy L Thompson                      rstr->nelem);
588c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
589074cb416Sjeremylt   ierr = rstr->ApplyBlock(rstr, block, tmode, u, ru, request);
590be9261b7Sjeremylt   CeedChk(ierr);
591be9261b7Sjeremylt 
592be9261b7Sjeremylt   return 0;
593be9261b7Sjeremylt }
594be9261b7Sjeremylt 
595be9261b7Sjeremylt /**
596*a681ae63Sjeremylt   @brief Get the L-vector interlaced mode of a CeedElemRestriction
597*a681ae63Sjeremylt 
598*a681ae63Sjeremylt   @param rstr             CeedElemRestriction
599*a681ae63Sjeremylt   @param[out] imode       Variable to store imode
600*a681ae63Sjeremylt 
601*a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
602*a681ae63Sjeremylt 
603*a681ae63Sjeremylt   @ref Backend
604*a681ae63Sjeremylt **/
605*a681ae63Sjeremylt int CeedElemRestrictionGetIMode(CeedElemRestriction rstr,
606*a681ae63Sjeremylt                                 CeedInterlaceMode *imode) {
607*a681ae63Sjeremylt   *imode = rstr->imode;
608*a681ae63Sjeremylt   return 0;
609*a681ae63Sjeremylt }
610*a681ae63Sjeremylt 
611*a681ae63Sjeremylt /**
612*a681ae63Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
613*a681ae63Sjeremylt 
614*a681ae63Sjeremylt   @param rstr             CeedElemRestriction
615*a681ae63Sjeremylt   @param[out] numelem     Variable to store number of elements
616*a681ae63Sjeremylt 
617*a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
618*a681ae63Sjeremylt 
619*a681ae63Sjeremylt   @ref Backend
620*a681ae63Sjeremylt **/
621*a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
622*a681ae63Sjeremylt                                       CeedInt *numelem) {
623*a681ae63Sjeremylt   *numelem = rstr->nelem;
624*a681ae63Sjeremylt   return 0;
625*a681ae63Sjeremylt }
626*a681ae63Sjeremylt 
627*a681ae63Sjeremylt /**
628*a681ae63Sjeremylt   @brief Get the size of elements in the CeedElemRestriction
629*a681ae63Sjeremylt 
630*a681ae63Sjeremylt   @param rstr             CeedElemRestriction
631*a681ae63Sjeremylt   @param[out] elemsize    Variable to store size of elements
632*a681ae63Sjeremylt 
633*a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
634*a681ae63Sjeremylt 
635*a681ae63Sjeremylt   @ref Backend
636*a681ae63Sjeremylt **/
637*a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
638*a681ae63Sjeremylt                                       CeedInt *elemsize) {
639*a681ae63Sjeremylt   *elemsize = rstr->elemsize;
640*a681ae63Sjeremylt   return 0;
641*a681ae63Sjeremylt }
642*a681ae63Sjeremylt 
643*a681ae63Sjeremylt /**
644*a681ae63Sjeremylt   @brief Get the number of degrees of freedom in the range of a
645*a681ae63Sjeremylt          CeedElemRestriction
646*a681ae63Sjeremylt 
647*a681ae63Sjeremylt   @param rstr             CeedElemRestriction
648*a681ae63Sjeremylt   @param[out] numnodes    Variable to store number of nodes
649*a681ae63Sjeremylt 
650*a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
651*a681ae63Sjeremylt 
652*a681ae63Sjeremylt   @ref Backend
653*a681ae63Sjeremylt **/
654*a681ae63Sjeremylt int CeedElemRestrictionGetNumNodes(CeedElemRestriction rstr,
655*a681ae63Sjeremylt                                    CeedInt *numnodes) {
656*a681ae63Sjeremylt   *numnodes = rstr->nnodes;
657*a681ae63Sjeremylt   return 0;
658*a681ae63Sjeremylt }
659*a681ae63Sjeremylt 
660*a681ae63Sjeremylt /**
661*a681ae63Sjeremylt   @brief Get the number of components in the elements of a
662*a681ae63Sjeremylt          CeedElemRestriction
663*a681ae63Sjeremylt 
664*a681ae63Sjeremylt   @param rstr             CeedElemRestriction
665*a681ae63Sjeremylt   @param[out] numcomp     Variable to store number of components
666*a681ae63Sjeremylt 
667*a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
668*a681ae63Sjeremylt 
669*a681ae63Sjeremylt   @ref Backend
670*a681ae63Sjeremylt **/
671*a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
672*a681ae63Sjeremylt                                         CeedInt *numcomp) {
673*a681ae63Sjeremylt   *numcomp = rstr->ncomp;
674*a681ae63Sjeremylt   return 0;
675*a681ae63Sjeremylt }
676*a681ae63Sjeremylt 
677*a681ae63Sjeremylt /**
678*a681ae63Sjeremylt   @brief Get the number of blocks in a CeedElemRestriction
679*a681ae63Sjeremylt 
680*a681ae63Sjeremylt   @param rstr             CeedElemRestriction
681*a681ae63Sjeremylt   @param[out] numblock    Variable to store number of blocks
682*a681ae63Sjeremylt 
683*a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
684*a681ae63Sjeremylt 
685*a681ae63Sjeremylt   @ref Backend
686*a681ae63Sjeremylt **/
687*a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
688*a681ae63Sjeremylt                                     CeedInt *numblock) {
689*a681ae63Sjeremylt   *numblock = rstr->nblk;
690*a681ae63Sjeremylt   return 0;
691*a681ae63Sjeremylt }
692*a681ae63Sjeremylt 
693*a681ae63Sjeremylt /**
694*a681ae63Sjeremylt   @brief Get the size of blocks in the CeedElemRestriction
695*a681ae63Sjeremylt 
696*a681ae63Sjeremylt   @param rstr             CeedElemRestriction
697*a681ae63Sjeremylt   @param[out] blksize     Variable to store size of blocks
698*a681ae63Sjeremylt 
699*a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
700*a681ae63Sjeremylt 
701*a681ae63Sjeremylt   @ref Backend
702*a681ae63Sjeremylt **/
703*a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
704*a681ae63Sjeremylt                                     CeedInt *blksize) {
705*a681ae63Sjeremylt   *blksize = rstr->blksize;
706*a681ae63Sjeremylt   return 0;
707*a681ae63Sjeremylt }
708*a681ae63Sjeremylt 
709*a681ae63Sjeremylt /**
710d9e1f99aSValeria Barra   @brief Get the multiplicity of nodes in a CeedElemRestriction
7111469ee4dSjeremylt 
7121469ee4dSjeremylt   @param rstr             CeedElemRestriction
713b9c05c73SJed Brown   @param[out] mult        Vector to store multiplicity (of size nnodes*ncomp)
7141469ee4dSjeremylt 
7151469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
7161469ee4dSjeremylt 
7177a982d89SJeremy L. Thompson   @ref User
7181469ee4dSjeremylt **/
7191469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
7201469ee4dSjeremylt                                        CeedVector mult) {
7211469ee4dSjeremylt   int ierr;
7221469ee4dSjeremylt   CeedVector evec;
7231469ee4dSjeremylt 
7241469ee4dSjeremylt   // Create and set evec
7251469ee4dSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr);
7261469ee4dSjeremylt   ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr);
727fa9eac48SJed Brown   ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr);
7281469ee4dSjeremylt 
7291469ee4dSjeremylt   // Apply to get multiplicity
730a8d32208Sjeremylt   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult,
731efc78312Sjeremylt                                   CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
7321469ee4dSjeremylt 
7331469ee4dSjeremylt   // Cleanup
7341469ee4dSjeremylt   ierr = CeedVectorDestroy(&evec); CeedChk(ierr);
7351469ee4dSjeremylt 
7361469ee4dSjeremylt   return 0;
7371469ee4dSjeremylt }
7381469ee4dSjeremylt 
7391469ee4dSjeremylt /**
740f02ca4a2SJed Brown   @brief View a CeedElemRestriction
741f02ca4a2SJed Brown 
742f02ca4a2SJed Brown   @param[in] rstr    CeedElemRestriction to view
743f02ca4a2SJed Brown   @param[in] stream  Stream to write; typically stdout/stderr or a file
744f02ca4a2SJed Brown 
745f02ca4a2SJed Brown   @return Error code: 0 - success, otherwise - failure
746f02ca4a2SJed Brown 
7477a982d89SJeremy L. Thompson   @ref User
748f02ca4a2SJed Brown **/
749f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
7507509a596Sjeremylt   char stridesstr[500];
7517509a596Sjeremylt   if (rstr->strides)
7527509a596Sjeremylt     sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1],
7537509a596Sjeremylt             rstr->strides[2]);
7547509a596Sjeremylt 
7550036de2cSjeremylt   fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d "
7560036de2cSjeremylt           "nodes each and %s %s\n", rstr->blksize > 1 ? "Blocked " : "",
7570036de2cSjeremylt           rstr->nnodes, rstr->ncomp, rstr->nelem, rstr->elemsize,
7580036de2cSjeremylt           rstr->strides ? "strides" : "L-vector components",
7597509a596Sjeremylt           rstr->strides ? stridesstr : CeedInterlaceModes[rstr->imode]);
760f02ca4a2SJed Brown   return 0;
761f02ca4a2SJed Brown }
762f02ca4a2SJed Brown 
763f02ca4a2SJed Brown /**
764b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
765b11c1e72Sjeremylt 
7664ce2993fSjeremylt   @param rstr  CeedElemRestriction to destroy
767b11c1e72Sjeremylt 
768b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
769dfdf5a53Sjeremylt 
7707a982d89SJeremy L. Thompson   @ref User
771b11c1e72Sjeremylt **/
7724ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
773d7b241e6Sjeremylt   int ierr;
774d7b241e6Sjeremylt 
7751d102b48SJeremy L Thompson   if (!*rstr || --(*rstr)->refcount > 0)
7761d102b48SJeremy L Thompson     return 0;
7774ce2993fSjeremylt   if ((*rstr)->Destroy) {
7784ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
779d7b241e6Sjeremylt   }
7807509a596Sjeremylt   ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr);
7814ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
7824ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
783d7b241e6Sjeremylt   return 0;
784d7b241e6Sjeremylt }
785d7b241e6Sjeremylt 
786d7b241e6Sjeremylt /// @}
787