xref: /libCEED/interface/ceed-elemrestriction.c (revision 49fd234cd5a6b1faaf6ecfc267b22ac88f378a38)
1d7b241e6Sjeremylt // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2d7b241e6Sjeremylt // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3d7b241e6Sjeremylt // reserved. See files LICENSE and NOTICE for details.
4d7b241e6Sjeremylt //
5d7b241e6Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software
6d7b241e6Sjeremylt // libraries and APIs for efficient high-order finite element and spectral
7d7b241e6Sjeremylt // element discretizations for exascale applications. For more information and
8d7b241e6Sjeremylt // source code availability see http://github.com/ceed.
9d7b241e6Sjeremylt //
10d7b241e6Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11d7b241e6Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office
12d7b241e6Sjeremylt // of Science and the National Nuclear Security Administration) responsible for
13d7b241e6Sjeremylt // the planning and preparation of a capable exascale ecosystem, including
14d7b241e6Sjeremylt // software, applications, hardware, advanced system engineering and early
15d7b241e6Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative.
16d7b241e6Sjeremylt 
17d7b241e6Sjeremylt #include <ceed-impl.h>
18d863ab9bSjeremylt #include <ceed-backend.h>
19d7b241e6Sjeremylt 
207a982d89SJeremy L. Thompson /// @file
217a982d89SJeremy L. Thompson /// Implementation of CeedElemRestriction interfaces
227a982d89SJeremy L. Thompson 
237a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
247a982d89SJeremy L. Thompson /// CeedElemRestriction Library Internal Functions
257a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
267a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionDeveloper
277a982d89SJeremy L. Thompson /// @{
287a982d89SJeremy L. Thompson 
297a982d89SJeremy L. Thompson /**
30d979a051Sjeremylt   @brief Permute and pad offsets for a blocked restriction
317a982d89SJeremy L. Thompson 
32d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
33d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
347a982d89SJeremy L. Thompson                       for the unknowns corresponding to element i, where
35d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
36d979a051Sjeremylt                       [0, @a lsize - 1].
37d979a051Sjeremylt   @param blkoffsets Array of permuted and padded offsets of
387a982d89SJeremy L. Thompson                       shape [@a nblk, @a elemsize, @a blksize].
397a982d89SJeremy L. Thompson   @param nblk       Number of blocks
407a982d89SJeremy L. Thompson   @param nelem      Number of elements
417a982d89SJeremy L. Thompson   @param blksize    Number of elements in a block
427a982d89SJeremy L. Thompson   @param elemsize   Size of each element
437a982d89SJeremy L. Thompson 
447a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
457a982d89SJeremy L. Thompson 
467a982d89SJeremy L. Thompson   @ref Utility
477a982d89SJeremy L. Thompson **/
48d979a051Sjeremylt int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blkoffsets,
497a982d89SJeremy L. Thompson                           CeedInt nblk, CeedInt nelem, CeedInt blksize,
507a982d89SJeremy L. Thompson                           CeedInt elemsize) {
517a982d89SJeremy L. Thompson   for (CeedInt e = 0; e < nblk*blksize; e+=blksize)
527a982d89SJeremy L. Thompson     for (int j = 0; j < blksize; j++)
537a982d89SJeremy L. Thompson       for (int k = 0; k < elemsize; k++)
54d979a051Sjeremylt         blkoffsets[e*elemsize + k*blksize + j]
55d979a051Sjeremylt           = offsets[CeedIntMin(e+j,nelem-1)*elemsize + k];
567a982d89SJeremy L. Thompson   return 0;
577a982d89SJeremy L. Thompson }
587a982d89SJeremy L. Thompson 
597a982d89SJeremy L. Thompson /// @}
607a982d89SJeremy L. Thompson 
617a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
627a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API
637a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
647a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend
657a982d89SJeremy L. Thompson /// @{
667a982d89SJeremy L. Thompson 
677a982d89SJeremy L. Thompson /**
687a982d89SJeremy L. Thompson   @brief Get the Ceed associated with a CeedElemRestriction
697a982d89SJeremy L. Thompson 
707a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
717a982d89SJeremy L. Thompson   @param[out] ceed        Variable to store Ceed
727a982d89SJeremy L. Thompson 
737a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
747a982d89SJeremy L. Thompson 
757a982d89SJeremy L. Thompson   @ref Backend
767a982d89SJeremy L. Thompson **/
777a982d89SJeremy L. Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) {
787a982d89SJeremy L. Thompson   *ceed = rstr->ceed;
797a982d89SJeremy L. Thompson   return 0;
807a982d89SJeremy L. Thompson }
817a982d89SJeremy L. Thompson 
827a982d89SJeremy L. Thompson /**
83a681ae63Sjeremylt 
84a681ae63Sjeremylt   @brief Get the strides of a strided CeedElemRestriction
857a982d89SJeremy L. Thompson 
867a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
87a681ae63Sjeremylt   @param[out] strides     Variable to store strides array
887a982d89SJeremy L. Thompson 
897a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
907a982d89SJeremy L. Thompson 
917a982d89SJeremy L. Thompson   @ref Backend
927a982d89SJeremy L. Thompson **/
93a681ae63Sjeremylt int CeedElemRestrictionGetStrides(CeedElemRestriction rstr,
94a681ae63Sjeremylt                                   CeedInt (*strides)[3]) {
95a681ae63Sjeremylt   if (!rstr->strides)
96a681ae63Sjeremylt     // LCOV_EXCL_START
97a681ae63Sjeremylt     return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data");
98a681ae63Sjeremylt   // LCOV_EXCL_STOP
99a681ae63Sjeremylt 
100a681ae63Sjeremylt   for (int i = 0; i<3; i++)
101a681ae63Sjeremylt     (*strides)[i] = rstr->strides[i];
1027a982d89SJeremy L. Thompson   return 0;
1037a982d89SJeremy L. Thompson }
1047a982d89SJeremy L. Thompson 
1057a982d89SJeremy L. Thompson /**
106bd33150aSjeremylt   @brief Get read-only access to a CeedElemRestriction offsets array by memtype
107bd33150aSjeremylt 
108bd33150aSjeremylt   @param rstr         CeedElemRestriction to retrieve offsets
109bd33150aSjeremylt   @param mtype        Memory type on which to access the array.  If the backend
110bd33150aSjeremylt                         uses a different memory type, this will perform a copy
111bd33150aSjeremylt                         (possibly cached).
112bd33150aSjeremylt   @param[out] offsets Array on memory type mtype
113bd33150aSjeremylt 
114bd33150aSjeremylt   @return An error code: 0 - success, otherwise - failure
115bd33150aSjeremylt 
116bd33150aSjeremylt   @ref User
117bd33150aSjeremylt **/
118bd33150aSjeremylt int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mtype,
119bd33150aSjeremylt                                   const CeedInt **offsets) {
120bd33150aSjeremylt   int ierr;
121bd33150aSjeremylt 
122bd33150aSjeremylt   if (!rstr->GetOffsets)
123bd33150aSjeremylt     // LCOV_EXCL_START
124bd33150aSjeremylt     return CeedError(rstr->ceed, 1, "Backend does not support GetOffsets");
125bd33150aSjeremylt   // LCOV_EXCL_STOP
126bd33150aSjeremylt 
127bd33150aSjeremylt   ierr = rstr->GetOffsets(rstr, mtype, offsets); CeedChk(ierr);
128430758c8SJeremy L Thompson   rstr->numreaders++;
129430758c8SJeremy L Thompson   return 0;
130430758c8SJeremy L Thompson }
131430758c8SJeremy L Thompson 
132430758c8SJeremy L Thompson /**
133430758c8SJeremy L Thompson   @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets()
134430758c8SJeremy L Thompson 
135430758c8SJeremy L Thompson   @param rstr    CeedElemRestriction to restore
136430758c8SJeremy L Thompson   @param offsets Array of offset data
137430758c8SJeremy L Thompson 
138430758c8SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
139430758c8SJeremy L Thompson 
140430758c8SJeremy L Thompson   @ref User
141430758c8SJeremy L Thompson **/
142430758c8SJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr,
143430758c8SJeremy L Thompson                                       const CeedInt **offsets) {
144430758c8SJeremy L Thompson   *offsets = NULL;
145430758c8SJeremy L Thompson   rstr->numreaders--;
146bd33150aSjeremylt   return 0;
147bd33150aSjeremylt }
148bd33150aSjeremylt 
149bd33150aSjeremylt /**
1503ac43b2cSJeremy L Thompson   @brief Get the strided status of a CeedElemRestriction
1513ac43b2cSJeremy L Thompson 
1523ac43b2cSJeremy L Thompson   @param rstr             CeedElemRestriction
1533ac43b2cSJeremy L Thompson   @param[out] status      Variable to store strided status, 1 if strided else 0
1543ac43b2cSJeremy L Thompson 
1553ac43b2cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1563ac43b2cSJeremy L Thompson 
1573ac43b2cSJeremy L Thompson   @ref Backend
1583ac43b2cSJeremy L Thompson **/
1593ac43b2cSJeremy L Thompson int CeedElemRestrictionGetStridedStatus(CeedElemRestriction rstr,
1603ac43b2cSJeremy L Thompson                                         bool *status) {
1613ac43b2cSJeremy L Thompson   *status = rstr->strides ? 1 : 0;
1623ac43b2cSJeremy L Thompson   return 0;
1633ac43b2cSJeremy L Thompson }
1643ac43b2cSJeremy L Thompson 
1653ac43b2cSJeremy L Thompson /**
166a681ae63Sjeremylt   @brief Get the backend stride status of a CeedElemRestriction
1677a982d89SJeremy L. Thompson 
1687a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
169a681ae63Sjeremylt   @param[out] status      Variable to store stride status
1707a982d89SJeremy L. Thompson 
1717a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
1727a982d89SJeremy L. Thompson 
1737a982d89SJeremy L. Thompson   @ref Backend
1747a982d89SJeremy L. Thompson **/
175a681ae63Sjeremylt int CeedElemRestrictionGetBackendStridesStatus(CeedElemRestriction rstr,
176a681ae63Sjeremylt     bool *status) {
177a681ae63Sjeremylt   if (!rstr->strides)
178a681ae63Sjeremylt     // LCOV_EXCL_START
179a681ae63Sjeremylt     return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data");
180a681ae63Sjeremylt   // LCOV_EXCL_STOP
1817a982d89SJeremy L. Thompson 
182a681ae63Sjeremylt   *status = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) &&
183a681ae63Sjeremylt              (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) &&
184a681ae63Sjeremylt              (rstr->strides[2] == CEED_STRIDES_BACKEND[2]));
1857a982d89SJeremy L. Thompson   return 0;
1867a982d89SJeremy L. Thompson }
1877a982d89SJeremy L. Thompson 
1887a982d89SJeremy L. Thompson /**
189*49fd234cSJeremy L Thompson 
190*49fd234cSJeremy L Thompson   @brief Get the E-vector layout of a CeedElemRestriction
191*49fd234cSJeremy L Thompson 
192*49fd234cSJeremy L Thompson   @param rstr             CeedElemRestriction
193*49fd234cSJeremy L Thompson   @param[out] layout      Variable to store layout array,
194*49fd234cSJeremy L Thompson                             stored as [nodes, components, elements].
195*49fd234cSJeremy L Thompson                             The data for node i, component j, element k in the
196*49fd234cSJeremy L Thompson                             E-vector is given by
197*49fd234cSJeremy L Thompson                             i*strides[0] + j*strides[1] + k*strides[2]
198*49fd234cSJeremy L Thompson 
199*49fd234cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
200*49fd234cSJeremy L Thompson 
201*49fd234cSJeremy L Thompson   @ref Backend
202*49fd234cSJeremy L Thompson **/
203*49fd234cSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr,
204*49fd234cSJeremy L Thompson                                   CeedInt (*layout)[3]) {
205*49fd234cSJeremy L Thompson   if (!rstr->layout[0])
206*49fd234cSJeremy L Thompson     // LCOV_EXCL_START
207*49fd234cSJeremy L Thompson     return CeedError(rstr->ceed, 1, "ElemRestriction has no layout data");
208*49fd234cSJeremy L Thompson   // LCOV_EXCL_STOP
209*49fd234cSJeremy L Thompson 
210*49fd234cSJeremy L Thompson   for (int i = 0; i<3; i++)
211*49fd234cSJeremy L Thompson     (*layout)[i] = rstr->layout[i];
212*49fd234cSJeremy L Thompson   return 0;
213*49fd234cSJeremy L Thompson }
214*49fd234cSJeremy L Thompson 
215*49fd234cSJeremy L Thompson /**
216*49fd234cSJeremy L Thompson 
217*49fd234cSJeremy L Thompson   @brief Set the E-vector layout of a CeedElemRestriction
218*49fd234cSJeremy L Thompson 
219*49fd234cSJeremy L Thompson   @param rstr             CeedElemRestriction
220*49fd234cSJeremy L Thompson   @param layout           Variable to containing layout array,
221*49fd234cSJeremy L Thompson                             stored as [nodes, components, elements].
222*49fd234cSJeremy L Thompson                             The data for node i, component j, element k in the
223*49fd234cSJeremy L Thompson                             E-vector is given by
224*49fd234cSJeremy L Thompson                             i*strides[0] + j*strides[1] + k*strides[2]
225*49fd234cSJeremy L Thompson 
226*49fd234cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
227*49fd234cSJeremy L Thompson 
228*49fd234cSJeremy L Thompson   @ref Backend
229*49fd234cSJeremy L Thompson **/
230*49fd234cSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr,
231*49fd234cSJeremy L Thompson                                   CeedInt layout[3]) {
232*49fd234cSJeremy L Thompson   for (int i = 0; i<3; i++)
233*49fd234cSJeremy L Thompson     rstr->layout[i] = layout[i];
234*49fd234cSJeremy L Thompson   return 0;
235*49fd234cSJeremy L Thompson }
236*49fd234cSJeremy L Thompson 
237*49fd234cSJeremy L Thompson /**
2387a982d89SJeremy L. Thompson   @brief Get the backend data of a CeedElemRestriction
2397a982d89SJeremy L. Thompson 
2407a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
2417a982d89SJeremy L. Thompson   @param[out] data        Variable to store data
2427a982d89SJeremy L. Thompson 
2437a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
2447a982d89SJeremy L. Thompson 
2457a982d89SJeremy L. Thompson   @ref Backend
2467a982d89SJeremy L. Thompson **/
2477a982d89SJeremy L. Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) {
2487a982d89SJeremy L. Thompson   *data = rstr->data;
2497a982d89SJeremy L. Thompson   return 0;
2507a982d89SJeremy L. Thompson }
2517a982d89SJeremy L. Thompson 
2527a982d89SJeremy L. Thompson /**
2537a982d89SJeremy L. Thompson   @brief Set the backend data of a CeedElemRestriction
2547a982d89SJeremy L. Thompson 
2557a982d89SJeremy L. Thompson   @param[out] rstr        CeedElemRestriction
2567a982d89SJeremy L. Thompson   @param data             Data to set
2577a982d89SJeremy L. Thompson 
2587a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
2597a982d89SJeremy L. Thompson 
2607a982d89SJeremy L. Thompson   @ref Backend
2617a982d89SJeremy L. Thompson **/
2627a982d89SJeremy L. Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) {
2637a982d89SJeremy L. Thompson   rstr->data = *data;
2647a982d89SJeremy L. Thompson   return 0;
2657a982d89SJeremy L. Thompson }
2667a982d89SJeremy L. Thompson 
2677a982d89SJeremy L. Thompson /// @}
2687a982d89SJeremy L. Thompson 
26915910d16Sjeremylt /// @cond DOXYGEN_SKIP
27015910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none;
27115910d16Sjeremylt /// @endcond
27215910d16Sjeremylt 
2737a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2747a982d89SJeremy L. Thompson /// CeedElemRestriction Public API
2757a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2767a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser
277d7b241e6Sjeremylt /// @{
278d7b241e6Sjeremylt 
2797a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend
2807a982d89SJeremy L. Thompson const CeedInt CEED_STRIDES_BACKEND[3] = {};
2817a982d89SJeremy L. Thompson 
2824cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user
2837a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE =
2847a982d89SJeremy L. Thompson   &ceed_elemrestriction_none;
2857a982d89SJeremy L. Thompson 
286d7b241e6Sjeremylt /**
287b11c1e72Sjeremylt   @brief Create a CeedElemRestriction
288d7b241e6Sjeremylt 
289b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
290d979a051Sjeremylt   @param nelem      Number of elements described in the @a offsets array
291b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
292b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
29395bb1877Svaleriabarra                       (1 for scalar fields)
294d979a051Sjeremylt   @param compstride Stride between components for the same L-vector "node".
295d979a051Sjeremylt                       Data for node i, component k can be found in the L-vector
296d979a051Sjeremylt                       at index [offsets[i] + k*compstride].
297d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
298d979a051Sjeremylt                       the elements and fields given by this restriction.
299d979a051Sjeremylt   @param mtype      Memory type of the @a offsets array, see CeedMemType
300d979a051Sjeremylt   @param cmode      Copy mode for the @a offsets array, see CeedCopyMode
301d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
302d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
3038795c945Sjeremylt                       for the unknowns corresponding to element i, where
304d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
305d979a051Sjeremylt                       [0, @a lsize - 1].
3064ce2993fSjeremylt   @param[out] rstr  Address of the variable where the newly created
307b11c1e72Sjeremylt                       CeedElemRestriction will be stored
308d7b241e6Sjeremylt 
309b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
310dfdf5a53Sjeremylt 
3117a982d89SJeremy L. Thompson   @ref User
312b11c1e72Sjeremylt **/
313d979a051Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem, CeedInt elemsize,
314d979a051Sjeremylt                               CeedInt ncomp, CeedInt compstride,
315d979a051Sjeremylt                               CeedInt lsize, CeedMemType mtype,
316d979a051Sjeremylt                               CeedCopyMode cmode, const CeedInt *offsets,
3174ce2993fSjeremylt                               CeedElemRestriction *rstr) {
318d7b241e6Sjeremylt   int ierr;
319d7b241e6Sjeremylt 
3205fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
3215fe0d4faSjeremylt     Ceed delegate;
322aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
323aefd8378Sjeremylt     CeedChk(ierr);
3245fe0d4faSjeremylt 
3255fe0d4faSjeremylt     if (!delegate)
326c042f62fSJeremy L Thompson       // LCOV_EXCL_START
327d7b241e6Sjeremylt       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
328c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3295fe0d4faSjeremylt 
330d979a051Sjeremylt     ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize, ncomp,
331d979a051Sjeremylt                                      compstride, lsize, mtype, cmode,
332d979a051Sjeremylt                                      offsets, rstr); CeedChk(ierr);
3335fe0d4faSjeremylt     return 0;
3345fe0d4faSjeremylt   }
3355fe0d4faSjeremylt 
3364ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
3374ce2993fSjeremylt   (*rstr)->ceed = ceed;
338d7b241e6Sjeremylt   ceed->refcount++;
3394ce2993fSjeremylt   (*rstr)->refcount = 1;
3404ce2993fSjeremylt   (*rstr)->nelem = nelem;
3414ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
3424ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
343d979a051Sjeremylt   (*rstr)->compstride = compstride;
344d979a051Sjeremylt   (*rstr)->lsize = lsize;
3454ce2993fSjeremylt   (*rstr)->nblk = nelem;
3464ce2993fSjeremylt   (*rstr)->blksize = 1;
347d979a051Sjeremylt   ierr = ceed->ElemRestrictionCreate(mtype, cmode, offsets, *rstr);
348d979a051Sjeremylt   CeedChk(ierr);
349d7b241e6Sjeremylt   return 0;
350d7b241e6Sjeremylt }
351d7b241e6Sjeremylt 
352d7b241e6Sjeremylt /**
3537509a596Sjeremylt   @brief Create a strided CeedElemRestriction
354d7b241e6Sjeremylt 
355b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
3567509a596Sjeremylt   @param nelem      Number of elements described by the restriction
357b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
358b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
35995bb1877Svaleriabarra                       (1 for scalar fields)
360d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
361d979a051Sjeremylt                       the elements and fields given by this restriction.
3627509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
3637509a596Sjeremylt                       The data for node i, component j, element k in the
3647509a596Sjeremylt                       L-vector is given by
3657509a596Sjeremylt                         i*strides[0] + j*strides[1] + k*strides[2]
3664ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
367b11c1e72Sjeremylt                       CeedElemRestriction will be stored
368d7b241e6Sjeremylt 
369b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
370dfdf5a53Sjeremylt 
3717a982d89SJeremy L. Thompson   @ref User
372b11c1e72Sjeremylt **/
3737509a596Sjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt nelem, CeedInt elemsize,
374d979a051Sjeremylt                                      CeedInt ncomp, CeedInt lsize,
3758621c6c6SJeremy L Thompson                                      const CeedInt strides[3],
376f90c8643Sjeremylt                                      CeedElemRestriction *rstr) {
377d7b241e6Sjeremylt   int ierr;
378d7b241e6Sjeremylt 
3795fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
3805fe0d4faSjeremylt     Ceed delegate;
381aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
382aefd8378Sjeremylt     CeedChk(ierr);
3835fe0d4faSjeremylt 
3845fe0d4faSjeremylt     if (!delegate)
385c042f62fSJeremy L Thompson       // LCOV_EXCL_START
3861d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
387c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3885fe0d4faSjeremylt 
389d979a051Sjeremylt     ierr = CeedElemRestrictionCreateStrided(delegate, nelem, elemsize, ncomp,
390d979a051Sjeremylt                                             lsize, strides, rstr);
391d979a051Sjeremylt     CeedChk(ierr);
3925fe0d4faSjeremylt     return 0;
3935fe0d4faSjeremylt   }
3945fe0d4faSjeremylt 
3954ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
3964ce2993fSjeremylt   (*rstr)->ceed = ceed;
397d7b241e6Sjeremylt   ceed->refcount++;
3984ce2993fSjeremylt   (*rstr)->refcount = 1;
3994ce2993fSjeremylt   (*rstr)->nelem = nelem;
4004ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
4014ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
402d979a051Sjeremylt   (*rstr)->lsize = lsize;
4034ce2993fSjeremylt   (*rstr)->nblk = nelem;
4044ce2993fSjeremylt   (*rstr)->blksize = 1;
4057509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
4067509a596Sjeremylt   for (int i = 0; i<3; i++)
4077509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
4081dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
4091dfeef1dSjeremylt                                      *rstr);
4104b8bea3bSJed Brown   CeedChk(ierr);
411d7b241e6Sjeremylt   return 0;
412d7b241e6Sjeremylt }
413d7b241e6Sjeremylt 
414d7b241e6Sjeremylt /**
415b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
416d7b241e6Sjeremylt 
417d7b241e6Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created.
418d979a051Sjeremylt   @param nelem      Number of elements described in the @a offsets array.
419b11c1e72Sjeremylt   @param elemsize   Size (number of unknowns) per element
420b11c1e72Sjeremylt   @param blksize    Number of elements in a block
42195bb1877Svaleriabarra   @param ncomp      Number of field components per interpolation node
42295bb1877Svaleriabarra                       (1 for scalar fields)
423d979a051Sjeremylt   @param compstride Stride between components for the same L-vector "node".
424d979a051Sjeremylt                       Data for node i, component k can be found in the L-vector
425d979a051Sjeremylt                       at index [offsets[i] + k*compstride].
426d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
427d979a051Sjeremylt                       the elements and fields given by this restriction.
428d979a051Sjeremylt   @param mtype      Memory type of the @a offsets array, see CeedMemType
429d979a051Sjeremylt   @param cmode      Copy mode for the @a offsets array, see CeedCopyMode
430d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
431d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
4328795c945Sjeremylt                       for the unknowns corresponding to element i, where
433d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
434d979a051Sjeremylt                       [0, @a lsize - 1]. The backend will permute and pad this
4358795c945Sjeremylt                       array to the desired ordering for the blocksize, which is
4368795c945Sjeremylt                       typically given by the backend. The default reordering is
4378795c945Sjeremylt                       to interlace elements.
4384ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
439b11c1e72Sjeremylt                       CeedElemRestriction will be stored
440d7b241e6Sjeremylt 
441b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
442dfdf5a53Sjeremylt 
4437a982d89SJeremy L. Thompson   @ref Backend
444b11c1e72Sjeremylt  **/
445d979a051Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize,
446d979a051Sjeremylt                                      CeedInt blksize, CeedInt ncomp,
447d979a051Sjeremylt                                      CeedInt compstride, CeedInt lsize,
448d979a051Sjeremylt                                      CeedMemType mtype, CeedCopyMode cmode,
449d979a051Sjeremylt                                      const CeedInt *offsets,
4504ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
451d7b241e6Sjeremylt   int ierr;
452d979a051Sjeremylt   CeedInt *blkoffsets;
453d7b241e6Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
454d7b241e6Sjeremylt 
4555fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
4565fe0d4faSjeremylt     Ceed delegate;
457aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
458aefd8378Sjeremylt     CeedChk(ierr);
4595fe0d4faSjeremylt 
4605fe0d4faSjeremylt     if (!delegate)
461c042f62fSJeremy L Thompson       // LCOV_EXCL_START
4621d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support "
4631d102b48SJeremy L Thompson                        "ElemRestrictionCreateBlocked");
464c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
4655fe0d4faSjeremylt 
466d979a051Sjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize, blksize,
467d979a051Sjeremylt                                             ncomp, compstride, lsize, mtype,
468d979a051Sjeremylt                                             cmode, offsets, rstr);
469d979a051Sjeremylt     CeedChk(ierr);
4705fe0d4faSjeremylt     return 0;
4715fe0d4faSjeremylt   }
472d7b241e6Sjeremylt 
4734ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
474d7b241e6Sjeremylt 
475d979a051Sjeremylt   ierr = CeedCalloc(nblk*blksize*elemsize, &blkoffsets); CeedChk(ierr);
476d979a051Sjeremylt   ierr = CeedPermutePadOffsets(offsets, blkoffsets, nblk, nelem, blksize,
4774b8bea3bSJed Brown                                elemsize);
478dfdf5a53Sjeremylt   CeedChk(ierr);
479d7b241e6Sjeremylt 
4804ce2993fSjeremylt   (*rstr)->ceed = ceed;
481d7b241e6Sjeremylt   ceed->refcount++;
4824ce2993fSjeremylt   (*rstr)->refcount = 1;
4834ce2993fSjeremylt   (*rstr)->nelem = nelem;
4844ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
4854ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
486d979a051Sjeremylt   (*rstr)->compstride = compstride;
487d979a051Sjeremylt   (*rstr)->lsize = lsize;
4884ce2993fSjeremylt   (*rstr)->nblk = nblk;
4894ce2993fSjeremylt   (*rstr)->blksize = blksize;
490667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
491d979a051Sjeremylt          (const CeedInt *) blkoffsets, *rstr); CeedChk(ierr);
492d7b241e6Sjeremylt 
4931d102b48SJeremy L Thompson   if (cmode == CEED_OWN_POINTER) {
494d979a051Sjeremylt     ierr = CeedFree(&offsets); CeedChk(ierr);
4951d102b48SJeremy L Thompson   }
496d7b241e6Sjeremylt 
497d7b241e6Sjeremylt   return 0;
498d7b241e6Sjeremylt }
499d7b241e6Sjeremylt 
500b11c1e72Sjeremylt /**
5017509a596Sjeremylt   @brief Create a blocked strided CeedElemRestriction
5027509a596Sjeremylt 
5037509a596Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
5047509a596Sjeremylt   @param nelem      Number of elements described by the restriction
5057509a596Sjeremylt   @param elemsize   Size (number of "nodes") per element
5067509a596Sjeremylt   @param blksize    Number of elements in a block
5077509a596Sjeremylt   @param ncomp      Number of field components per interpolation node
5087509a596Sjeremylt                       (1 for scalar fields)
509d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
510d979a051Sjeremylt                       the elements and fields given by this restriction.
5117509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
5127509a596Sjeremylt                       The data for node i, component j, element k in the
5137509a596Sjeremylt                       L-vector is given by
5147509a596Sjeremylt                         i*strides[0] + j*strides[1] + k*strides[2]
5157509a596Sjeremylt   @param rstr       Address of the variable where the newly created
5167509a596Sjeremylt                       CeedElemRestriction will be stored
5177509a596Sjeremylt 
5187509a596Sjeremylt   @return An error code: 0 - success, otherwise - failure
5197509a596Sjeremylt 
5207a982d89SJeremy L. Thompson   @ref User
5217509a596Sjeremylt **/
5227509a596Sjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt nelem,
523d979a051Sjeremylt     CeedInt elemsize, CeedInt blksize, CeedInt ncomp, CeedInt lsize,
5248621c6c6SJeremy L Thompson     const CeedInt strides[3], CeedElemRestriction *rstr) {
5257509a596Sjeremylt   int ierr;
5267509a596Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
5277509a596Sjeremylt 
5287509a596Sjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
5297509a596Sjeremylt     Ceed delegate;
5307509a596Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
5317509a596Sjeremylt     CeedChk(ierr);
5327509a596Sjeremylt 
5337509a596Sjeremylt     if (!delegate)
5347509a596Sjeremylt       // LCOV_EXCL_START
5357509a596Sjeremylt       return CeedError(ceed, 1, "Backend does not support "
5367509a596Sjeremylt                        "ElemRestrictionCreateBlocked");
5377509a596Sjeremylt     // LCOV_EXCL_STOP
5387509a596Sjeremylt 
5397509a596Sjeremylt     ierr = CeedElemRestrictionCreateBlockedStrided(delegate, nelem, elemsize,
540d979a051Sjeremylt            blksize, ncomp, lsize, strides, rstr);
5417509a596Sjeremylt     CeedChk(ierr);
5427509a596Sjeremylt     return 0;
5437509a596Sjeremylt   }
5447509a596Sjeremylt 
5457509a596Sjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
5467509a596Sjeremylt 
5477509a596Sjeremylt   (*rstr)->ceed = ceed;
5487509a596Sjeremylt   ceed->refcount++;
5497509a596Sjeremylt   (*rstr)->refcount = 1;
5507509a596Sjeremylt   (*rstr)->nelem = nelem;
5517509a596Sjeremylt   (*rstr)->elemsize = elemsize;
5527509a596Sjeremylt   (*rstr)->ncomp = ncomp;
553d979a051Sjeremylt   (*rstr)->lsize = lsize;
5547509a596Sjeremylt   (*rstr)->nblk = nblk;
5557509a596Sjeremylt   (*rstr)->blksize = blksize;
5567509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
5577509a596Sjeremylt   for (int i = 0; i<3; i++)
5587509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
5597509a596Sjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
5607509a596Sjeremylt          NULL, *rstr); CeedChk(ierr);
5617509a596Sjeremylt 
5627509a596Sjeremylt   return 0;
5637509a596Sjeremylt }
5647509a596Sjeremylt 
5657509a596Sjeremylt /**
566b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
567b11c1e72Sjeremylt 
5684ce2993fSjeremylt   @param rstr  CeedElemRestriction
569b11c1e72Sjeremylt   @param lvec  The address of the L-vector to be created, or NULL
570b11c1e72Sjeremylt   @param evec  The address of the E-vector to be created, or NULL
571b11c1e72Sjeremylt 
572b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
573dfdf5a53Sjeremylt 
5747a982d89SJeremy L. Thompson   @ref User
575b11c1e72Sjeremylt **/
5764ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec,
577d7b241e6Sjeremylt                                     CeedVector *evec) {
578d7b241e6Sjeremylt   int ierr;
579d7b241e6Sjeremylt   CeedInt n, m;
580d979a051Sjeremylt   m = rstr->lsize;
5814ce2993fSjeremylt   n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
582d7b241e6Sjeremylt   if (lvec) {
5834ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr);
584d7b241e6Sjeremylt   }
585d7b241e6Sjeremylt   if (evec) {
5864ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr);
587d7b241e6Sjeremylt   }
588d7b241e6Sjeremylt   return 0;
589d7b241e6Sjeremylt }
590d7b241e6Sjeremylt 
591d7b241e6Sjeremylt /**
592d9e1f99aSValeria Barra   @brief Restrict an L-vector to an E-vector or apply its transpose
593d7b241e6Sjeremylt 
5944ce2993fSjeremylt   @param rstr    CeedElemRestriction
595d7b241e6Sjeremylt   @param tmode   Apply restriction or transpose
5964cc79fe7SJed Brown   @param u       Input vector (of size @a lsize when tmode=@ref CEED_NOTRANSPOSE)
597a8d32208Sjeremylt   @param ru      Output vector (of shape [@a nelem * @a elemsize] when
5984cc79fe7SJed Brown                    tmode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
5997aaeacdcSjeremylt                    by the backend.
6004cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
601b11c1e72Sjeremylt 
602b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
603dfdf5a53Sjeremylt 
6047a982d89SJeremy L. Thompson   @ref User
605b11c1e72Sjeremylt **/
6064ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode,
607a8d32208Sjeremylt                              CeedVector u, CeedVector ru,
608a8d32208Sjeremylt                              CeedRequest *request) {
609d7b241e6Sjeremylt   CeedInt m,n;
610d7b241e6Sjeremylt   int ierr;
611d7b241e6Sjeremylt 
612d7b241e6Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
6134ce2993fSjeremylt     m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
614d979a051Sjeremylt     n = rstr->lsize;
615d7b241e6Sjeremylt   } else {
616d979a051Sjeremylt     m = rstr->lsize;
6174ce2993fSjeremylt     n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
618d7b241e6Sjeremylt   }
619d7b241e6Sjeremylt   if (n != u->length)
620c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6211d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
6221d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
623c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
624a8d32208Sjeremylt   if (m != ru->length)
625c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6261d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
627a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
628c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
629074cb416Sjeremylt   ierr = rstr->Apply(rstr, tmode, u, ru, request); CeedChk(ierr);
630d7b241e6Sjeremylt 
631d7b241e6Sjeremylt   return 0;
632d7b241e6Sjeremylt }
633d7b241e6Sjeremylt 
634d7b241e6Sjeremylt /**
635d9e1f99aSValeria Barra   @brief Restrict an L-vector to a block of an E-vector or apply its transpose
636be9261b7Sjeremylt 
637be9261b7Sjeremylt   @param rstr    CeedElemRestriction
6381f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
6391f37b403Sjeremylt                    elements [0 : blksize] and block=3 will handle elements
6401f37b403Sjeremylt                    [3*blksize : 4*blksize]
641be9261b7Sjeremylt   @param tmode   Apply restriction or transpose
6424cc79fe7SJed Brown   @param u       Input vector (of size @a lsize when tmode=@ref CEED_NOTRANSPOSE)
643a8d32208Sjeremylt   @param ru      Output vector (of shape [@a blksize * @a elemsize] when
6444cc79fe7SJed Brown                    tmode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
6457aaeacdcSjeremylt                    by the backend.
6464cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
647be9261b7Sjeremylt 
648be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
649be9261b7Sjeremylt 
6507a982d89SJeremy L. Thompson   @ref Backend
651be9261b7Sjeremylt **/
652be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
653a8d32208Sjeremylt                                   CeedTransposeMode tmode, CeedVector u,
654a8d32208Sjeremylt                                   CeedVector ru, CeedRequest *request) {
655be9261b7Sjeremylt   CeedInt m,n;
656be9261b7Sjeremylt   int ierr;
657be9261b7Sjeremylt 
658be9261b7Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
659be9261b7Sjeremylt     m = rstr->blksize * rstr->elemsize * rstr->ncomp;
660d979a051Sjeremylt     n = rstr->lsize;
661be9261b7Sjeremylt   } else {
662d979a051Sjeremylt     m = rstr->lsize;
663be9261b7Sjeremylt     n = rstr->blksize * rstr->elemsize * rstr->ncomp;
664be9261b7Sjeremylt   }
665be9261b7Sjeremylt   if (n != u->length)
666c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6671d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
6681d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
669c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
670a8d32208Sjeremylt   if (m != ru->length)
671c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6721d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
673a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
674c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
675be9261b7Sjeremylt   if (rstr->blksize*block > rstr->nelem)
676c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6771d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > "
6781d102b48SJeremy L Thompson                      "total elements %d", block, rstr->blksize*block,
6791d102b48SJeremy L Thompson                      rstr->nelem);
680c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
681074cb416Sjeremylt   ierr = rstr->ApplyBlock(rstr, block, tmode, u, ru, request);
682be9261b7Sjeremylt   CeedChk(ierr);
683be9261b7Sjeremylt 
684be9261b7Sjeremylt   return 0;
685be9261b7Sjeremylt }
686be9261b7Sjeremylt 
687be9261b7Sjeremylt /**
688d979a051Sjeremylt   @brief Get the L-vector component stride
689a681ae63Sjeremylt 
690a681ae63Sjeremylt   @param rstr             CeedElemRestriction
691d979a051Sjeremylt   @param[out] compstride  Variable to store component stride
692a681ae63Sjeremylt 
693a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
694a681ae63Sjeremylt 
695a681ae63Sjeremylt   @ref Backend
696a681ae63Sjeremylt **/
697d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr,
698d979a051Sjeremylt                                      CeedInt *compstride) {
699d979a051Sjeremylt   *compstride = rstr->compstride;
700a681ae63Sjeremylt   return 0;
701a681ae63Sjeremylt }
702a681ae63Sjeremylt 
703a681ae63Sjeremylt /**
704a681ae63Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
705a681ae63Sjeremylt 
706a681ae63Sjeremylt   @param rstr             CeedElemRestriction
707a681ae63Sjeremylt   @param[out] numelem     Variable to store number of elements
708a681ae63Sjeremylt 
709a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
710a681ae63Sjeremylt 
711a681ae63Sjeremylt   @ref Backend
712a681ae63Sjeremylt **/
713a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
714a681ae63Sjeremylt                                       CeedInt *numelem) {
715a681ae63Sjeremylt   *numelem = rstr->nelem;
716a681ae63Sjeremylt   return 0;
717a681ae63Sjeremylt }
718a681ae63Sjeremylt 
719a681ae63Sjeremylt /**
720a681ae63Sjeremylt   @brief Get the size of elements in the CeedElemRestriction
721a681ae63Sjeremylt 
722a681ae63Sjeremylt   @param rstr             CeedElemRestriction
723a681ae63Sjeremylt   @param[out] elemsize    Variable to store size of elements
724a681ae63Sjeremylt 
725a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
726a681ae63Sjeremylt 
727a681ae63Sjeremylt   @ref Backend
728a681ae63Sjeremylt **/
729a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
730a681ae63Sjeremylt                                       CeedInt *elemsize) {
731a681ae63Sjeremylt   *elemsize = rstr->elemsize;
732a681ae63Sjeremylt   return 0;
733a681ae63Sjeremylt }
734a681ae63Sjeremylt 
735a681ae63Sjeremylt /**
736d979a051Sjeremylt   @brief Get the size of the l-vector for a CeedElemRestriction
737a681ae63Sjeremylt 
738a681ae63Sjeremylt   @param rstr             CeedElemRestriction
739a681ae63Sjeremylt   @param[out] numnodes    Variable to store number of nodes
740a681ae63Sjeremylt 
741a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
742a681ae63Sjeremylt 
743a681ae63Sjeremylt   @ref Backend
744a681ae63Sjeremylt **/
745d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr,
746d979a051Sjeremylt                                       CeedInt *lsize) {
747d979a051Sjeremylt   *lsize = rstr->lsize;
748a681ae63Sjeremylt   return 0;
749a681ae63Sjeremylt }
750a681ae63Sjeremylt 
751a681ae63Sjeremylt /**
752a681ae63Sjeremylt   @brief Get the number of components in the elements of a
753a681ae63Sjeremylt          CeedElemRestriction
754a681ae63Sjeremylt 
755a681ae63Sjeremylt   @param rstr             CeedElemRestriction
756a681ae63Sjeremylt   @param[out] numcomp     Variable to store number of components
757a681ae63Sjeremylt 
758a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
759a681ae63Sjeremylt 
760a681ae63Sjeremylt   @ref Backend
761a681ae63Sjeremylt **/
762a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
763a681ae63Sjeremylt                                         CeedInt *numcomp) {
764a681ae63Sjeremylt   *numcomp = rstr->ncomp;
765a681ae63Sjeremylt   return 0;
766a681ae63Sjeremylt }
767a681ae63Sjeremylt 
768a681ae63Sjeremylt /**
769a681ae63Sjeremylt   @brief Get the number of blocks in a CeedElemRestriction
770a681ae63Sjeremylt 
771a681ae63Sjeremylt   @param rstr             CeedElemRestriction
772a681ae63Sjeremylt   @param[out] numblock    Variable to store number of blocks
773a681ae63Sjeremylt 
774a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
775a681ae63Sjeremylt 
776a681ae63Sjeremylt   @ref Backend
777a681ae63Sjeremylt **/
778a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
779a681ae63Sjeremylt                                     CeedInt *numblock) {
780a681ae63Sjeremylt   *numblock = rstr->nblk;
781a681ae63Sjeremylt   return 0;
782a681ae63Sjeremylt }
783a681ae63Sjeremylt 
784a681ae63Sjeremylt /**
785a681ae63Sjeremylt   @brief Get the size of blocks in the CeedElemRestriction
786a681ae63Sjeremylt 
787a681ae63Sjeremylt   @param rstr             CeedElemRestriction
788a681ae63Sjeremylt   @param[out] blksize     Variable to store size of blocks
789a681ae63Sjeremylt 
790a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
791a681ae63Sjeremylt 
792a681ae63Sjeremylt   @ref Backend
793a681ae63Sjeremylt **/
794a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
795a681ae63Sjeremylt                                     CeedInt *blksize) {
796a681ae63Sjeremylt   *blksize = rstr->blksize;
797a681ae63Sjeremylt   return 0;
798a681ae63Sjeremylt }
799a681ae63Sjeremylt 
800a681ae63Sjeremylt /**
801d9e1f99aSValeria Barra   @brief Get the multiplicity of nodes in a CeedElemRestriction
8021469ee4dSjeremylt 
8031469ee4dSjeremylt   @param rstr             CeedElemRestriction
804d979a051Sjeremylt   @param[out] mult        Vector to store multiplicity (of size lsize)
8051469ee4dSjeremylt 
8061469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
8071469ee4dSjeremylt 
8087a982d89SJeremy L. Thompson   @ref User
8091469ee4dSjeremylt **/
8101469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
8111469ee4dSjeremylt                                        CeedVector mult) {
8121469ee4dSjeremylt   int ierr;
8131469ee4dSjeremylt   CeedVector evec;
8141469ee4dSjeremylt 
8151469ee4dSjeremylt   // Create and set evec
8161469ee4dSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr);
8171469ee4dSjeremylt   ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr);
818fa9eac48SJed Brown   ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr);
8191469ee4dSjeremylt 
8201469ee4dSjeremylt   // Apply to get multiplicity
821a8d32208Sjeremylt   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult,
822efc78312Sjeremylt                                   CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
8231469ee4dSjeremylt 
8241469ee4dSjeremylt   // Cleanup
8251469ee4dSjeremylt   ierr = CeedVectorDestroy(&evec); CeedChk(ierr);
8261469ee4dSjeremylt 
8271469ee4dSjeremylt   return 0;
8281469ee4dSjeremylt }
8291469ee4dSjeremylt 
8301469ee4dSjeremylt /**
831f02ca4a2SJed Brown   @brief View a CeedElemRestriction
832f02ca4a2SJed Brown 
833f02ca4a2SJed Brown   @param[in] rstr    CeedElemRestriction to view
834f02ca4a2SJed Brown   @param[in] stream  Stream to write; typically stdout/stderr or a file
835f02ca4a2SJed Brown 
836f02ca4a2SJed Brown   @return Error code: 0 - success, otherwise - failure
837f02ca4a2SJed Brown 
8387a982d89SJeremy L. Thompson   @ref User
839f02ca4a2SJed Brown **/
840f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
8417509a596Sjeremylt   char stridesstr[500];
8427509a596Sjeremylt   if (rstr->strides)
8437509a596Sjeremylt     sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1],
8447509a596Sjeremylt             rstr->strides[2]);
845d979a051Sjeremylt   else
846d979a051Sjeremylt     sprintf(stridesstr, "%d", rstr->compstride);
8477509a596Sjeremylt 
8480036de2cSjeremylt   fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d "
8490036de2cSjeremylt           "nodes each and %s %s\n", rstr->blksize > 1 ? "Blocked " : "",
850d979a051Sjeremylt           rstr->lsize, rstr->ncomp, rstr->nelem, rstr->elemsize,
851d979a051Sjeremylt           rstr->strides ? "strides" : "component stride", stridesstr);
852f02ca4a2SJed Brown   return 0;
853f02ca4a2SJed Brown }
854f02ca4a2SJed Brown 
855f02ca4a2SJed Brown /**
856b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
857b11c1e72Sjeremylt 
8584ce2993fSjeremylt   @param rstr  CeedElemRestriction to destroy
859b11c1e72Sjeremylt 
860b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
861dfdf5a53Sjeremylt 
8627a982d89SJeremy L. Thompson   @ref User
863b11c1e72Sjeremylt **/
8644ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
865d7b241e6Sjeremylt   int ierr;
866d7b241e6Sjeremylt 
8671d102b48SJeremy L Thompson   if (!*rstr || --(*rstr)->refcount > 0)
8681d102b48SJeremy L Thompson     return 0;
869430758c8SJeremy L Thompson   if ((*rstr)->numreaders)
870430758c8SJeremy L Thompson     return CeedError((*rstr)->ceed, 1, "Cannot destroy CeedElemRestriction, "
871430758c8SJeremy L Thompson                      "a process has read access to the offset data");
8724ce2993fSjeremylt   if ((*rstr)->Destroy) {
8734ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
874d7b241e6Sjeremylt   }
8757509a596Sjeremylt   ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr);
8764ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
8774ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
878d7b241e6Sjeremylt   return 0;
879d7b241e6Sjeremylt }
880d7b241e6Sjeremylt 
881d7b241e6Sjeremylt /// @}
882