xref: /libCEED/interface/ceed-elemrestriction.c (revision 8621c6c6de0ebe428b5b7a9c1ff9e4a60667b9cc)
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 
2015910d16Sjeremylt /// @cond DOXYGEN_SKIP
2115910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none;
2215910d16Sjeremylt /// @endcond
2315910d16Sjeremylt 
24d7b241e6Sjeremylt /// @file
25d7b241e6Sjeremylt /// Implementation of public CeedElemRestriction interfaces
26d7b241e6Sjeremylt ///
27dfdf5a53Sjeremylt /// @addtogroup CeedElemRestriction
28d7b241e6Sjeremylt /// @{
29d7b241e6Sjeremylt 
30d7b241e6Sjeremylt /**
31b11c1e72Sjeremylt   @brief Create a CeedElemRestriction
32d7b241e6Sjeremylt 
33b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
3461dbc9d2Sjeremylt   @param imode      Ordering of the ncomp components, i.e. it specifies
35a8d32208Sjeremylt                       the ordering of the components of the L-vector used
3661dbc9d2Sjeremylt                       by this CeedElemRestriction. CEED_NONINTERLACED indicates
3761dbc9d2Sjeremylt                       the component is the outermost index and CEED_INTERLACED
38a8d32208Sjeremylt                       indicates the component is the innermost index in
39a8d32208Sjeremylt                       ordering of the L-vector.
40b11c1e72Sjeremylt   @param nelem      Number of elements described in the @a indices array
41b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
428795c945Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
438795c945Sjeremylt                       to which the restriction will be applied is of size
448795c945Sjeremylt                       @a nnodes * @a ncomp. This size may include data
45d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
46d7b241e6Sjeremylt                       different types of elements.
47b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
4895bb1877Svaleriabarra                       (1 for scalar fields)
49b11c1e72Sjeremylt   @param mtype      Memory type of the @a indices array, see CeedMemType
50b11c1e72Sjeremylt   @param cmode      Copy mode for the @a indices array, see CeedCopyMode
518795c945Sjeremylt   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the
528795c945Sjeremylt                       ordered list of the indices (into the input CeedVector)
538795c945Sjeremylt                       for the unknowns corresponding to element i, where
5434138859Sjeremylt                       0 <= i < @a nelem. All indices must be in the range
5523e8ed12Sjeremylt                       [0, @a nnodes - 1].
564ce2993fSjeremylt   @param[out] rstr  Address of the variable where the newly created
57b11c1e72Sjeremylt                       CeedElemRestriction will be stored
58d7b241e6Sjeremylt 
59b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
60dfdf5a53Sjeremylt 
61dfdf5a53Sjeremylt   @ref Basic
62b11c1e72Sjeremylt **/
6361dbc9d2Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInterlaceMode imode,
647509a596Sjeremylt                               CeedInt nelem, CeedInt elemsize, CeedInt nnodes,
657509a596Sjeremylt                               CeedInt ncomp, CeedMemType mtype,
667509a596Sjeremylt                               CeedCopyMode cmode, const CeedInt *indices,
674ce2993fSjeremylt                               CeedElemRestriction *rstr) {
68d7b241e6Sjeremylt   int ierr;
69d7b241e6Sjeremylt 
705fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
715fe0d4faSjeremylt     Ceed delegate;
72aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
73aefd8378Sjeremylt     CeedChk(ierr);
745fe0d4faSjeremylt 
755fe0d4faSjeremylt     if (!delegate)
76c042f62fSJeremy L Thompson       // LCOV_EXCL_START
77d7b241e6Sjeremylt       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
78c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
795fe0d4faSjeremylt 
8061dbc9d2Sjeremylt     ierr = CeedElemRestrictionCreate(delegate, imode, nelem, elemsize,
818795c945Sjeremylt                                      nnodes, ncomp, mtype, cmode,
824ce2993fSjeremylt                                      indices, rstr); CeedChk(ierr);
835fe0d4faSjeremylt     return 0;
845fe0d4faSjeremylt   }
855fe0d4faSjeremylt 
864ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
874ce2993fSjeremylt   (*rstr)->ceed = ceed;
88d7b241e6Sjeremylt   ceed->refcount++;
894ce2993fSjeremylt   (*rstr)->refcount = 1;
9061dbc9d2Sjeremylt   (*rstr)->imode = imode;
914ce2993fSjeremylt   (*rstr)->nelem = nelem;
924ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
938795c945Sjeremylt   (*rstr)->nnodes = nnodes;
944ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
954ce2993fSjeremylt   (*rstr)->nblk = nelem;
964ce2993fSjeremylt   (*rstr)->blksize = 1;
974ce2993fSjeremylt   ierr = ceed->ElemRestrictionCreate(mtype, cmode, indices, *rstr); CeedChk(ierr);
98d7b241e6Sjeremylt   return 0;
99d7b241e6Sjeremylt }
100d7b241e6Sjeremylt 
101d7b241e6Sjeremylt /**
1027509a596Sjeremylt   @brief Create a strided CeedElemRestriction
103d7b241e6Sjeremylt 
104b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
1057509a596Sjeremylt   @param nelem      Number of elements described by the restriction
106b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
1078795c945Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
1088795c945Sjeremylt                       to which the restriction will be applied is of size
1098795c945Sjeremylt                       @a nnodes * @a ncomp. This size may include data
110d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
1118795c945Sjeremylt                       different types of elements.
112b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
11395bb1877Svaleriabarra                       (1 for scalar fields)
1147509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
1157509a596Sjeremylt                       The data for node i, component j, element k in the
1167509a596Sjeremylt                       L-vector is given by
1177509a596Sjeremylt                         i*strides[0] + j*strides[1] + k*strides[2]
1184ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
119b11c1e72Sjeremylt                       CeedElemRestriction will be stored
120d7b241e6Sjeremylt 
121b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
122dfdf5a53Sjeremylt 
123dfdf5a53Sjeremylt   @ref Basic
124b11c1e72Sjeremylt **/
1257509a596Sjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt nelem, CeedInt elemsize,
126a8d32208Sjeremylt                                      CeedInt nnodes, CeedInt ncomp,
127*8621c6c6SJeremy L Thompson                                      const CeedInt strides[3],
128f90c8643Sjeremylt                                      CeedElemRestriction *rstr) {
129d7b241e6Sjeremylt   int ierr;
130d7b241e6Sjeremylt 
1315fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
1325fe0d4faSjeremylt     Ceed delegate;
133aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
134aefd8378Sjeremylt     CeedChk(ierr);
1355fe0d4faSjeremylt 
1365fe0d4faSjeremylt     if (!delegate)
137c042f62fSJeremy L Thompson       // LCOV_EXCL_START
1381d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
139c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
1405fe0d4faSjeremylt 
1417509a596Sjeremylt     ierr = CeedElemRestrictionCreateStrided(delegate, nelem, elemsize, nnodes,
1427509a596Sjeremylt                                             ncomp, strides, rstr); CeedChk(ierr);
1435fe0d4faSjeremylt     return 0;
1445fe0d4faSjeremylt   }
1455fe0d4faSjeremylt 
1464ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
1474ce2993fSjeremylt   (*rstr)->ceed = ceed;
148d7b241e6Sjeremylt   ceed->refcount++;
1494ce2993fSjeremylt   (*rstr)->refcount = 1;
1504ce2993fSjeremylt   (*rstr)->nelem = nelem;
1514ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
1528795c945Sjeremylt   (*rstr)->nnodes = nnodes;
1534ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
1544ce2993fSjeremylt   (*rstr)->nblk = nelem;
1554ce2993fSjeremylt   (*rstr)->blksize = 1;
1567509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
1577509a596Sjeremylt   for (int i = 0; i<3; i++)
1587509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
1591dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
1601dfeef1dSjeremylt                                      *rstr);
1614b8bea3bSJed Brown   CeedChk(ierr);
162d7b241e6Sjeremylt   return 0;
163d7b241e6Sjeremylt }
164d7b241e6Sjeremylt 
165d7b241e6Sjeremylt /**
166b11c1e72Sjeremylt   @brief Permute and pad indices for a blocked restriction
167d7b241e6Sjeremylt 
1688795c945Sjeremylt   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the
1698795c945Sjeremylt                       ordered list of the indices (into the input CeedVector)
1708795c945Sjeremylt                       for the unknowns corresponding to element i, where
17134138859Sjeremylt                       0 <= i < @a nelem. All indices must be in the range
1728795c945Sjeremylt                       [0, @a nnodes).
173ecf6354eSJed Brown   @param blkindices Array of permuted and padded indices of
174ecf6354eSJed Brown                       shape [@a nblk, @a elemsize, @a blksize].
175d7b241e6Sjeremylt   @param nblk       Number of blocks
176d7b241e6Sjeremylt   @param nelem      Number of elements
177d7b241e6Sjeremylt   @param blksize    Number of elements in a block
178d7b241e6Sjeremylt   @param elemsize   Size of each element
179d7b241e6Sjeremylt 
180b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
181b11c1e72Sjeremylt 
182dfdf5a53Sjeremylt   @ref Utility
183b11c1e72Sjeremylt **/
184dfdf5a53Sjeremylt int CeedPermutePadIndices(const CeedInt *indices, CeedInt *blkindices,
185692c2638Sjeremylt                           CeedInt nblk, CeedInt nelem, CeedInt blksize,
186692c2638Sjeremylt                           CeedInt elemsize) {
187d7b241e6Sjeremylt   for (CeedInt e = 0; e < nblk*blksize; e+=blksize)
188d7b241e6Sjeremylt     for (int j = 0; j < blksize; j++)
189d7b241e6Sjeremylt       for (int k = 0; k < elemsize; k++)
190d7b241e6Sjeremylt         blkindices[e*elemsize + k*blksize + j]
191d7b241e6Sjeremylt           = indices[CeedIntMin(e+j,nelem-1)*elemsize + k];
192dfdf5a53Sjeremylt   return 0;
193d7b241e6Sjeremylt }
194d7b241e6Sjeremylt 
195d7b241e6Sjeremylt /**
196b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
197d7b241e6Sjeremylt 
198d7b241e6Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created.
19961dbc9d2Sjeremylt   @param imode      Ordering of the ncomp components, i.e. it specifies
200a8d32208Sjeremylt                       the ordering of the components of the L-vector used
20161dbc9d2Sjeremylt                       by this CeedElemRestriction. CEED_NONINTERLACED indicates
20261dbc9d2Sjeremylt                       the component is the outermost index and CEED_INTERLACED
203a8d32208Sjeremylt                       indicates the component is the innermost index in
204a8d32208Sjeremylt                       ordering of the L-vector.
205d7b241e6Sjeremylt   @param nelem      Number of elements described in the @a indices array.
206b11c1e72Sjeremylt   @param elemsize   Size (number of unknowns) per element
207b11c1e72Sjeremylt   @param blksize    Number of elements in a block
2088795c945Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
2098795c945Sjeremylt                       to which the restriction will be applied is of size
2108795c945Sjeremylt                       @a nnodes * @a ncomp. This size may include data
211d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
212d7b241e6Sjeremylt                       different types of elements.
21395bb1877Svaleriabarra   @param ncomp      Number of field components per interpolation node
21495bb1877Svaleriabarra                       (1 for scalar fields)
215b11c1e72Sjeremylt   @param mtype      Memory type of the @a indices array, see CeedMemType
216b11c1e72Sjeremylt   @param cmode      Copy mode for the @a indices array, see CeedCopyMode
2178795c945Sjeremylt   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the
2188795c945Sjeremylt                       ordered list of the indices (into the input CeedVector)
2198795c945Sjeremylt                       for the unknowns corresponding to element i, where
22034138859Sjeremylt                       0 <= i < @a nelem. All indices must be in the range
2218795c945Sjeremylt                       [0, @a nnodes). The backend will permute and pad this
2228795c945Sjeremylt                       array to the desired ordering for the blocksize, which is
2238795c945Sjeremylt                       typically given by the backend. The default reordering is
2248795c945Sjeremylt                       to interlace elements.
2254ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
226b11c1e72Sjeremylt                       CeedElemRestriction will be stored
227d7b241e6Sjeremylt 
228b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
229dfdf5a53Sjeremylt 
230dfdf5a53Sjeremylt   @ref Advanced
231b11c1e72Sjeremylt  **/
23261dbc9d2Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed,  CeedInterlaceMode imode,
233a8d32208Sjeremylt                                      CeedInt nelem, CeedInt elemsize,
2348795c945Sjeremylt                                      CeedInt blksize, CeedInt nnodes,
2358795c945Sjeremylt                                      CeedInt ncomp, CeedMemType mtype,
2368795c945Sjeremylt                                      CeedCopyMode cmode, const CeedInt *indices,
2374ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
238d7b241e6Sjeremylt   int ierr;
239d7b241e6Sjeremylt   CeedInt *blkindices;
240d7b241e6Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
241d7b241e6Sjeremylt 
2425fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
2435fe0d4faSjeremylt     Ceed delegate;
244aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
245aefd8378Sjeremylt     CeedChk(ierr);
2465fe0d4faSjeremylt 
2475fe0d4faSjeremylt     if (!delegate)
248c042f62fSJeremy L Thompson       // LCOV_EXCL_START
2491d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support "
2501d102b48SJeremy L Thompson                        "ElemRestrictionCreateBlocked");
251c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
2525fe0d4faSjeremylt 
25361dbc9d2Sjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, imode, nelem, elemsize,
2548795c945Sjeremylt                                             blksize, nnodes, ncomp, mtype, cmode,
2554ce2993fSjeremylt                                             indices, rstr); CeedChk(ierr);
2565fe0d4faSjeremylt     return 0;
2575fe0d4faSjeremylt   }
258d7b241e6Sjeremylt 
2594ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
260d7b241e6Sjeremylt 
261de686571SJeremy L Thompson   ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr);
2624b8bea3bSJed Brown   ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize,
2634b8bea3bSJed Brown                                elemsize);
264dfdf5a53Sjeremylt   CeedChk(ierr);
265d7b241e6Sjeremylt 
2664ce2993fSjeremylt   (*rstr)->ceed = ceed;
267d7b241e6Sjeremylt   ceed->refcount++;
2684ce2993fSjeremylt   (*rstr)->refcount = 1;
26961dbc9d2Sjeremylt   (*rstr)->imode = imode;
2704ce2993fSjeremylt   (*rstr)->nelem = nelem;
2714ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
2728795c945Sjeremylt   (*rstr)->nnodes = nnodes;
2734ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
2744ce2993fSjeremylt   (*rstr)->nblk = nblk;
2754ce2993fSjeremylt   (*rstr)->blksize = blksize;
276667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
2777f823360Sjeremylt          (const CeedInt *) blkindices, *rstr); CeedChk(ierr);
278d7b241e6Sjeremylt 
2791d102b48SJeremy L Thompson   if (cmode == CEED_OWN_POINTER) {
280d7b241e6Sjeremylt     ierr = CeedFree(&indices); CeedChk(ierr);
2811d102b48SJeremy L Thompson   }
282d7b241e6Sjeremylt 
283d7b241e6Sjeremylt   return 0;
284d7b241e6Sjeremylt }
285d7b241e6Sjeremylt 
286b11c1e72Sjeremylt /**
2877509a596Sjeremylt   @brief Create a blocked strided CeedElemRestriction
2887509a596Sjeremylt 
2897509a596Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
2907509a596Sjeremylt   @param nelem      Number of elements described by the restriction
2917509a596Sjeremylt   @param elemsize   Size (number of "nodes") per element
2927509a596Sjeremylt   @param blksize    Number of elements in a block
2937509a596Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
2947509a596Sjeremylt                       to which the restriction will be applied is of size
2957509a596Sjeremylt                       @a nnodes * @a ncomp. This size may include data
2967509a596Sjeremylt                       used by other CeedElemRestriction objects describing
2977509a596Sjeremylt                       different types of elements.
2987509a596Sjeremylt   @param ncomp      Number of field components per interpolation node
2997509a596Sjeremylt                       (1 for scalar fields)
3007509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
3017509a596Sjeremylt                       The data for node i, component j, element k in the
3027509a596Sjeremylt                       L-vector is given by
3037509a596Sjeremylt                         i*strides[0] + j*strides[1] + k*strides[2]
3047509a596Sjeremylt   @param rstr       Address of the variable where the newly created
3057509a596Sjeremylt                       CeedElemRestriction will be stored
3067509a596Sjeremylt 
3077509a596Sjeremylt   @return An error code: 0 - success, otherwise - failure
3087509a596Sjeremylt 
3097509a596Sjeremylt   @ref Basic
3107509a596Sjeremylt **/
3117509a596Sjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt nelem,
312*8621c6c6SJeremy L Thompson     CeedInt elemsize, CeedInt blksize, CeedInt nnodes, CeedInt ncomp,
313*8621c6c6SJeremy L Thompson     const CeedInt strides[3], CeedElemRestriction *rstr) {
3147509a596Sjeremylt   int ierr;
3157509a596Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
3167509a596Sjeremylt 
3177509a596Sjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
3187509a596Sjeremylt     Ceed delegate;
3197509a596Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
3207509a596Sjeremylt     CeedChk(ierr);
3217509a596Sjeremylt 
3227509a596Sjeremylt     if (!delegate)
3237509a596Sjeremylt       // LCOV_EXCL_START
3247509a596Sjeremylt       return CeedError(ceed, 1, "Backend does not support "
3257509a596Sjeremylt                        "ElemRestrictionCreateBlocked");
3267509a596Sjeremylt     // LCOV_EXCL_STOP
3277509a596Sjeremylt 
3287509a596Sjeremylt     ierr = CeedElemRestrictionCreateBlockedStrided(delegate, nelem, elemsize,
329*8621c6c6SJeremy L Thompson            blksize, nnodes, ncomp, strides, rstr);
3307509a596Sjeremylt     CeedChk(ierr);
3317509a596Sjeremylt     return 0;
3327509a596Sjeremylt   }
3337509a596Sjeremylt 
3347509a596Sjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
3357509a596Sjeremylt 
3367509a596Sjeremylt   (*rstr)->ceed = ceed;
3377509a596Sjeremylt   ceed->refcount++;
3387509a596Sjeremylt   (*rstr)->refcount = 1;
3397509a596Sjeremylt   (*rstr)->nelem = nelem;
3407509a596Sjeremylt   (*rstr)->elemsize = elemsize;
3417509a596Sjeremylt   (*rstr)->nnodes = nnodes;
3427509a596Sjeremylt   (*rstr)->ncomp = ncomp;
3437509a596Sjeremylt   (*rstr)->nblk = nblk;
3447509a596Sjeremylt   (*rstr)->blksize = blksize;
3457509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
3467509a596Sjeremylt   for (int i = 0; i<3; i++)
3477509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
3487509a596Sjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
3497509a596Sjeremylt          NULL, *rstr); CeedChk(ierr);
3507509a596Sjeremylt 
3517509a596Sjeremylt   return 0;
3527509a596Sjeremylt }
3537509a596Sjeremylt 
3547509a596Sjeremylt /**
355b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
356b11c1e72Sjeremylt 
3574ce2993fSjeremylt   @param rstr  CeedElemRestriction
358b11c1e72Sjeremylt   @param lvec  The address of the L-vector to be created, or NULL
359b11c1e72Sjeremylt   @param evec  The address of the E-vector to be created, or NULL
360b11c1e72Sjeremylt 
361b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
362dfdf5a53Sjeremylt 
363dfdf5a53Sjeremylt   @ref Advanced
364b11c1e72Sjeremylt **/
3654ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec,
366d7b241e6Sjeremylt                                     CeedVector *evec) {
367d7b241e6Sjeremylt   int ierr;
368d7b241e6Sjeremylt   CeedInt n, m;
3698795c945Sjeremylt   m = rstr->nnodes * rstr->ncomp;
3704ce2993fSjeremylt   n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
371d7b241e6Sjeremylt   if (lvec) {
3724ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr);
373d7b241e6Sjeremylt   }
374d7b241e6Sjeremylt   if (evec) {
3754ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr);
376d7b241e6Sjeremylt   }
377d7b241e6Sjeremylt   return 0;
378d7b241e6Sjeremylt }
379d7b241e6Sjeremylt 
380d7b241e6Sjeremylt /**
381d9e1f99aSValeria Barra   @brief Restrict an L-vector to an E-vector or apply its transpose
382d7b241e6Sjeremylt 
3834ce2993fSjeremylt   @param rstr    CeedElemRestriction
384d7b241e6Sjeremylt   @param tmode   Apply restriction or transpose
3857aaeacdcSjeremylt   @param u       Input vector (of shape [@a nnodes, @a ncomp] when
38661dbc9d2Sjeremylt                    tmode=CEED_NOTRANSPOSE, imode=CEED_INTERLACED)
387a8d32208Sjeremylt   @param ru      Output vector (of shape [@a nelem * @a elemsize] when
3887aaeacdcSjeremylt                    tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided
3897aaeacdcSjeremylt                    by the backend.
390d7b241e6Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
391b11c1e72Sjeremylt 
392b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
393dfdf5a53Sjeremylt 
394dfdf5a53Sjeremylt   @ref Advanced
395b11c1e72Sjeremylt **/
3964ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode,
397a8d32208Sjeremylt                              CeedVector u, CeedVector ru,
398a8d32208Sjeremylt                              CeedRequest *request) {
399d7b241e6Sjeremylt   CeedInt m,n;
400d7b241e6Sjeremylt   int ierr;
401d7b241e6Sjeremylt 
402d7b241e6Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
4034ce2993fSjeremylt     m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
4048795c945Sjeremylt     n = rstr->nnodes * rstr->ncomp;
405d7b241e6Sjeremylt   } else {
4068795c945Sjeremylt     m = rstr->nnodes * rstr->ncomp;
4074ce2993fSjeremylt     n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
408d7b241e6Sjeremylt   }
409d7b241e6Sjeremylt   if (n != u->length)
410c042f62fSJeremy L Thompson     // LCOV_EXCL_START
4111d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
4121d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
413c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
414a8d32208Sjeremylt   if (m != ru->length)
415c042f62fSJeremy L Thompson     // LCOV_EXCL_START
4161d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
417a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
418c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
419074cb416Sjeremylt   ierr = rstr->Apply(rstr, tmode, u, ru, request); CeedChk(ierr);
420d7b241e6Sjeremylt 
421d7b241e6Sjeremylt   return 0;
422d7b241e6Sjeremylt }
423d7b241e6Sjeremylt 
424d7b241e6Sjeremylt /**
425d9e1f99aSValeria Barra   @brief Restrict an L-vector to a block of an E-vector or apply its transpose
426be9261b7Sjeremylt 
427be9261b7Sjeremylt   @param rstr    CeedElemRestriction
4281f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
4291f37b403Sjeremylt                    elements [0 : blksize] and block=3 will handle elements
4301f37b403Sjeremylt                    [3*blksize : 4*blksize]
431be9261b7Sjeremylt   @param tmode   Apply restriction or transpose
4327aaeacdcSjeremylt   @param u       Input vector (of shape [@a nnodes, @a ncomp] when
43361dbc9d2Sjeremylt                    tmode=CEED_NOTRANSPOSE, imode=CEED_INTERLACED)
434a8d32208Sjeremylt   @param ru      Output vector (of shape [@a blksize * @a elemsize] when
4357aaeacdcSjeremylt                    tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided
4367aaeacdcSjeremylt                    by the backend.
437be9261b7Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
438be9261b7Sjeremylt 
439be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
440be9261b7Sjeremylt 
441be9261b7Sjeremylt   @ref Advanced
442be9261b7Sjeremylt **/
443be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
444a8d32208Sjeremylt                                   CeedTransposeMode tmode, CeedVector u,
445a8d32208Sjeremylt                                   CeedVector ru, CeedRequest *request) {
446be9261b7Sjeremylt   CeedInt m,n;
447be9261b7Sjeremylt   int ierr;
448be9261b7Sjeremylt 
449be9261b7Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
450be9261b7Sjeremylt     m = rstr->blksize * rstr->elemsize * rstr->ncomp;
4518795c945Sjeremylt     n = rstr->nnodes * rstr->ncomp;
452be9261b7Sjeremylt   } else {
4538795c945Sjeremylt     m = rstr->nnodes * rstr->ncomp;
454be9261b7Sjeremylt     n = rstr->blksize * rstr->elemsize * rstr->ncomp;
455be9261b7Sjeremylt   }
456be9261b7Sjeremylt   if (n != u->length)
457c042f62fSJeremy L Thompson     // LCOV_EXCL_START
4581d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
4591d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
460c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
461a8d32208Sjeremylt   if (m != ru->length)
462c042f62fSJeremy L Thompson     // LCOV_EXCL_START
4631d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
464a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
465c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
466be9261b7Sjeremylt   if (rstr->blksize*block > rstr->nelem)
467c042f62fSJeremy L Thompson     // LCOV_EXCL_START
4681d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > "
4691d102b48SJeremy L Thompson                      "total elements %d", block, rstr->blksize*block,
4701d102b48SJeremy L Thompson                      rstr->nelem);
471c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
472074cb416Sjeremylt   ierr = rstr->ApplyBlock(rstr, block, tmode, u, ru, request);
473be9261b7Sjeremylt   CeedChk(ierr);
474be9261b7Sjeremylt 
475be9261b7Sjeremylt   return 0;
476be9261b7Sjeremylt }
477be9261b7Sjeremylt 
478be9261b7Sjeremylt /**
479d9e1f99aSValeria Barra   @brief Get the multiplicity of nodes in a CeedElemRestriction
4801469ee4dSjeremylt 
4811469ee4dSjeremylt   @param rstr             CeedElemRestriction
482b9c05c73SJed Brown   @param[out] mult        Vector to store multiplicity (of size nnodes*ncomp)
4831469ee4dSjeremylt 
4841469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
4851469ee4dSjeremylt 
4861469ee4dSjeremylt   @ref Advanced
4871469ee4dSjeremylt **/
4881469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
4891469ee4dSjeremylt                                        CeedVector mult) {
4901469ee4dSjeremylt   int ierr;
4911469ee4dSjeremylt   CeedVector evec;
4921469ee4dSjeremylt 
4931469ee4dSjeremylt   // Create and set evec
4941469ee4dSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr);
4951469ee4dSjeremylt   ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr);
496fa9eac48SJed Brown   ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr);
4971469ee4dSjeremylt 
4981469ee4dSjeremylt   // Apply to get multiplicity
499a8d32208Sjeremylt   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult,
500efc78312Sjeremylt                                   CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
5011469ee4dSjeremylt 
5021469ee4dSjeremylt   // Cleanup
5031469ee4dSjeremylt   ierr = CeedVectorDestroy(&evec); CeedChk(ierr);
5041469ee4dSjeremylt 
5051469ee4dSjeremylt   return 0;
5061469ee4dSjeremylt }
5071469ee4dSjeremylt 
5081469ee4dSjeremylt /**
5094ce2993fSjeremylt   @brief Get the Ceed associated with a CeedElemRestriction
5104ce2993fSjeremylt 
5114ce2993fSjeremylt   @param rstr             CeedElemRestriction
5124ce2993fSjeremylt   @param[out] ceed        Variable to store Ceed
5134ce2993fSjeremylt 
5144ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
5154ce2993fSjeremylt 
51623617272Sjeremylt   @ref Advanced
5174ce2993fSjeremylt **/
5184ce2993fSjeremylt int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) {
5194ce2993fSjeremylt   *ceed = rstr->ceed;
5204ce2993fSjeremylt   return 0;
5214ce2993fSjeremylt }
5224ce2993fSjeremylt 
5234ce2993fSjeremylt /**
52461dbc9d2Sjeremylt   @brief Get the L-vector interlaced mode of a CeedElemRestriction
525a8d32208Sjeremylt 
526a8d32208Sjeremylt   @param rstr             CeedElemRestriction
52761dbc9d2Sjeremylt   @param[out] imode       Variable to store imode
528a8d32208Sjeremylt 
529a8d32208Sjeremylt   @return An error code: 0 - success, otherwise - failure
530a8d32208Sjeremylt 
531a8d32208Sjeremylt   @ref Advanced
532a8d32208Sjeremylt **/
53361dbc9d2Sjeremylt int CeedElemRestrictionGetIMode(CeedElemRestriction rstr,
53461dbc9d2Sjeremylt                                 CeedInterlaceMode *imode) {
5357509a596Sjeremylt   if (rstr->strides)
5367509a596Sjeremylt     // LCOV_EXCL_START
5377509a596Sjeremylt     return CeedError(rstr->ceed, 1, "Strided ElemRestriction has no interlace "
5387509a596Sjeremylt                      "mode");
5397509a596Sjeremylt   // LCOV_EXCL_STOP
5407509a596Sjeremylt 
54161dbc9d2Sjeremylt   *imode = rstr->imode;
542a8d32208Sjeremylt   return 0;
543a8d32208Sjeremylt }
544a8d32208Sjeremylt 
545a8d32208Sjeremylt /**
546b11c1e72Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
547d7b241e6Sjeremylt 
5484ce2993fSjeremylt   @param rstr             CeedElemRestriction
549288c0443SJeremy L Thompson   @param[out] numelem     Variable to store number of elements
550b11c1e72Sjeremylt 
551b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
552dfdf5a53Sjeremylt 
55323617272Sjeremylt   @ref Advanced
554b11c1e72Sjeremylt **/
5554ce2993fSjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
5564ce2993fSjeremylt                                       CeedInt *numelem) {
5574ce2993fSjeremylt   *numelem = rstr->nelem;
5584ce2993fSjeremylt   return 0;
5594ce2993fSjeremylt }
5604ce2993fSjeremylt 
5614ce2993fSjeremylt /**
5624ce2993fSjeremylt   @brief Get the size of elements in the CeedElemRestriction
5634ce2993fSjeremylt 
5644ce2993fSjeremylt   @param rstr             CeedElemRestriction
5654ce2993fSjeremylt   @param[out] elemsize    Variable to store size of elements
5664ce2993fSjeremylt 
5674ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
5684ce2993fSjeremylt 
56923617272Sjeremylt   @ref Advanced
5704ce2993fSjeremylt **/
5714ce2993fSjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
5724ce2993fSjeremylt                                       CeedInt *elemsize) {
5734ce2993fSjeremylt   *elemsize = rstr->elemsize;
5744ce2993fSjeremylt   return 0;
5754ce2993fSjeremylt }
5764ce2993fSjeremylt 
5774ce2993fSjeremylt /**
5784ce2993fSjeremylt   @brief Get the number of degrees of freedom in the range of a
5794ce2993fSjeremylt          CeedElemRestriction
5804ce2993fSjeremylt 
5814ce2993fSjeremylt   @param rstr             CeedElemRestriction
5828795c945Sjeremylt   @param[out] numnodes    Variable to store number of nodes
5834ce2993fSjeremylt 
5844ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
5854ce2993fSjeremylt 
58623617272Sjeremylt   @ref Advanced
5874ce2993fSjeremylt **/
5888795c945Sjeremylt int CeedElemRestrictionGetNumNodes(CeedElemRestriction rstr,
5898795c945Sjeremylt                                    CeedInt *numnodes) {
5908795c945Sjeremylt   *numnodes = rstr->nnodes;
5914ce2993fSjeremylt   return 0;
5924ce2993fSjeremylt }
5934ce2993fSjeremylt 
5944ce2993fSjeremylt /**
5954ce2993fSjeremylt   @brief Get the number of components in the elements of a
5964ce2993fSjeremylt          CeedElemRestriction
5974ce2993fSjeremylt 
5984ce2993fSjeremylt   @param rstr             CeedElemRestriction
5994ce2993fSjeremylt   @param[out] numcomp     Variable to store number of components
6004ce2993fSjeremylt 
6014ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
6024ce2993fSjeremylt 
60323617272Sjeremylt   @ref Advanced
6044ce2993fSjeremylt **/
6054ce2993fSjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
6064ce2993fSjeremylt                                         CeedInt *numcomp) {
6074ce2993fSjeremylt   *numcomp = rstr->ncomp;
6084ce2993fSjeremylt   return 0;
6094ce2993fSjeremylt }
6104ce2993fSjeremylt 
6114ce2993fSjeremylt /**
6124ce2993fSjeremylt   @brief Get the number of blocks in a CeedElemRestriction
6134ce2993fSjeremylt 
6144ce2993fSjeremylt   @param rstr             CeedElemRestriction
6154ce2993fSjeremylt   @param[out] numblock    Variable to store number of blocks
6164ce2993fSjeremylt 
6174ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
6184ce2993fSjeremylt 
61923617272Sjeremylt   @ref Advanced
6204ce2993fSjeremylt **/
6214ce2993fSjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
6224ce2993fSjeremylt                                     CeedInt *numblock) {
6234ce2993fSjeremylt   *numblock = rstr->nblk;
6244ce2993fSjeremylt   return 0;
6254ce2993fSjeremylt }
6264ce2993fSjeremylt 
6274ce2993fSjeremylt /**
6284ce2993fSjeremylt   @brief Get the size of blocks in the CeedElemRestriction
6294ce2993fSjeremylt 
630288c0443SJeremy L Thompson   @param rstr             CeedElemRestriction
6314ce2993fSjeremylt   @param[out] blksize     Variable to store size of blocks
6324ce2993fSjeremylt 
6334ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
6344ce2993fSjeremylt 
63523617272Sjeremylt   @ref Advanced
6364ce2993fSjeremylt **/
6374ce2993fSjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
6384ce2993fSjeremylt                                     CeedInt *blksize) {
6394ce2993fSjeremylt   *blksize = rstr->blksize;
6404ce2993fSjeremylt   return 0;
6414ce2993fSjeremylt }
6424ce2993fSjeremylt 
6434ce2993fSjeremylt /**
6447509a596Sjeremylt   @brief Get the strides of a strided CeedElemRestriction
6457509a596Sjeremylt 
6467509a596Sjeremylt   @param rstr             CeedElemRestriction
6477509a596Sjeremylt   @param[out] strides     Variable to store strides array
6487509a596Sjeremylt 
6497509a596Sjeremylt   @return An error code: 0 - success, otherwise - failure
6507509a596Sjeremylt 
6517509a596Sjeremylt   @ref Advanced
6527509a596Sjeremylt **/
6537509a596Sjeremylt int CeedElemRestrictionGetStrides(CeedElemRestriction rstr,
6547509a596Sjeremylt                                   CeedInt (*strides)[3]) {
6557509a596Sjeremylt   if (!rstr->strides)
6567509a596Sjeremylt     // LCOV_EXCL_START
6577509a596Sjeremylt     return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data");
6587509a596Sjeremylt   // LCOV_EXCL_STOP
6597509a596Sjeremylt 
6607509a596Sjeremylt   for (int i = 0; i<3; i++)
6617509a596Sjeremylt     (*strides)[i] = rstr->strides[i];
6627509a596Sjeremylt   return 0;
6637509a596Sjeremylt }
6647509a596Sjeremylt 
6657509a596Sjeremylt /**
666523b8ea0Sjeremylt   @brief Get the backend stride status of a CeedElemRestriction
667523b8ea0Sjeremylt 
668523b8ea0Sjeremylt   @param rstr             CeedElemRestriction
669523b8ea0Sjeremylt   @param[out] bool        Variable to store stride status
670523b8ea0Sjeremylt 
671523b8ea0Sjeremylt   @return An error code: 0 - success, otherwise - failure
672523b8ea0Sjeremylt 
673523b8ea0Sjeremylt   @ref Advanced
674523b8ea0Sjeremylt **/
675523b8ea0Sjeremylt int CeedElemRestrictionGetBackendStridesStatus(CeedElemRestriction rstr,
676523b8ea0Sjeremylt     bool *status) {
677523b8ea0Sjeremylt   if (!rstr->strides)
678523b8ea0Sjeremylt     // LCOV_EXCL_START
679523b8ea0Sjeremylt     return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data");
680523b8ea0Sjeremylt   // LCOV_EXCL_STOP
681523b8ea0Sjeremylt 
682523b8ea0Sjeremylt   *status = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) &&
683523b8ea0Sjeremylt              (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) &&
684523b8ea0Sjeremylt              (rstr->strides[2] == CEED_STRIDES_BACKEND[2]));
685523b8ea0Sjeremylt   return 0;
686523b8ea0Sjeremylt }
687523b8ea0Sjeremylt 
688523b8ea0Sjeremylt /**
6894ce2993fSjeremylt   @brief Get the backend data of a CeedElemRestriction
6904ce2993fSjeremylt 
691288c0443SJeremy L Thompson   @param rstr             CeedElemRestriction
6924ce2993fSjeremylt   @param[out] data        Variable to store data
6934ce2993fSjeremylt 
6944ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
6954ce2993fSjeremylt 
69623617272Sjeremylt   @ref Advanced
6974ce2993fSjeremylt **/
6981d102b48SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) {
6994ce2993fSjeremylt   *data = rstr->data;
700d7b241e6Sjeremylt   return 0;
701d7b241e6Sjeremylt }
702d7b241e6Sjeremylt 
703d7b241e6Sjeremylt /**
704fe2413ffSjeremylt   @brief Set the backend data of a CeedElemRestriction
705fe2413ffSjeremylt 
706288c0443SJeremy L Thompson   @param[out] rstr        CeedElemRestriction
707fe2413ffSjeremylt   @param data             Data to set
708fe2413ffSjeremylt 
709fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
710fe2413ffSjeremylt 
711fe2413ffSjeremylt   @ref Advanced
712fe2413ffSjeremylt **/
7131d102b48SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) {
714fe2413ffSjeremylt   rstr->data = *data;
715fe2413ffSjeremylt   return 0;
716fe2413ffSjeremylt }
717fe2413ffSjeremylt 
718fe2413ffSjeremylt /**
719f02ca4a2SJed Brown   @brief View a CeedElemRestriction
720f02ca4a2SJed Brown 
721f02ca4a2SJed Brown   @param[in] rstr    CeedElemRestriction to view
722f02ca4a2SJed Brown   @param[in] stream  Stream to write; typically stdout/stderr or a file
723f02ca4a2SJed Brown 
724f02ca4a2SJed Brown   @return Error code: 0 - success, otherwise - failure
725f02ca4a2SJed Brown 
726f02ca4a2SJed Brown   @ref Utility
727f02ca4a2SJed Brown **/
728f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
7297509a596Sjeremylt   char stridesstr[500];
7307509a596Sjeremylt   if (rstr->strides)
7317509a596Sjeremylt     sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1],
7327509a596Sjeremylt             rstr->strides[2]);
7337509a596Sjeremylt 
7340036de2cSjeremylt   fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d "
7350036de2cSjeremylt           "nodes each and %s %s\n", rstr->blksize > 1 ? "Blocked " : "",
7360036de2cSjeremylt           rstr->nnodes, rstr->ncomp, rstr->nelem, rstr->elemsize,
7370036de2cSjeremylt           rstr->strides ? "strides" : "L-vector components",
7387509a596Sjeremylt           rstr->strides ? stridesstr : CeedInterlaceModes[rstr->imode]);
739f02ca4a2SJed Brown   return 0;
740f02ca4a2SJed Brown }
741f02ca4a2SJed Brown 
742f02ca4a2SJed Brown /**
743b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
744b11c1e72Sjeremylt 
7454ce2993fSjeremylt   @param rstr  CeedElemRestriction to destroy
746b11c1e72Sjeremylt 
747b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
748dfdf5a53Sjeremylt 
749dfdf5a53Sjeremylt   @ref Basic
750b11c1e72Sjeremylt **/
7514ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
752d7b241e6Sjeremylt   int ierr;
753d7b241e6Sjeremylt 
7541d102b48SJeremy L Thompson   if (!*rstr || --(*rstr)->refcount > 0)
7551d102b48SJeremy L Thompson     return 0;
7564ce2993fSjeremylt   if ((*rstr)->Destroy) {
7574ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
758d7b241e6Sjeremylt   }
7597509a596Sjeremylt   ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr);
7604ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
7614ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
762d7b241e6Sjeremylt   return 0;
763d7b241e6Sjeremylt }
764d7b241e6Sjeremylt 
765523b8ea0Sjeremylt /// @cond DOXYGEN_SKIP
766523b8ea0Sjeremylt // Indicate that the stride is determined by the backend
767523b8ea0Sjeremylt CeedInt CEED_STRIDES_BACKEND[3] = {};
76815910d16Sjeremylt 
76915910d16Sjeremylt // Indicate that no ElemRestriction is provided by the user
77015910d16Sjeremylt CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none;
771523b8ea0Sjeremylt /// @endcond
772523b8ea0Sjeremylt 
773d7b241e6Sjeremylt /// @}
774