xref: /libCEED/interface/ceed-elemrestriction.c (revision 2db7ab32b27a7c139da2037b4563a3addb30b1ca)
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 /**
18949fd234cSJeremy L Thompson 
19049fd234cSJeremy L Thompson   @brief Get the E-vector layout of a CeedElemRestriction
19149fd234cSJeremy L Thompson 
19249fd234cSJeremy L Thompson   @param rstr             CeedElemRestriction
19349fd234cSJeremy L Thompson   @param[out] layout      Variable to store layout array,
19449fd234cSJeremy L Thompson                             stored as [nodes, components, elements].
19549fd234cSJeremy L Thompson                             The data for node i, component j, element k in the
19649fd234cSJeremy L Thompson                             E-vector is given by
19795e93d34SJeremy L Thompson                             i*layout[0] + j*layout[1] + k*layout[2]
19849fd234cSJeremy L Thompson 
19949fd234cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
20049fd234cSJeremy L Thompson 
20149fd234cSJeremy L Thompson   @ref Backend
20249fd234cSJeremy L Thompson **/
20349fd234cSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr,
20449fd234cSJeremy L Thompson                                   CeedInt (*layout)[3]) {
20549fd234cSJeremy L Thompson   if (!rstr->layout[0])
20649fd234cSJeremy L Thompson     // LCOV_EXCL_START
20749fd234cSJeremy L Thompson     return CeedError(rstr->ceed, 1, "ElemRestriction has no layout data");
20849fd234cSJeremy L Thompson   // LCOV_EXCL_STOP
20949fd234cSJeremy L Thompson 
21049fd234cSJeremy L Thompson   for (int i = 0; i<3; i++)
21149fd234cSJeremy L Thompson     (*layout)[i] = rstr->layout[i];
21249fd234cSJeremy L Thompson   return 0;
21349fd234cSJeremy L Thompson }
21449fd234cSJeremy L Thompson 
21549fd234cSJeremy L Thompson /**
21649fd234cSJeremy L Thompson 
21749fd234cSJeremy L Thompson   @brief Set the E-vector layout of a CeedElemRestriction
21849fd234cSJeremy L Thompson 
21949fd234cSJeremy L Thompson   @param rstr             CeedElemRestriction
22049fd234cSJeremy L Thompson   @param layout           Variable to containing layout array,
22149fd234cSJeremy L Thompson                             stored as [nodes, components, elements].
22249fd234cSJeremy L Thompson                             The data for node i, component j, element k in the
22349fd234cSJeremy L Thompson                             E-vector is given by
22495e93d34SJeremy L Thompson                             i*layout[0] + j*layout[1] + k*layout[2]
22549fd234cSJeremy L Thompson 
22649fd234cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
22749fd234cSJeremy L Thompson 
22849fd234cSJeremy L Thompson   @ref Backend
22949fd234cSJeremy L Thompson **/
23049fd234cSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr,
23149fd234cSJeremy L Thompson                                   CeedInt layout[3]) {
23249fd234cSJeremy L Thompson   for (int i = 0; i<3; i++)
23349fd234cSJeremy L Thompson     rstr->layout[i] = layout[i];
23449fd234cSJeremy L Thompson   return 0;
23549fd234cSJeremy L Thompson }
23649fd234cSJeremy L Thompson 
23749fd234cSJeremy 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".
29595e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
29695e93d34SJeremy L Thompson                       the L-vector at index
297*2db7ab32SJeremy L Thompson                         offsets[i + k*elemsize] + j*compstride.
298d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
299d979a051Sjeremylt                       the elements and fields given by this restriction.
300d979a051Sjeremylt   @param mtype      Memory type of the @a offsets array, see CeedMemType
301d979a051Sjeremylt   @param cmode      Copy mode for the @a offsets array, see CeedCopyMode
302d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
303d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
3048795c945Sjeremylt                       for the unknowns corresponding to element i, where
305d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
306d979a051Sjeremylt                       [0, @a lsize - 1].
3074ce2993fSjeremylt   @param[out] rstr  Address of the variable where the newly created
308b11c1e72Sjeremylt                       CeedElemRestriction will be stored
309d7b241e6Sjeremylt 
310b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
311dfdf5a53Sjeremylt 
3127a982d89SJeremy L. Thompson   @ref User
313b11c1e72Sjeremylt **/
314d979a051Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem, CeedInt elemsize,
315d979a051Sjeremylt                               CeedInt ncomp, CeedInt compstride,
316d979a051Sjeremylt                               CeedInt lsize, CeedMemType mtype,
317d979a051Sjeremylt                               CeedCopyMode cmode, const CeedInt *offsets,
3184ce2993fSjeremylt                               CeedElemRestriction *rstr) {
319d7b241e6Sjeremylt   int ierr;
320d7b241e6Sjeremylt 
3215fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
3225fe0d4faSjeremylt     Ceed delegate;
323aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
324aefd8378Sjeremylt     CeedChk(ierr);
3255fe0d4faSjeremylt 
3265fe0d4faSjeremylt     if (!delegate)
327c042f62fSJeremy L Thompson       // LCOV_EXCL_START
328d7b241e6Sjeremylt       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
329c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3305fe0d4faSjeremylt 
331d979a051Sjeremylt     ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize, ncomp,
332d979a051Sjeremylt                                      compstride, lsize, mtype, cmode,
333d979a051Sjeremylt                                      offsets, rstr); CeedChk(ierr);
3345fe0d4faSjeremylt     return 0;
3355fe0d4faSjeremylt   }
3365fe0d4faSjeremylt 
3374ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
3384ce2993fSjeremylt   (*rstr)->ceed = ceed;
339d7b241e6Sjeremylt   ceed->refcount++;
3404ce2993fSjeremylt   (*rstr)->refcount = 1;
3414ce2993fSjeremylt   (*rstr)->nelem = nelem;
3424ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
3434ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
344d979a051Sjeremylt   (*rstr)->compstride = compstride;
345d979a051Sjeremylt   (*rstr)->lsize = lsize;
3464ce2993fSjeremylt   (*rstr)->nblk = nelem;
3474ce2993fSjeremylt   (*rstr)->blksize = 1;
348d979a051Sjeremylt   ierr = ceed->ElemRestrictionCreate(mtype, cmode, offsets, *rstr);
349d979a051Sjeremylt   CeedChk(ierr);
350d7b241e6Sjeremylt   return 0;
351d7b241e6Sjeremylt }
352d7b241e6Sjeremylt 
353d7b241e6Sjeremylt /**
3547509a596Sjeremylt   @brief Create a strided CeedElemRestriction
355d7b241e6Sjeremylt 
356b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
3577509a596Sjeremylt   @param nelem      Number of elements described by the restriction
358b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
35995e93d34SJeremy L Thompson   @param ncomp      Number of field components per interpolation "node"
36095bb1877Svaleriabarra                       (1 for scalar fields)
361d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
362d979a051Sjeremylt                       the elements and fields given by this restriction.
3637509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
36495e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
36595e93d34SJeremy L Thompson                       the L-vector at index
36695e93d34SJeremy L Thompson                         i*strides[0] + j*strides[1] + k*strides[2].
36795e93d34SJeremy L Thompson                       @a CEED_STRIDES_BACKEND may be used with vectors created
36895e93d34SJeremy L Thompson                       by a Ceed backend.
3694ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
370b11c1e72Sjeremylt                       CeedElemRestriction will be stored
371d7b241e6Sjeremylt 
372b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
373dfdf5a53Sjeremylt 
3747a982d89SJeremy L. Thompson   @ref User
375b11c1e72Sjeremylt **/
3767509a596Sjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt nelem, CeedInt elemsize,
377d979a051Sjeremylt                                      CeedInt ncomp, CeedInt lsize,
3788621c6c6SJeremy L Thompson                                      const CeedInt strides[3],
379f90c8643Sjeremylt                                      CeedElemRestriction *rstr) {
380d7b241e6Sjeremylt   int ierr;
381d7b241e6Sjeremylt 
3825fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
3835fe0d4faSjeremylt     Ceed delegate;
384aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
385aefd8378Sjeremylt     CeedChk(ierr);
3865fe0d4faSjeremylt 
3875fe0d4faSjeremylt     if (!delegate)
388c042f62fSJeremy L Thompson       // LCOV_EXCL_START
3891d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
390c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3915fe0d4faSjeremylt 
392d979a051Sjeremylt     ierr = CeedElemRestrictionCreateStrided(delegate, nelem, elemsize, ncomp,
393d979a051Sjeremylt                                             lsize, strides, rstr);
394d979a051Sjeremylt     CeedChk(ierr);
3955fe0d4faSjeremylt     return 0;
3965fe0d4faSjeremylt   }
3975fe0d4faSjeremylt 
3984ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
3994ce2993fSjeremylt   (*rstr)->ceed = ceed;
400d7b241e6Sjeremylt   ceed->refcount++;
4014ce2993fSjeremylt   (*rstr)->refcount = 1;
4024ce2993fSjeremylt   (*rstr)->nelem = nelem;
4034ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
4044ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
405d979a051Sjeremylt   (*rstr)->lsize = lsize;
4064ce2993fSjeremylt   (*rstr)->nblk = nelem;
4074ce2993fSjeremylt   (*rstr)->blksize = 1;
4087509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
4097509a596Sjeremylt   for (int i = 0; i<3; i++)
4107509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
4111dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
4121dfeef1dSjeremylt                                      *rstr);
4134b8bea3bSJed Brown   CeedChk(ierr);
414d7b241e6Sjeremylt   return 0;
415d7b241e6Sjeremylt }
416d7b241e6Sjeremylt 
417d7b241e6Sjeremylt /**
418b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
419d7b241e6Sjeremylt 
420d7b241e6Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created.
421d979a051Sjeremylt   @param nelem      Number of elements described in the @a offsets array.
422b11c1e72Sjeremylt   @param elemsize   Size (number of unknowns) per element
423b11c1e72Sjeremylt   @param blksize    Number of elements in a block
42495bb1877Svaleriabarra   @param ncomp      Number of field components per interpolation node
42595bb1877Svaleriabarra                       (1 for scalar fields)
426d979a051Sjeremylt   @param compstride Stride between components for the same L-vector "node".
42795e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
42895e93d34SJeremy L Thompson                       the L-vector at index
429*2db7ab32SJeremy L Thompson                         offsets[i + k*elemsize] + j*compstride.
430d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
431d979a051Sjeremylt                       the elements and fields given by this restriction.
432d979a051Sjeremylt   @param mtype      Memory type of the @a offsets array, see CeedMemType
433d979a051Sjeremylt   @param cmode      Copy mode for the @a offsets array, see CeedCopyMode
434d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
435d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
4368795c945Sjeremylt                       for the unknowns corresponding to element i, where
437d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
438d979a051Sjeremylt                       [0, @a lsize - 1]. The backend will permute and pad this
4398795c945Sjeremylt                       array to the desired ordering for the blocksize, which is
4408795c945Sjeremylt                       typically given by the backend. The default reordering is
4418795c945Sjeremylt                       to interlace elements.
4424ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
443b11c1e72Sjeremylt                       CeedElemRestriction will be stored
444d7b241e6Sjeremylt 
445b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
446dfdf5a53Sjeremylt 
4477a982d89SJeremy L. Thompson   @ref Backend
448b11c1e72Sjeremylt  **/
449d979a051Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize,
450d979a051Sjeremylt                                      CeedInt blksize, CeedInt ncomp,
451d979a051Sjeremylt                                      CeedInt compstride, CeedInt lsize,
452d979a051Sjeremylt                                      CeedMemType mtype, CeedCopyMode cmode,
453d979a051Sjeremylt                                      const CeedInt *offsets,
4544ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
455d7b241e6Sjeremylt   int ierr;
456d979a051Sjeremylt   CeedInt *blkoffsets;
457d7b241e6Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
458d7b241e6Sjeremylt 
4595fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
4605fe0d4faSjeremylt     Ceed delegate;
461aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
462aefd8378Sjeremylt     CeedChk(ierr);
4635fe0d4faSjeremylt 
4645fe0d4faSjeremylt     if (!delegate)
465c042f62fSJeremy L Thompson       // LCOV_EXCL_START
4661d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support "
4671d102b48SJeremy L Thompson                        "ElemRestrictionCreateBlocked");
468c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
4695fe0d4faSjeremylt 
470d979a051Sjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize, blksize,
471d979a051Sjeremylt                                             ncomp, compstride, lsize, mtype,
472d979a051Sjeremylt                                             cmode, offsets, rstr);
473d979a051Sjeremylt     CeedChk(ierr);
4745fe0d4faSjeremylt     return 0;
4755fe0d4faSjeremylt   }
476d7b241e6Sjeremylt 
4774ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
478d7b241e6Sjeremylt 
479d979a051Sjeremylt   ierr = CeedCalloc(nblk*blksize*elemsize, &blkoffsets); CeedChk(ierr);
480d979a051Sjeremylt   ierr = CeedPermutePadOffsets(offsets, blkoffsets, nblk, nelem, blksize,
4814b8bea3bSJed Brown                                elemsize);
482dfdf5a53Sjeremylt   CeedChk(ierr);
483d7b241e6Sjeremylt 
4844ce2993fSjeremylt   (*rstr)->ceed = ceed;
485d7b241e6Sjeremylt   ceed->refcount++;
4864ce2993fSjeremylt   (*rstr)->refcount = 1;
4874ce2993fSjeremylt   (*rstr)->nelem = nelem;
4884ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
4894ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
490d979a051Sjeremylt   (*rstr)->compstride = compstride;
491d979a051Sjeremylt   (*rstr)->lsize = lsize;
4924ce2993fSjeremylt   (*rstr)->nblk = nblk;
4934ce2993fSjeremylt   (*rstr)->blksize = blksize;
494667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
495d979a051Sjeremylt          (const CeedInt *) blkoffsets, *rstr); CeedChk(ierr);
496d7b241e6Sjeremylt 
4971d102b48SJeremy L Thompson   if (cmode == CEED_OWN_POINTER) {
498d979a051Sjeremylt     ierr = CeedFree(&offsets); CeedChk(ierr);
4991d102b48SJeremy L Thompson   }
500d7b241e6Sjeremylt 
501d7b241e6Sjeremylt   return 0;
502d7b241e6Sjeremylt }
503d7b241e6Sjeremylt 
504b11c1e72Sjeremylt /**
5057509a596Sjeremylt   @brief Create a blocked strided CeedElemRestriction
5067509a596Sjeremylt 
5077509a596Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
5087509a596Sjeremylt   @param nelem      Number of elements described by the restriction
5097509a596Sjeremylt   @param elemsize   Size (number of "nodes") per element
5107509a596Sjeremylt   @param blksize    Number of elements in a block
5117509a596Sjeremylt   @param ncomp      Number of field components per interpolation node
5127509a596Sjeremylt                       (1 for scalar fields)
513d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
514d979a051Sjeremylt                       the elements and fields given by this restriction.
5157509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
51695e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
51795e93d34SJeremy L Thompson                       the L-vector at index
51895e93d34SJeremy L Thompson                         i*strides[0] + j*strides[1] + k*strides[2].
51995e93d34SJeremy L Thompson                       @a CEED_STRIDES_BACKEND may be used with vectors created
52095e93d34SJeremy L Thompson                       by a Ceed backend.
5217509a596Sjeremylt   @param rstr       Address of the variable where the newly created
5227509a596Sjeremylt                       CeedElemRestriction will be stored
5237509a596Sjeremylt 
5247509a596Sjeremylt   @return An error code: 0 - success, otherwise - failure
5257509a596Sjeremylt 
5267a982d89SJeremy L. Thompson   @ref User
5277509a596Sjeremylt **/
5287509a596Sjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt nelem,
529d979a051Sjeremylt     CeedInt elemsize, CeedInt blksize, CeedInt ncomp, CeedInt lsize,
5308621c6c6SJeremy L Thompson     const CeedInt strides[3], CeedElemRestriction *rstr) {
5317509a596Sjeremylt   int ierr;
5327509a596Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
5337509a596Sjeremylt 
5347509a596Sjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
5357509a596Sjeremylt     Ceed delegate;
5367509a596Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
5377509a596Sjeremylt     CeedChk(ierr);
5387509a596Sjeremylt 
5397509a596Sjeremylt     if (!delegate)
5407509a596Sjeremylt       // LCOV_EXCL_START
5417509a596Sjeremylt       return CeedError(ceed, 1, "Backend does not support "
5427509a596Sjeremylt                        "ElemRestrictionCreateBlocked");
5437509a596Sjeremylt     // LCOV_EXCL_STOP
5447509a596Sjeremylt 
5457509a596Sjeremylt     ierr = CeedElemRestrictionCreateBlockedStrided(delegate, nelem, elemsize,
546d979a051Sjeremylt            blksize, ncomp, lsize, strides, rstr);
5477509a596Sjeremylt     CeedChk(ierr);
5487509a596Sjeremylt     return 0;
5497509a596Sjeremylt   }
5507509a596Sjeremylt 
5517509a596Sjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
5527509a596Sjeremylt 
5537509a596Sjeremylt   (*rstr)->ceed = ceed;
5547509a596Sjeremylt   ceed->refcount++;
5557509a596Sjeremylt   (*rstr)->refcount = 1;
5567509a596Sjeremylt   (*rstr)->nelem = nelem;
5577509a596Sjeremylt   (*rstr)->elemsize = elemsize;
5587509a596Sjeremylt   (*rstr)->ncomp = ncomp;
559d979a051Sjeremylt   (*rstr)->lsize = lsize;
5607509a596Sjeremylt   (*rstr)->nblk = nblk;
5617509a596Sjeremylt   (*rstr)->blksize = blksize;
5627509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
5637509a596Sjeremylt   for (int i = 0; i<3; i++)
5647509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
5657509a596Sjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
5667509a596Sjeremylt          NULL, *rstr); CeedChk(ierr);
5677509a596Sjeremylt 
5687509a596Sjeremylt   return 0;
5697509a596Sjeremylt }
5707509a596Sjeremylt 
5717509a596Sjeremylt /**
572b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
573b11c1e72Sjeremylt 
5744ce2993fSjeremylt   @param rstr  CeedElemRestriction
575b11c1e72Sjeremylt   @param lvec  The address of the L-vector to be created, or NULL
576b11c1e72Sjeremylt   @param evec  The address of the E-vector to be created, or NULL
577b11c1e72Sjeremylt 
578b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
579dfdf5a53Sjeremylt 
5807a982d89SJeremy L. Thompson   @ref User
581b11c1e72Sjeremylt **/
5824ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec,
583d7b241e6Sjeremylt                                     CeedVector *evec) {
584d7b241e6Sjeremylt   int ierr;
585d7b241e6Sjeremylt   CeedInt n, m;
586d979a051Sjeremylt   m = rstr->lsize;
5874ce2993fSjeremylt   n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
588d7b241e6Sjeremylt   if (lvec) {
5894ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr);
590d7b241e6Sjeremylt   }
591d7b241e6Sjeremylt   if (evec) {
5924ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr);
593d7b241e6Sjeremylt   }
594d7b241e6Sjeremylt   return 0;
595d7b241e6Sjeremylt }
596d7b241e6Sjeremylt 
597d7b241e6Sjeremylt /**
598d9e1f99aSValeria Barra   @brief Restrict an L-vector to an E-vector or apply its transpose
599d7b241e6Sjeremylt 
6004ce2993fSjeremylt   @param rstr    CeedElemRestriction
601d7b241e6Sjeremylt   @param tmode   Apply restriction or transpose
6024cc79fe7SJed Brown   @param u       Input vector (of size @a lsize when tmode=@ref CEED_NOTRANSPOSE)
603a8d32208Sjeremylt   @param ru      Output vector (of shape [@a nelem * @a elemsize] when
6044cc79fe7SJed Brown                    tmode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
6057aaeacdcSjeremylt                    by the backend.
6064cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
607b11c1e72Sjeremylt 
608b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
609dfdf5a53Sjeremylt 
6107a982d89SJeremy L. Thompson   @ref User
611b11c1e72Sjeremylt **/
6124ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode,
613a8d32208Sjeremylt                              CeedVector u, CeedVector ru,
614a8d32208Sjeremylt                              CeedRequest *request) {
615d7b241e6Sjeremylt   CeedInt m,n;
616d7b241e6Sjeremylt   int ierr;
617d7b241e6Sjeremylt 
618d7b241e6Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
6194ce2993fSjeremylt     m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
620d979a051Sjeremylt     n = rstr->lsize;
621d7b241e6Sjeremylt   } else {
622d979a051Sjeremylt     m = rstr->lsize;
6234ce2993fSjeremylt     n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
624d7b241e6Sjeremylt   }
625d7b241e6Sjeremylt   if (n != u->length)
626c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6271d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
6281d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
629c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
630a8d32208Sjeremylt   if (m != ru->length)
631c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6321d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
633a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
634c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
635074cb416Sjeremylt   ierr = rstr->Apply(rstr, tmode, u, ru, request); CeedChk(ierr);
636d7b241e6Sjeremylt 
637d7b241e6Sjeremylt   return 0;
638d7b241e6Sjeremylt }
639d7b241e6Sjeremylt 
640d7b241e6Sjeremylt /**
641d9e1f99aSValeria Barra   @brief Restrict an L-vector to a block of an E-vector or apply its transpose
642be9261b7Sjeremylt 
643be9261b7Sjeremylt   @param rstr    CeedElemRestriction
6441f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
6451f37b403Sjeremylt                    elements [0 : blksize] and block=3 will handle elements
6461f37b403Sjeremylt                    [3*blksize : 4*blksize]
647be9261b7Sjeremylt   @param tmode   Apply restriction or transpose
6484cc79fe7SJed Brown   @param u       Input vector (of size @a lsize when tmode=@ref CEED_NOTRANSPOSE)
649a8d32208Sjeremylt   @param ru      Output vector (of shape [@a blksize * @a elemsize] when
6504cc79fe7SJed Brown                    tmode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
6517aaeacdcSjeremylt                    by the backend.
6524cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
653be9261b7Sjeremylt 
654be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
655be9261b7Sjeremylt 
6567a982d89SJeremy L. Thompson   @ref Backend
657be9261b7Sjeremylt **/
658be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
659a8d32208Sjeremylt                                   CeedTransposeMode tmode, CeedVector u,
660a8d32208Sjeremylt                                   CeedVector ru, CeedRequest *request) {
661be9261b7Sjeremylt   CeedInt m,n;
662be9261b7Sjeremylt   int ierr;
663be9261b7Sjeremylt 
664be9261b7Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
665be9261b7Sjeremylt     m = rstr->blksize * rstr->elemsize * rstr->ncomp;
666d979a051Sjeremylt     n = rstr->lsize;
667be9261b7Sjeremylt   } else {
668d979a051Sjeremylt     m = rstr->lsize;
669be9261b7Sjeremylt     n = rstr->blksize * rstr->elemsize * rstr->ncomp;
670be9261b7Sjeremylt   }
671be9261b7Sjeremylt   if (n != u->length)
672c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6731d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
6741d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
675c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
676a8d32208Sjeremylt   if (m != ru->length)
677c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6781d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
679a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
680c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
681be9261b7Sjeremylt   if (rstr->blksize*block > rstr->nelem)
682c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6831d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > "
6841d102b48SJeremy L Thompson                      "total elements %d", block, rstr->blksize*block,
6851d102b48SJeremy L Thompson                      rstr->nelem);
686c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
687074cb416Sjeremylt   ierr = rstr->ApplyBlock(rstr, block, tmode, u, ru, request);
688be9261b7Sjeremylt   CeedChk(ierr);
689be9261b7Sjeremylt 
690be9261b7Sjeremylt   return 0;
691be9261b7Sjeremylt }
692be9261b7Sjeremylt 
693be9261b7Sjeremylt /**
694d979a051Sjeremylt   @brief Get the L-vector component stride
695a681ae63Sjeremylt 
696a681ae63Sjeremylt   @param rstr             CeedElemRestriction
697d979a051Sjeremylt   @param[out] compstride  Variable to store component stride
698a681ae63Sjeremylt 
699a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
700a681ae63Sjeremylt 
701a681ae63Sjeremylt   @ref Backend
702a681ae63Sjeremylt **/
703d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr,
704d979a051Sjeremylt                                      CeedInt *compstride) {
705d979a051Sjeremylt   *compstride = rstr->compstride;
706a681ae63Sjeremylt   return 0;
707a681ae63Sjeremylt }
708a681ae63Sjeremylt 
709a681ae63Sjeremylt /**
710a681ae63Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
711a681ae63Sjeremylt 
712a681ae63Sjeremylt   @param rstr             CeedElemRestriction
713a681ae63Sjeremylt   @param[out] numelem     Variable to store number of elements
714a681ae63Sjeremylt 
715a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
716a681ae63Sjeremylt 
717a681ae63Sjeremylt   @ref Backend
718a681ae63Sjeremylt **/
719a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
720a681ae63Sjeremylt                                       CeedInt *numelem) {
721a681ae63Sjeremylt   *numelem = rstr->nelem;
722a681ae63Sjeremylt   return 0;
723a681ae63Sjeremylt }
724a681ae63Sjeremylt 
725a681ae63Sjeremylt /**
726a681ae63Sjeremylt   @brief Get the size of elements in the CeedElemRestriction
727a681ae63Sjeremylt 
728a681ae63Sjeremylt   @param rstr             CeedElemRestriction
729a681ae63Sjeremylt   @param[out] elemsize    Variable to store size of elements
730a681ae63Sjeremylt 
731a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
732a681ae63Sjeremylt 
733a681ae63Sjeremylt   @ref Backend
734a681ae63Sjeremylt **/
735a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
736a681ae63Sjeremylt                                       CeedInt *elemsize) {
737a681ae63Sjeremylt   *elemsize = rstr->elemsize;
738a681ae63Sjeremylt   return 0;
739a681ae63Sjeremylt }
740a681ae63Sjeremylt 
741a681ae63Sjeremylt /**
742d979a051Sjeremylt   @brief Get the size of the l-vector for a CeedElemRestriction
743a681ae63Sjeremylt 
744a681ae63Sjeremylt   @param rstr             CeedElemRestriction
745a681ae63Sjeremylt   @param[out] numnodes    Variable to store number of nodes
746a681ae63Sjeremylt 
747a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
748a681ae63Sjeremylt 
749a681ae63Sjeremylt   @ref Backend
750a681ae63Sjeremylt **/
751d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr,
752d979a051Sjeremylt                                       CeedInt *lsize) {
753d979a051Sjeremylt   *lsize = rstr->lsize;
754a681ae63Sjeremylt   return 0;
755a681ae63Sjeremylt }
756a681ae63Sjeremylt 
757a681ae63Sjeremylt /**
758a681ae63Sjeremylt   @brief Get the number of components in the elements of a
759a681ae63Sjeremylt          CeedElemRestriction
760a681ae63Sjeremylt 
761a681ae63Sjeremylt   @param rstr             CeedElemRestriction
762a681ae63Sjeremylt   @param[out] numcomp     Variable to store number of components
763a681ae63Sjeremylt 
764a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
765a681ae63Sjeremylt 
766a681ae63Sjeremylt   @ref Backend
767a681ae63Sjeremylt **/
768a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
769a681ae63Sjeremylt                                         CeedInt *numcomp) {
770a681ae63Sjeremylt   *numcomp = rstr->ncomp;
771a681ae63Sjeremylt   return 0;
772a681ae63Sjeremylt }
773a681ae63Sjeremylt 
774a681ae63Sjeremylt /**
775a681ae63Sjeremylt   @brief Get the number of blocks in a CeedElemRestriction
776a681ae63Sjeremylt 
777a681ae63Sjeremylt   @param rstr             CeedElemRestriction
778a681ae63Sjeremylt   @param[out] numblock    Variable to store number of blocks
779a681ae63Sjeremylt 
780a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
781a681ae63Sjeremylt 
782a681ae63Sjeremylt   @ref Backend
783a681ae63Sjeremylt **/
784a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
785a681ae63Sjeremylt                                     CeedInt *numblock) {
786a681ae63Sjeremylt   *numblock = rstr->nblk;
787a681ae63Sjeremylt   return 0;
788a681ae63Sjeremylt }
789a681ae63Sjeremylt 
790a681ae63Sjeremylt /**
791a681ae63Sjeremylt   @brief Get the size of blocks in the CeedElemRestriction
792a681ae63Sjeremylt 
793a681ae63Sjeremylt   @param rstr             CeedElemRestriction
794a681ae63Sjeremylt   @param[out] blksize     Variable to store size of blocks
795a681ae63Sjeremylt 
796a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
797a681ae63Sjeremylt 
798a681ae63Sjeremylt   @ref Backend
799a681ae63Sjeremylt **/
800a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
801a681ae63Sjeremylt                                     CeedInt *blksize) {
802a681ae63Sjeremylt   *blksize = rstr->blksize;
803a681ae63Sjeremylt   return 0;
804a681ae63Sjeremylt }
805a681ae63Sjeremylt 
806a681ae63Sjeremylt /**
807d9e1f99aSValeria Barra   @brief Get the multiplicity of nodes in a CeedElemRestriction
8081469ee4dSjeremylt 
8091469ee4dSjeremylt   @param rstr             CeedElemRestriction
810d979a051Sjeremylt   @param[out] mult        Vector to store multiplicity (of size lsize)
8111469ee4dSjeremylt 
8121469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
8131469ee4dSjeremylt 
8147a982d89SJeremy L. Thompson   @ref User
8151469ee4dSjeremylt **/
8161469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
8171469ee4dSjeremylt                                        CeedVector mult) {
8181469ee4dSjeremylt   int ierr;
8191469ee4dSjeremylt   CeedVector evec;
8201469ee4dSjeremylt 
8211469ee4dSjeremylt   // Create and set evec
8221469ee4dSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr);
8231469ee4dSjeremylt   ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr);
824fa9eac48SJed Brown   ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr);
8251469ee4dSjeremylt 
8261469ee4dSjeremylt   // Apply to get multiplicity
827a8d32208Sjeremylt   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult,
828efc78312Sjeremylt                                   CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
8291469ee4dSjeremylt 
8301469ee4dSjeremylt   // Cleanup
8311469ee4dSjeremylt   ierr = CeedVectorDestroy(&evec); CeedChk(ierr);
8321469ee4dSjeremylt 
8331469ee4dSjeremylt   return 0;
8341469ee4dSjeremylt }
8351469ee4dSjeremylt 
8361469ee4dSjeremylt /**
837f02ca4a2SJed Brown   @brief View a CeedElemRestriction
838f02ca4a2SJed Brown 
839f02ca4a2SJed Brown   @param[in] rstr    CeedElemRestriction to view
840f02ca4a2SJed Brown   @param[in] stream  Stream to write; typically stdout/stderr or a file
841f02ca4a2SJed Brown 
842f02ca4a2SJed Brown   @return Error code: 0 - success, otherwise - failure
843f02ca4a2SJed Brown 
8447a982d89SJeremy L. Thompson   @ref User
845f02ca4a2SJed Brown **/
846f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
8477509a596Sjeremylt   char stridesstr[500];
8487509a596Sjeremylt   if (rstr->strides)
8497509a596Sjeremylt     sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1],
8507509a596Sjeremylt             rstr->strides[2]);
851d979a051Sjeremylt   else
852d979a051Sjeremylt     sprintf(stridesstr, "%d", rstr->compstride);
8537509a596Sjeremylt 
8540036de2cSjeremylt   fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d "
8550036de2cSjeremylt           "nodes each and %s %s\n", rstr->blksize > 1 ? "Blocked " : "",
856d979a051Sjeremylt           rstr->lsize, rstr->ncomp, rstr->nelem, rstr->elemsize,
857d979a051Sjeremylt           rstr->strides ? "strides" : "component stride", stridesstr);
858f02ca4a2SJed Brown   return 0;
859f02ca4a2SJed Brown }
860f02ca4a2SJed Brown 
861f02ca4a2SJed Brown /**
862b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
863b11c1e72Sjeremylt 
8644ce2993fSjeremylt   @param rstr  CeedElemRestriction to destroy
865b11c1e72Sjeremylt 
866b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
867dfdf5a53Sjeremylt 
8687a982d89SJeremy L. Thompson   @ref User
869b11c1e72Sjeremylt **/
8704ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
871d7b241e6Sjeremylt   int ierr;
872d7b241e6Sjeremylt 
8731d102b48SJeremy L Thompson   if (!*rstr || --(*rstr)->refcount > 0)
8741d102b48SJeremy L Thompson     return 0;
875430758c8SJeremy L Thompson   if ((*rstr)->numreaders)
876430758c8SJeremy L Thompson     return CeedError((*rstr)->ceed, 1, "Cannot destroy CeedElemRestriction, "
877430758c8SJeremy L Thompson                      "a process has read access to the offset data");
8784ce2993fSjeremylt   if ((*rstr)->Destroy) {
8794ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
880d7b241e6Sjeremylt   }
8817509a596Sjeremylt   ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr);
8824ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
8834ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
884d7b241e6Sjeremylt   return 0;
885d7b241e6Sjeremylt }
886d7b241e6Sjeremylt 
887d7b241e6Sjeremylt /// @}
888