xref: /libCEED/interface/ceed-elemrestriction.c (revision ec3da8bcb94d9f0073544b37b5081a06981a86f7)
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 
17*ec3da8bcSJed Brown #include <ceed/ceed.h>
18*ec3da8bcSJed Brown #include <ceed/backend.h>
193d576824SJeremy L Thompson #include <ceed-impl.h>
203d576824SJeremy L Thompson #include <stdbool.h>
213d576824SJeremy L Thompson #include <stdio.h>
22d7b241e6Sjeremylt 
237a982d89SJeremy L. Thompson /// @file
247a982d89SJeremy L. Thompson /// Implementation of CeedElemRestriction interfaces
257a982d89SJeremy L. Thompson 
267a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
277a982d89SJeremy L. Thompson /// CeedElemRestriction Library Internal Functions
287a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
297a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionDeveloper
307a982d89SJeremy L. Thompson /// @{
317a982d89SJeremy L. Thompson 
327a982d89SJeremy L. Thompson /**
33d979a051Sjeremylt   @brief Permute and pad offsets for a blocked restriction
347a982d89SJeremy L. Thompson 
35d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
36d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
377a982d89SJeremy L. Thompson                       for the unknowns corresponding to element i, where
38d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
39d979a051Sjeremylt                       [0, @a lsize - 1].
40d979a051Sjeremylt   @param blkoffsets Array of permuted and padded offsets of
417a982d89SJeremy L. Thompson                       shape [@a nblk, @a elemsize, @a blksize].
427a982d89SJeremy L. Thompson   @param nblk       Number of blocks
437a982d89SJeremy L. Thompson   @param nelem      Number of elements
447a982d89SJeremy L. Thompson   @param blksize    Number of elements in a block
457a982d89SJeremy L. Thompson   @param elemsize   Size of each element
467a982d89SJeremy L. Thompson 
477a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
487a982d89SJeremy L. Thompson 
497a982d89SJeremy L. Thompson   @ref Utility
507a982d89SJeremy L. Thompson **/
51d979a051Sjeremylt int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blkoffsets,
527a982d89SJeremy L. Thompson                           CeedInt nblk, CeedInt nelem, CeedInt blksize,
537a982d89SJeremy L. Thompson                           CeedInt elemsize) {
547a982d89SJeremy L. Thompson   for (CeedInt e=0; e<nblk*blksize; e+=blksize)
557a982d89SJeremy L. Thompson     for (int j=0; j<blksize; j++)
567a982d89SJeremy L. Thompson       for (int k=0; k<elemsize; k++)
57d979a051Sjeremylt         blkoffsets[e*elemsize + k*blksize + j]
58d979a051Sjeremylt           = offsets[CeedIntMin(e+j,nelem-1)*elemsize + k];
59e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
607a982d89SJeremy L. Thompson }
617a982d89SJeremy L. Thompson 
627a982d89SJeremy L. Thompson /// @}
637a982d89SJeremy L. Thompson 
647a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
657a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API
667a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
677a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend
687a982d89SJeremy L. Thompson /// @{
697a982d89SJeremy L. Thompson 
707a982d89SJeremy L. Thompson /**
717a982d89SJeremy L. Thompson   @brief Get the Ceed associated with a CeedElemRestriction
727a982d89SJeremy L. Thompson 
737a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
747a982d89SJeremy L. Thompson   @param[out] ceed        Variable to store Ceed
757a982d89SJeremy L. Thompson 
767a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
777a982d89SJeremy L. Thompson 
787a982d89SJeremy L. Thompson   @ref Backend
797a982d89SJeremy L. Thompson **/
807a982d89SJeremy L. Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) {
817a982d89SJeremy L. Thompson   *ceed = rstr->ceed;
82e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
837a982d89SJeremy L. Thompson }
847a982d89SJeremy L. Thompson 
857a982d89SJeremy L. Thompson /**
86a681ae63Sjeremylt 
87a681ae63Sjeremylt   @brief Get the strides of a strided CeedElemRestriction
887a982d89SJeremy L. Thompson 
897a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
90a681ae63Sjeremylt   @param[out] strides     Variable to store strides array
917a982d89SJeremy L. Thompson 
927a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
937a982d89SJeremy L. Thompson 
947a982d89SJeremy L. Thompson   @ref Backend
957a982d89SJeremy L. Thompson **/
96a681ae63Sjeremylt int CeedElemRestrictionGetStrides(CeedElemRestriction rstr,
97a681ae63Sjeremylt                                   CeedInt (*strides)[3]) {
98a681ae63Sjeremylt   if (!rstr->strides)
99a681ae63Sjeremylt     // LCOV_EXCL_START
100e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_MINOR,
101e15f9bd0SJeremy L Thompson                      "ElemRestriction has no stride data");
102a681ae63Sjeremylt   // LCOV_EXCL_STOP
103a681ae63Sjeremylt 
104a681ae63Sjeremylt   for (int i=0; i<3; i++)
105a681ae63Sjeremylt     (*strides)[i] = rstr->strides[i];
106e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1077a982d89SJeremy L. Thompson }
1087a982d89SJeremy L. Thompson 
1097a982d89SJeremy L. Thompson /**
110bd33150aSjeremylt   @brief Get read-only access to a CeedElemRestriction offsets array by memtype
111bd33150aSjeremylt 
112bd33150aSjeremylt   @param rstr         CeedElemRestriction to retrieve offsets
113bd33150aSjeremylt   @param mtype        Memory type on which to access the array.  If the backend
114bd33150aSjeremylt                         uses a different memory type, this will perform a copy
115bd33150aSjeremylt                         (possibly cached).
116bd33150aSjeremylt   @param[out] offsets Array on memory type mtype
117bd33150aSjeremylt 
118bd33150aSjeremylt   @return An error code: 0 - success, otherwise - failure
119bd33150aSjeremylt 
120bd33150aSjeremylt   @ref User
121bd33150aSjeremylt **/
122bd33150aSjeremylt int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mtype,
123bd33150aSjeremylt                                   const CeedInt **offsets) {
124bd33150aSjeremylt   int ierr;
125bd33150aSjeremylt 
126bd33150aSjeremylt   if (!rstr->GetOffsets)
127bd33150aSjeremylt     // LCOV_EXCL_START
128e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_UNSUPPORTED,
129e15f9bd0SJeremy L Thompson                      "Backend does not support GetOffsets");
130bd33150aSjeremylt   // LCOV_EXCL_STOP
131bd33150aSjeremylt 
132bd33150aSjeremylt   ierr = rstr->GetOffsets(rstr, mtype, offsets); CeedChk(ierr);
133430758c8SJeremy L Thompson   rstr->numreaders++;
134e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
135430758c8SJeremy L Thompson }
136430758c8SJeremy L Thompson 
137430758c8SJeremy L Thompson /**
138430758c8SJeremy L Thompson   @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets()
139430758c8SJeremy L Thompson 
140430758c8SJeremy L Thompson   @param rstr    CeedElemRestriction to restore
141430758c8SJeremy L Thompson   @param offsets Array of offset data
142430758c8SJeremy L Thompson 
143430758c8SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
144430758c8SJeremy L Thompson 
145430758c8SJeremy L Thompson   @ref User
146430758c8SJeremy L Thompson **/
147430758c8SJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr,
148430758c8SJeremy L Thompson                                       const CeedInt **offsets) {
149430758c8SJeremy L Thompson   *offsets = NULL;
150430758c8SJeremy L Thompson   rstr->numreaders--;
151e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
152bd33150aSjeremylt }
153bd33150aSjeremylt 
154bd33150aSjeremylt /**
1553ac43b2cSJeremy L Thompson   @brief Get the strided status of a CeedElemRestriction
1563ac43b2cSJeremy L Thompson 
1573ac43b2cSJeremy L Thompson   @param rstr             CeedElemRestriction
158fd364f38SJeremy L Thompson   @param[out] isstrided   Variable to store strided status, 1 if strided else 0
1593ac43b2cSJeremy L Thompson 
1603ac43b2cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1613ac43b2cSJeremy L Thompson 
1623ac43b2cSJeremy L Thompson   @ref Backend
1633ac43b2cSJeremy L Thompson **/
164fd364f38SJeremy L Thompson int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *isstrided) {
165e15f9bd0SJeremy L Thompson   *isstrided = rstr->strides ? true : false;
166e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1673ac43b2cSJeremy L Thompson }
1683ac43b2cSJeremy L Thompson 
1693ac43b2cSJeremy L Thompson /**
170a681ae63Sjeremylt   @brief Get the backend stride status of a CeedElemRestriction
1717a982d89SJeremy L. Thompson 
1727a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
173a681ae63Sjeremylt   @param[out] status      Variable to store stride status
1747a982d89SJeremy L. Thompson 
1757a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
1767a982d89SJeremy L. Thompson 
1777a982d89SJeremy L. Thompson   @ref Backend
1787a982d89SJeremy L. Thompson **/
179fd364f38SJeremy L Thompson int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr,
180fd364f38SJeremy L Thompson     bool *hasbackendstrides) {
181a681ae63Sjeremylt   if (!rstr->strides)
182a681ae63Sjeremylt     // LCOV_EXCL_START
183e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_MINOR,
184e15f9bd0SJeremy L Thompson                      "ElemRestriction has no stride data");
185a681ae63Sjeremylt   // LCOV_EXCL_STOP
1867a982d89SJeremy L. Thompson 
187fd364f38SJeremy L Thompson   *hasbackendstrides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) &&
188a681ae63Sjeremylt                         (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) &&
189a681ae63Sjeremylt                         (rstr->strides[2] == CEED_STRIDES_BACKEND[2]));
190e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1917a982d89SJeremy L. Thompson }
1927a982d89SJeremy L. Thompson 
1937a982d89SJeremy L. Thompson /**
19449fd234cSJeremy L Thompson 
19549fd234cSJeremy L Thompson   @brief Get the E-vector layout of a CeedElemRestriction
19649fd234cSJeremy L Thompson 
19749fd234cSJeremy L Thompson   @param rstr             CeedElemRestriction
19849fd234cSJeremy L Thompson   @param[out] layout      Variable to store layout array,
19949fd234cSJeremy L Thompson                             stored as [nodes, components, elements].
20049fd234cSJeremy L Thompson                             The data for node i, component j, element k in the
20149fd234cSJeremy L Thompson                             E-vector is given by
20295e93d34SJeremy L Thompson                             i*layout[0] + j*layout[1] + k*layout[2]
20349fd234cSJeremy L Thompson 
20449fd234cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
20549fd234cSJeremy L Thompson 
20649fd234cSJeremy L Thompson   @ref Backend
20749fd234cSJeremy L Thompson **/
20849fd234cSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr,
20949fd234cSJeremy L Thompson                                   CeedInt (*layout)[3]) {
21049fd234cSJeremy L Thompson   if (!rstr->layout[0])
21149fd234cSJeremy L Thompson     // LCOV_EXCL_START
212e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_MINOR,
213e15f9bd0SJeremy L Thompson                      "ElemRestriction has no layout data");
21449fd234cSJeremy L Thompson   // LCOV_EXCL_STOP
21549fd234cSJeremy L Thompson 
21649fd234cSJeremy L Thompson   for (int i=0; i<3; i++)
21749fd234cSJeremy L Thompson     (*layout)[i] = rstr->layout[i];
218e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
21949fd234cSJeremy L Thompson }
22049fd234cSJeremy L Thompson 
22149fd234cSJeremy L Thompson /**
22249fd234cSJeremy L Thompson 
22349fd234cSJeremy L Thompson   @brief Set the E-vector layout of a CeedElemRestriction
22449fd234cSJeremy L Thompson 
22549fd234cSJeremy L Thompson   @param rstr             CeedElemRestriction
22649fd234cSJeremy L Thompson   @param layout           Variable to containing layout array,
22749fd234cSJeremy L Thompson                             stored as [nodes, components, elements].
22849fd234cSJeremy L Thompson                             The data for node i, component j, element k in the
22949fd234cSJeremy L Thompson                             E-vector is given by
23095e93d34SJeremy L Thompson                             i*layout[0] + j*layout[1] + k*layout[2]
23149fd234cSJeremy L Thompson 
23249fd234cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
23349fd234cSJeremy L Thompson 
23449fd234cSJeremy L Thompson   @ref Backend
23549fd234cSJeremy L Thompson **/
23649fd234cSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr,
23749fd234cSJeremy L Thompson                                   CeedInt layout[3]) {
23849fd234cSJeremy L Thompson   for (int i = 0; i<3; i++)
23949fd234cSJeremy L Thompson     rstr->layout[i] = layout[i];
240e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
24149fd234cSJeremy L Thompson }
24249fd234cSJeremy L Thompson 
24349fd234cSJeremy L Thompson /**
2447a982d89SJeremy L. Thompson   @brief Get the backend data of a CeedElemRestriction
2457a982d89SJeremy L. Thompson 
2467a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
2477a982d89SJeremy L. Thompson   @param[out] data        Variable to store data
2487a982d89SJeremy L. Thompson 
2497a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
2507a982d89SJeremy L. Thompson 
2517a982d89SJeremy L. Thompson   @ref Backend
2527a982d89SJeremy L. Thompson **/
253777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) {
254777ff853SJeremy L Thompson   *(void **)data = rstr->data;
255e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2567a982d89SJeremy L. Thompson }
2577a982d89SJeremy L. Thompson 
2587a982d89SJeremy L. Thompson /**
2597a982d89SJeremy L. Thompson   @brief Set the backend data of a CeedElemRestriction
2607a982d89SJeremy L. Thompson 
2617a982d89SJeremy L. Thompson   @param[out] rstr        CeedElemRestriction
2627a982d89SJeremy L. Thompson   @param data             Data to set
2637a982d89SJeremy L. Thompson 
2647a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
2657a982d89SJeremy L. Thompson 
2667a982d89SJeremy L. Thompson   @ref Backend
2677a982d89SJeremy L. Thompson **/
268777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) {
269777ff853SJeremy L Thompson   rstr->data = data;
270e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2717a982d89SJeremy L. Thompson }
2727a982d89SJeremy L. Thompson 
2737a982d89SJeremy L. Thompson /// @}
2747a982d89SJeremy L. Thompson 
27515910d16Sjeremylt /// @cond DOXYGEN_SKIP
27615910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none;
27715910d16Sjeremylt /// @endcond
27815910d16Sjeremylt 
2797a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2807a982d89SJeremy L. Thompson /// CeedElemRestriction Public API
2817a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2827a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser
283d7b241e6Sjeremylt /// @{
284d7b241e6Sjeremylt 
2857a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend
2867a982d89SJeremy L. Thompson const CeedInt CEED_STRIDES_BACKEND[3] = {};
2877a982d89SJeremy L. Thompson 
2884cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user
2897a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE =
2907a982d89SJeremy L. Thompson   &ceed_elemrestriction_none;
2917a982d89SJeremy L. Thompson 
292d7b241e6Sjeremylt /**
293b11c1e72Sjeremylt   @brief Create a CeedElemRestriction
294d7b241e6Sjeremylt 
295b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
296d979a051Sjeremylt   @param nelem      Number of elements described in the @a offsets array
297b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
298b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
29995bb1877Svaleriabarra                       (1 for scalar fields)
300d979a051Sjeremylt   @param compstride Stride between components for the same L-vector "node".
30195e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
30295e93d34SJeremy L Thompson                       the L-vector at index
3032db7ab32SJeremy L Thompson                         offsets[i + k*elemsize] + j*compstride.
304d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
305d979a051Sjeremylt                       the elements and fields given by this restriction.
306d979a051Sjeremylt   @param mtype      Memory type of the @a offsets array, see CeedMemType
307d979a051Sjeremylt   @param cmode      Copy mode for the @a offsets array, see CeedCopyMode
308d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
309d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
3108795c945Sjeremylt                       for the unknowns corresponding to element i, where
311d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
312d979a051Sjeremylt                       [0, @a lsize - 1].
3134ce2993fSjeremylt   @param[out] rstr  Address of the variable where the newly created
314b11c1e72Sjeremylt                       CeedElemRestriction will be stored
315d7b241e6Sjeremylt 
316b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
317dfdf5a53Sjeremylt 
3187a982d89SJeremy L. Thompson   @ref User
319b11c1e72Sjeremylt **/
320d979a051Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem, CeedInt elemsize,
321d979a051Sjeremylt                               CeedInt ncomp, CeedInt compstride,
322d979a051Sjeremylt                               CeedInt lsize, CeedMemType mtype,
323d979a051Sjeremylt                               CeedCopyMode cmode, const CeedInt *offsets,
3244ce2993fSjeremylt                               CeedElemRestriction *rstr) {
325d7b241e6Sjeremylt   int ierr;
326d7b241e6Sjeremylt 
3275fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
3285fe0d4faSjeremylt     Ceed delegate;
329aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
330aefd8378Sjeremylt     CeedChk(ierr);
3315fe0d4faSjeremylt 
3325fe0d4faSjeremylt     if (!delegate)
333c042f62fSJeremy L Thompson       // LCOV_EXCL_START
334e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
335e15f9bd0SJeremy L Thompson                        "Backend does not support ElemRestrictionCreate");
336c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3375fe0d4faSjeremylt 
338d979a051Sjeremylt     ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize, ncomp,
339d979a051Sjeremylt                                      compstride, lsize, mtype, cmode,
340d979a051Sjeremylt                                      offsets, rstr); CeedChk(ierr);
341e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
3425fe0d4faSjeremylt   }
3435fe0d4faSjeremylt 
3444ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
3454ce2993fSjeremylt   (*rstr)->ceed = ceed;
346d7b241e6Sjeremylt   ceed->refcount++;
3474ce2993fSjeremylt   (*rstr)->refcount = 1;
3484ce2993fSjeremylt   (*rstr)->nelem = nelem;
3494ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
3504ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
351d979a051Sjeremylt   (*rstr)->compstride = compstride;
352d979a051Sjeremylt   (*rstr)->lsize = lsize;
3534ce2993fSjeremylt   (*rstr)->nblk = nelem;
3544ce2993fSjeremylt   (*rstr)->blksize = 1;
355d979a051Sjeremylt   ierr = ceed->ElemRestrictionCreate(mtype, cmode, offsets, *rstr);
356d979a051Sjeremylt   CeedChk(ierr);
357e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
358d7b241e6Sjeremylt }
359d7b241e6Sjeremylt 
360d7b241e6Sjeremylt /**
3617509a596Sjeremylt   @brief Create a strided CeedElemRestriction
362d7b241e6Sjeremylt 
363b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
3647509a596Sjeremylt   @param nelem      Number of elements described by the restriction
365b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
36695e93d34SJeremy L Thompson   @param ncomp      Number of field components per interpolation "node"
36795bb1877Svaleriabarra                       (1 for scalar fields)
368d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
369d979a051Sjeremylt                       the elements and fields given by this restriction.
3707509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
37195e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
37295e93d34SJeremy L Thompson                       the L-vector at index
37395e93d34SJeremy L Thompson                         i*strides[0] + j*strides[1] + k*strides[2].
37495e93d34SJeremy L Thompson                       @a CEED_STRIDES_BACKEND may be used with vectors created
37595e93d34SJeremy L Thompson                       by a Ceed backend.
3764ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
377b11c1e72Sjeremylt                       CeedElemRestriction will be stored
378d7b241e6Sjeremylt 
379b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
380dfdf5a53Sjeremylt 
3817a982d89SJeremy L. Thompson   @ref User
382b11c1e72Sjeremylt **/
3837509a596Sjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt nelem, CeedInt elemsize,
384d979a051Sjeremylt                                      CeedInt ncomp, CeedInt lsize,
3858621c6c6SJeremy L Thompson                                      const CeedInt strides[3],
386f90c8643Sjeremylt                                      CeedElemRestriction *rstr) {
387d7b241e6Sjeremylt   int ierr;
388d7b241e6Sjeremylt 
3895fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
3905fe0d4faSjeremylt     Ceed delegate;
391aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
392aefd8378Sjeremylt     CeedChk(ierr);
3935fe0d4faSjeremylt 
3945fe0d4faSjeremylt     if (!delegate)
395c042f62fSJeremy L Thompson       // LCOV_EXCL_START
396e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
397e15f9bd0SJeremy L Thompson                        "Backend does not support ElemRestrictionCreate");
398c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3995fe0d4faSjeremylt 
400d979a051Sjeremylt     ierr = CeedElemRestrictionCreateStrided(delegate, nelem, elemsize, ncomp,
401d979a051Sjeremylt                                             lsize, strides, rstr);
402d979a051Sjeremylt     CeedChk(ierr);
403e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
4045fe0d4faSjeremylt   }
4055fe0d4faSjeremylt 
4064ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
4074ce2993fSjeremylt   (*rstr)->ceed = ceed;
408d7b241e6Sjeremylt   ceed->refcount++;
4094ce2993fSjeremylt   (*rstr)->refcount = 1;
4104ce2993fSjeremylt   (*rstr)->nelem = nelem;
4114ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
4124ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
413d979a051Sjeremylt   (*rstr)->lsize = lsize;
4144ce2993fSjeremylt   (*rstr)->nblk = nelem;
4154ce2993fSjeremylt   (*rstr)->blksize = 1;
4167509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
4177509a596Sjeremylt   for (int i=0; i<3; i++)
4187509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
4191dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
4201dfeef1dSjeremylt                                      *rstr);
4214b8bea3bSJed Brown   CeedChk(ierr);
422e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
423d7b241e6Sjeremylt }
424d7b241e6Sjeremylt 
425d7b241e6Sjeremylt /**
426b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
427d7b241e6Sjeremylt 
428d7b241e6Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created.
429d979a051Sjeremylt   @param nelem      Number of elements described in the @a offsets array.
430b11c1e72Sjeremylt   @param elemsize   Size (number of unknowns) per element
431b11c1e72Sjeremylt   @param blksize    Number of elements in a block
43295bb1877Svaleriabarra   @param ncomp      Number of field components per interpolation node
43395bb1877Svaleriabarra                       (1 for scalar fields)
434d979a051Sjeremylt   @param compstride Stride between components for the same L-vector "node".
43595e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
43695e93d34SJeremy L Thompson                       the L-vector at index
4372db7ab32SJeremy L Thompson                         offsets[i + k*elemsize] + j*compstride.
438d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
439d979a051Sjeremylt                       the elements and fields given by this restriction.
440d979a051Sjeremylt   @param mtype      Memory type of the @a offsets array, see CeedMemType
441d979a051Sjeremylt   @param cmode      Copy mode for the @a offsets array, see CeedCopyMode
442d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
443d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
4448795c945Sjeremylt                       for the unknowns corresponding to element i, where
445d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
446d979a051Sjeremylt                       [0, @a lsize - 1]. The backend will permute and pad this
4478795c945Sjeremylt                       array to the desired ordering for the blocksize, which is
4488795c945Sjeremylt                       typically given by the backend. The default reordering is
4498795c945Sjeremylt                       to interlace elements.
4504ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
451b11c1e72Sjeremylt                       CeedElemRestriction will be stored
452d7b241e6Sjeremylt 
453b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
454dfdf5a53Sjeremylt 
4557a982d89SJeremy L. Thompson   @ref Backend
456b11c1e72Sjeremylt  **/
457d979a051Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize,
458d979a051Sjeremylt                                      CeedInt blksize, CeedInt ncomp,
459d979a051Sjeremylt                                      CeedInt compstride, CeedInt lsize,
460d979a051Sjeremylt                                      CeedMemType mtype, CeedCopyMode cmode,
461d979a051Sjeremylt                                      const CeedInt *offsets,
4624ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
463d7b241e6Sjeremylt   int ierr;
464d979a051Sjeremylt   CeedInt *blkoffsets;
465d7b241e6Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
466d7b241e6Sjeremylt 
4675fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
4685fe0d4faSjeremylt     Ceed delegate;
469aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
470aefd8378Sjeremylt     CeedChk(ierr);
4715fe0d4faSjeremylt 
4725fe0d4faSjeremylt     if (!delegate)
473c042f62fSJeremy L Thompson       // LCOV_EXCL_START
474e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support "
4751d102b48SJeremy L Thompson                        "ElemRestrictionCreateBlocked");
476c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
4775fe0d4faSjeremylt 
478d979a051Sjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize, blksize,
479d979a051Sjeremylt                                             ncomp, compstride, lsize, mtype,
480d979a051Sjeremylt                                             cmode, offsets, rstr);
481d979a051Sjeremylt     CeedChk(ierr);
482e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
4835fe0d4faSjeremylt   }
484d7b241e6Sjeremylt 
4854ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
486d7b241e6Sjeremylt 
487d979a051Sjeremylt   ierr = CeedCalloc(nblk*blksize*elemsize, &blkoffsets); CeedChk(ierr);
488d979a051Sjeremylt   ierr = CeedPermutePadOffsets(offsets, blkoffsets, nblk, nelem, blksize,
4894b8bea3bSJed Brown                                elemsize);
490dfdf5a53Sjeremylt   CeedChk(ierr);
491d7b241e6Sjeremylt 
4924ce2993fSjeremylt   (*rstr)->ceed = ceed;
493d7b241e6Sjeremylt   ceed->refcount++;
4944ce2993fSjeremylt   (*rstr)->refcount = 1;
4954ce2993fSjeremylt   (*rstr)->nelem = nelem;
4964ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
4974ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
498d979a051Sjeremylt   (*rstr)->compstride = compstride;
499d979a051Sjeremylt   (*rstr)->lsize = lsize;
5004ce2993fSjeremylt   (*rstr)->nblk = nblk;
5014ce2993fSjeremylt   (*rstr)->blksize = blksize;
502667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
503d979a051Sjeremylt          (const CeedInt *) blkoffsets, *rstr); CeedChk(ierr);
5041d102b48SJeremy L Thompson   if (cmode == CEED_OWN_POINTER) {
505d979a051Sjeremylt     ierr = CeedFree(&offsets); CeedChk(ierr);
5061d102b48SJeremy L Thompson   }
507e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
508d7b241e6Sjeremylt }
509d7b241e6Sjeremylt 
510b11c1e72Sjeremylt /**
5117509a596Sjeremylt   @brief Create a blocked strided CeedElemRestriction
5127509a596Sjeremylt 
5137509a596Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
5147509a596Sjeremylt   @param nelem      Number of elements described by the restriction
5157509a596Sjeremylt   @param elemsize   Size (number of "nodes") per element
5167509a596Sjeremylt   @param blksize    Number of elements in a block
5177509a596Sjeremylt   @param ncomp      Number of field components per interpolation node
5187509a596Sjeremylt                       (1 for scalar fields)
519d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
520d979a051Sjeremylt                       the elements and fields given by this restriction.
5217509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
52295e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
52395e93d34SJeremy L Thompson                       the L-vector at index
52495e93d34SJeremy L Thompson                         i*strides[0] + j*strides[1] + k*strides[2].
52595e93d34SJeremy L Thompson                       @a CEED_STRIDES_BACKEND may be used with vectors created
52695e93d34SJeremy L Thompson                       by a Ceed backend.
5277509a596Sjeremylt   @param rstr       Address of the variable where the newly created
5287509a596Sjeremylt                       CeedElemRestriction will be stored
5297509a596Sjeremylt 
5307509a596Sjeremylt   @return An error code: 0 - success, otherwise - failure
5317509a596Sjeremylt 
5327a982d89SJeremy L. Thompson   @ref User
5337509a596Sjeremylt **/
5347509a596Sjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt nelem,
535d979a051Sjeremylt     CeedInt elemsize, CeedInt blksize, CeedInt ncomp, CeedInt lsize,
5368621c6c6SJeremy L Thompson     const CeedInt strides[3], CeedElemRestriction *rstr) {
5377509a596Sjeremylt   int ierr;
5387509a596Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
5397509a596Sjeremylt 
5407509a596Sjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
5417509a596Sjeremylt     Ceed delegate;
5427509a596Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
5437509a596Sjeremylt     CeedChk(ierr);
5447509a596Sjeremylt 
5457509a596Sjeremylt     if (!delegate)
5467509a596Sjeremylt       // LCOV_EXCL_START
547e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support "
5487509a596Sjeremylt                        "ElemRestrictionCreateBlocked");
5497509a596Sjeremylt     // LCOV_EXCL_STOP
5507509a596Sjeremylt 
5517509a596Sjeremylt     ierr = CeedElemRestrictionCreateBlockedStrided(delegate, nelem, elemsize,
552d979a051Sjeremylt            blksize, ncomp, lsize, strides, rstr);
5537509a596Sjeremylt     CeedChk(ierr);
554e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
5557509a596Sjeremylt   }
5567509a596Sjeremylt 
5577509a596Sjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
5587509a596Sjeremylt 
5597509a596Sjeremylt   (*rstr)->ceed = ceed;
5607509a596Sjeremylt   ceed->refcount++;
5617509a596Sjeremylt   (*rstr)->refcount = 1;
5627509a596Sjeremylt   (*rstr)->nelem = nelem;
5637509a596Sjeremylt   (*rstr)->elemsize = elemsize;
5647509a596Sjeremylt   (*rstr)->ncomp = ncomp;
565d979a051Sjeremylt   (*rstr)->lsize = lsize;
5667509a596Sjeremylt   (*rstr)->nblk = nblk;
5677509a596Sjeremylt   (*rstr)->blksize = blksize;
5687509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
5697509a596Sjeremylt   for (int i=0; i<3; i++)
5707509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
5717509a596Sjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
5727509a596Sjeremylt          NULL, *rstr); CeedChk(ierr);
573e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5747509a596Sjeremylt }
5757509a596Sjeremylt 
5767509a596Sjeremylt /**
577b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
578b11c1e72Sjeremylt 
5794ce2993fSjeremylt   @param rstr  CeedElemRestriction
580b11c1e72Sjeremylt   @param lvec  The address of the L-vector to be created, or NULL
581b11c1e72Sjeremylt   @param evec  The address of the E-vector to be created, or NULL
582b11c1e72Sjeremylt 
583b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
584dfdf5a53Sjeremylt 
5857a982d89SJeremy L. Thompson   @ref User
586b11c1e72Sjeremylt **/
5874ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec,
588d7b241e6Sjeremylt                                     CeedVector *evec) {
589d7b241e6Sjeremylt   int ierr;
590d7b241e6Sjeremylt   CeedInt n, m;
591d979a051Sjeremylt   m = rstr->lsize;
5924ce2993fSjeremylt   n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
593d7b241e6Sjeremylt   if (lvec) {
5944ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr);
595d7b241e6Sjeremylt   }
596d7b241e6Sjeremylt   if (evec) {
5974ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr);
598d7b241e6Sjeremylt   }
599e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
600d7b241e6Sjeremylt }
601d7b241e6Sjeremylt 
602d7b241e6Sjeremylt /**
603d9e1f99aSValeria Barra   @brief Restrict an L-vector to an E-vector or apply its transpose
604d7b241e6Sjeremylt 
6054ce2993fSjeremylt   @param rstr    CeedElemRestriction
606d7b241e6Sjeremylt   @param tmode   Apply restriction or transpose
6074cc79fe7SJed Brown   @param u       Input vector (of size @a lsize when tmode=@ref CEED_NOTRANSPOSE)
608a8d32208Sjeremylt   @param ru      Output vector (of shape [@a nelem * @a elemsize] when
6094cc79fe7SJed Brown                    tmode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
6107aaeacdcSjeremylt                    by the backend.
6114cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
612b11c1e72Sjeremylt 
613b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
614dfdf5a53Sjeremylt 
6157a982d89SJeremy L. Thompson   @ref User
616b11c1e72Sjeremylt **/
6174ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode,
618a8d32208Sjeremylt                              CeedVector u, CeedVector ru,
619a8d32208Sjeremylt                              CeedRequest *request) {
620d7b241e6Sjeremylt   CeedInt m,n;
621d7b241e6Sjeremylt   int ierr;
622d7b241e6Sjeremylt 
623d7b241e6Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
6244ce2993fSjeremylt     m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
625d979a051Sjeremylt     n = rstr->lsize;
626d7b241e6Sjeremylt   } else {
627d979a051Sjeremylt     m = rstr->lsize;
6284ce2993fSjeremylt     n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
629d7b241e6Sjeremylt   }
630d7b241e6Sjeremylt   if (n != u->length)
631c042f62fSJeremy L Thompson     // LCOV_EXCL_START
632e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
633e15f9bd0SJeremy L Thompson                      "Input vector size %d not compatible with "
6341d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
635c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
636a8d32208Sjeremylt   if (m != ru->length)
637c042f62fSJeremy L Thompson     // LCOV_EXCL_START
638e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
639e15f9bd0SJeremy L Thompson                      "Output vector size %d not compatible with "
640a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
641c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
642074cb416Sjeremylt   ierr = rstr->Apply(rstr, tmode, u, ru, request); CeedChk(ierr);
643e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
644d7b241e6Sjeremylt }
645d7b241e6Sjeremylt 
646d7b241e6Sjeremylt /**
647d9e1f99aSValeria Barra   @brief Restrict an L-vector to a block of an E-vector or apply its transpose
648be9261b7Sjeremylt 
649be9261b7Sjeremylt   @param rstr    CeedElemRestriction
6501f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
6511f37b403Sjeremylt                    elements [0 : blksize] and block=3 will handle elements
6521f37b403Sjeremylt                    [3*blksize : 4*blksize]
653be9261b7Sjeremylt   @param tmode   Apply restriction or transpose
6544cc79fe7SJed Brown   @param u       Input vector (of size @a lsize when tmode=@ref CEED_NOTRANSPOSE)
655a8d32208Sjeremylt   @param ru      Output vector (of shape [@a blksize * @a elemsize] when
6564cc79fe7SJed Brown                    tmode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
6577aaeacdcSjeremylt                    by the backend.
6584cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
659be9261b7Sjeremylt 
660be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
661be9261b7Sjeremylt 
6627a982d89SJeremy L. Thompson   @ref Backend
663be9261b7Sjeremylt **/
664be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
665a8d32208Sjeremylt                                   CeedTransposeMode tmode, CeedVector u,
666a8d32208Sjeremylt                                   CeedVector ru, CeedRequest *request) {
667be9261b7Sjeremylt   CeedInt m,n;
668be9261b7Sjeremylt   int ierr;
669be9261b7Sjeremylt 
670be9261b7Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
671be9261b7Sjeremylt     m = rstr->blksize * rstr->elemsize * rstr->ncomp;
672d979a051Sjeremylt     n = rstr->lsize;
673be9261b7Sjeremylt   } else {
674d979a051Sjeremylt     m = rstr->lsize;
675be9261b7Sjeremylt     n = rstr->blksize * rstr->elemsize * rstr->ncomp;
676be9261b7Sjeremylt   }
677be9261b7Sjeremylt   if (n != u->length)
678c042f62fSJeremy L Thompson     // LCOV_EXCL_START
679e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
680e15f9bd0SJeremy L Thompson                      "Input vector size %d not compatible with "
6811d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
682c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
683a8d32208Sjeremylt   if (m != ru->length)
684c042f62fSJeremy L Thompson     // LCOV_EXCL_START
685e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
686e15f9bd0SJeremy L Thompson                      "Output vector size %d not compatible with "
687a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
688c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
689be9261b7Sjeremylt   if (rstr->blksize*block > rstr->nelem)
690c042f62fSJeremy L Thompson     // LCOV_EXCL_START
691e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
692e15f9bd0SJeremy L Thompson                      "Cannot retrieve block %d, element %d > "
6931d102b48SJeremy L Thompson                      "total elements %d", block, rstr->blksize*block,
6941d102b48SJeremy L Thompson                      rstr->nelem);
695c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
696074cb416Sjeremylt   ierr = rstr->ApplyBlock(rstr, block, tmode, u, ru, request);
697be9261b7Sjeremylt   CeedChk(ierr);
698e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
699be9261b7Sjeremylt }
700be9261b7Sjeremylt 
701be9261b7Sjeremylt /**
702d979a051Sjeremylt   @brief Get the L-vector component stride
703a681ae63Sjeremylt 
704a681ae63Sjeremylt   @param rstr             CeedElemRestriction
705d979a051Sjeremylt   @param[out] compstride  Variable to store component stride
706a681ae63Sjeremylt 
707a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
708a681ae63Sjeremylt 
709a681ae63Sjeremylt   @ref Backend
710a681ae63Sjeremylt **/
711d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr,
712d979a051Sjeremylt                                      CeedInt *compstride) {
713d979a051Sjeremylt   *compstride = rstr->compstride;
714e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
715a681ae63Sjeremylt }
716a681ae63Sjeremylt 
717a681ae63Sjeremylt /**
718a681ae63Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
719a681ae63Sjeremylt 
720a681ae63Sjeremylt   @param rstr             CeedElemRestriction
721a681ae63Sjeremylt   @param[out] numelem     Variable to store number of elements
722a681ae63Sjeremylt 
723a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
724a681ae63Sjeremylt 
725a681ae63Sjeremylt   @ref Backend
726a681ae63Sjeremylt **/
727a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
728a681ae63Sjeremylt                                       CeedInt *numelem) {
729a681ae63Sjeremylt   *numelem = rstr->nelem;
730e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
731a681ae63Sjeremylt }
732a681ae63Sjeremylt 
733a681ae63Sjeremylt /**
734a681ae63Sjeremylt   @brief Get the size of elements in the CeedElemRestriction
735a681ae63Sjeremylt 
736a681ae63Sjeremylt   @param rstr             CeedElemRestriction
737a681ae63Sjeremylt   @param[out] elemsize    Variable to store size of elements
738a681ae63Sjeremylt 
739a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
740a681ae63Sjeremylt 
741a681ae63Sjeremylt   @ref Backend
742a681ae63Sjeremylt **/
743a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
744a681ae63Sjeremylt                                       CeedInt *elemsize) {
745a681ae63Sjeremylt   *elemsize = rstr->elemsize;
746e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
747a681ae63Sjeremylt }
748a681ae63Sjeremylt 
749a681ae63Sjeremylt /**
750d979a051Sjeremylt   @brief Get the size of the l-vector for a CeedElemRestriction
751a681ae63Sjeremylt 
752a681ae63Sjeremylt   @param rstr             CeedElemRestriction
753a681ae63Sjeremylt   @param[out] numnodes    Variable to store number of nodes
754a681ae63Sjeremylt 
755a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
756a681ae63Sjeremylt 
757a681ae63Sjeremylt   @ref Backend
758a681ae63Sjeremylt **/
759d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr,
760d979a051Sjeremylt                                       CeedInt *lsize) {
761d979a051Sjeremylt   *lsize = rstr->lsize;
762e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
763a681ae63Sjeremylt }
764a681ae63Sjeremylt 
765a681ae63Sjeremylt /**
766a681ae63Sjeremylt   @brief Get the number of components in the elements of a
767a681ae63Sjeremylt          CeedElemRestriction
768a681ae63Sjeremylt 
769a681ae63Sjeremylt   @param rstr             CeedElemRestriction
770a681ae63Sjeremylt   @param[out] numcomp     Variable to store number of components
771a681ae63Sjeremylt 
772a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
773a681ae63Sjeremylt 
774a681ae63Sjeremylt   @ref Backend
775a681ae63Sjeremylt **/
776a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
777a681ae63Sjeremylt                                         CeedInt *numcomp) {
778a681ae63Sjeremylt   *numcomp = rstr->ncomp;
779e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
780a681ae63Sjeremylt }
781a681ae63Sjeremylt 
782a681ae63Sjeremylt /**
783a681ae63Sjeremylt   @brief Get the number of blocks in a CeedElemRestriction
784a681ae63Sjeremylt 
785a681ae63Sjeremylt   @param rstr             CeedElemRestriction
786a681ae63Sjeremylt   @param[out] numblock    Variable to store number of blocks
787a681ae63Sjeremylt 
788a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
789a681ae63Sjeremylt 
790a681ae63Sjeremylt   @ref Backend
791a681ae63Sjeremylt **/
792a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
793a681ae63Sjeremylt                                     CeedInt *numblock) {
794a681ae63Sjeremylt   *numblock = rstr->nblk;
795e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
796a681ae63Sjeremylt }
797a681ae63Sjeremylt 
798a681ae63Sjeremylt /**
799a681ae63Sjeremylt   @brief Get the size of blocks in the CeedElemRestriction
800a681ae63Sjeremylt 
801a681ae63Sjeremylt   @param rstr             CeedElemRestriction
802a681ae63Sjeremylt   @param[out] blksize     Variable to store size of blocks
803a681ae63Sjeremylt 
804a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
805a681ae63Sjeremylt 
806a681ae63Sjeremylt   @ref Backend
807a681ae63Sjeremylt **/
808a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
809a681ae63Sjeremylt                                     CeedInt *blksize) {
810a681ae63Sjeremylt   *blksize = rstr->blksize;
811e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
812a681ae63Sjeremylt }
813a681ae63Sjeremylt 
814a681ae63Sjeremylt /**
815d9e1f99aSValeria Barra   @brief Get the multiplicity of nodes in a CeedElemRestriction
8161469ee4dSjeremylt 
8171469ee4dSjeremylt   @param rstr             CeedElemRestriction
818d979a051Sjeremylt   @param[out] mult        Vector to store multiplicity (of size lsize)
8191469ee4dSjeremylt 
8201469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
8211469ee4dSjeremylt 
8227a982d89SJeremy L. Thompson   @ref User
8231469ee4dSjeremylt **/
8241469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
8251469ee4dSjeremylt                                        CeedVector mult) {
8261469ee4dSjeremylt   int ierr;
8271469ee4dSjeremylt   CeedVector evec;
8281469ee4dSjeremylt 
8291469ee4dSjeremylt   // Create and set evec
8301469ee4dSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr);
8311469ee4dSjeremylt   ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr);
832fa9eac48SJed Brown   ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr);
8331469ee4dSjeremylt 
8341469ee4dSjeremylt   // Apply to get multiplicity
835a8d32208Sjeremylt   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult,
836efc78312Sjeremylt                                   CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
8371469ee4dSjeremylt 
8381469ee4dSjeremylt   // Cleanup
8391469ee4dSjeremylt   ierr = CeedVectorDestroy(&evec); CeedChk(ierr);
840e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
8411469ee4dSjeremylt }
8421469ee4dSjeremylt 
8431469ee4dSjeremylt /**
844f02ca4a2SJed Brown   @brief View a CeedElemRestriction
845f02ca4a2SJed Brown 
846f02ca4a2SJed Brown   @param[in] rstr    CeedElemRestriction to view
847f02ca4a2SJed Brown   @param[in] stream  Stream to write; typically stdout/stderr or a file
848f02ca4a2SJed Brown 
849f02ca4a2SJed Brown   @return Error code: 0 - success, otherwise - failure
850f02ca4a2SJed Brown 
8517a982d89SJeremy L. Thompson   @ref User
852f02ca4a2SJed Brown **/
853f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
8547509a596Sjeremylt   char stridesstr[500];
8557509a596Sjeremylt   if (rstr->strides)
8567509a596Sjeremylt     sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1],
8577509a596Sjeremylt             rstr->strides[2]);
858d979a051Sjeremylt   else
859d979a051Sjeremylt     sprintf(stridesstr, "%d", rstr->compstride);
8607509a596Sjeremylt 
8610036de2cSjeremylt   fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d "
8620036de2cSjeremylt           "nodes each and %s %s\n", rstr->blksize > 1 ? "Blocked " : "",
863d979a051Sjeremylt           rstr->lsize, rstr->ncomp, rstr->nelem, rstr->elemsize,
864d979a051Sjeremylt           rstr->strides ? "strides" : "component stride", stridesstr);
865e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
866f02ca4a2SJed Brown }
867f02ca4a2SJed Brown 
868f02ca4a2SJed Brown /**
869b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
870b11c1e72Sjeremylt 
8714ce2993fSjeremylt   @param rstr  CeedElemRestriction to destroy
872b11c1e72Sjeremylt 
873b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
874dfdf5a53Sjeremylt 
8757a982d89SJeremy L. Thompson   @ref User
876b11c1e72Sjeremylt **/
8774ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
878d7b241e6Sjeremylt   int ierr;
879d7b241e6Sjeremylt 
880e15f9bd0SJeremy L Thompson   if (!*rstr || --(*rstr)->refcount > 0) return CEED_ERROR_SUCCESS;
881430758c8SJeremy L Thompson   if ((*rstr)->numreaders)
882e15f9bd0SJeremy L Thompson     return CeedError((*rstr)->ceed, CEED_ERROR_ACCESS,
883e15f9bd0SJeremy L Thompson                      "Cannot destroy CeedElemRestriction, "
884430758c8SJeremy L Thompson                      "a process has read access to the offset data");
8854ce2993fSjeremylt   if ((*rstr)->Destroy) {
8864ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
887d7b241e6Sjeremylt   }
8887509a596Sjeremylt   ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr);
8894ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
8904ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
891e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
892d7b241e6Sjeremylt }
893d7b241e6Sjeremylt 
894d7b241e6Sjeremylt /// @}
895