xref: /libCEED/interface/ceed-elemrestriction.c (revision 3d576824e8d990e1f48c6609089904bee9170514)
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*3d576824SJeremy L Thompson #include <ceed.h>
18d863ab9bSjeremylt #include <ceed-backend.h>
19*3d576824SJeremy L Thompson #include <ceed-impl.h>
20*3d576824SJeremy L Thompson #include <stdbool.h>
21*3d576824SJeremy 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];
597a982d89SJeremy L. Thompson   return 0;
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;
827a982d89SJeremy L. Thompson   return 0;
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
100a681ae63Sjeremylt     return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data");
101a681ae63Sjeremylt   // LCOV_EXCL_STOP
102a681ae63Sjeremylt 
103a681ae63Sjeremylt   for (int i = 0; i<3; i++)
104a681ae63Sjeremylt     (*strides)[i] = rstr->strides[i];
1057a982d89SJeremy L. Thompson   return 0;
1067a982d89SJeremy L. Thompson }
1077a982d89SJeremy L. Thompson 
1087a982d89SJeremy L. Thompson /**
109bd33150aSjeremylt   @brief Get read-only access to a CeedElemRestriction offsets array by memtype
110bd33150aSjeremylt 
111bd33150aSjeremylt   @param rstr         CeedElemRestriction to retrieve offsets
112bd33150aSjeremylt   @param mtype        Memory type on which to access the array.  If the backend
113bd33150aSjeremylt                         uses a different memory type, this will perform a copy
114bd33150aSjeremylt                         (possibly cached).
115bd33150aSjeremylt   @param[out] offsets Array on memory type mtype
116bd33150aSjeremylt 
117bd33150aSjeremylt   @return An error code: 0 - success, otherwise - failure
118bd33150aSjeremylt 
119bd33150aSjeremylt   @ref User
120bd33150aSjeremylt **/
121bd33150aSjeremylt int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mtype,
122bd33150aSjeremylt                                   const CeedInt **offsets) {
123bd33150aSjeremylt   int ierr;
124bd33150aSjeremylt 
125bd33150aSjeremylt   if (!rstr->GetOffsets)
126bd33150aSjeremylt     // LCOV_EXCL_START
127bd33150aSjeremylt     return CeedError(rstr->ceed, 1, "Backend does not support GetOffsets");
128bd33150aSjeremylt   // LCOV_EXCL_STOP
129bd33150aSjeremylt 
130bd33150aSjeremylt   ierr = rstr->GetOffsets(rstr, mtype, offsets); CeedChk(ierr);
131430758c8SJeremy L Thompson   rstr->numreaders++;
132430758c8SJeremy L Thompson   return 0;
133430758c8SJeremy L Thompson }
134430758c8SJeremy L Thompson 
135430758c8SJeremy L Thompson /**
136430758c8SJeremy L Thompson   @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets()
137430758c8SJeremy L Thompson 
138430758c8SJeremy L Thompson   @param rstr    CeedElemRestriction to restore
139430758c8SJeremy L Thompson   @param offsets Array of offset data
140430758c8SJeremy L Thompson 
141430758c8SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
142430758c8SJeremy L Thompson 
143430758c8SJeremy L Thompson   @ref User
144430758c8SJeremy L Thompson **/
145430758c8SJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr,
146430758c8SJeremy L Thompson                                       const CeedInt **offsets) {
147430758c8SJeremy L Thompson   *offsets = NULL;
148430758c8SJeremy L Thompson   rstr->numreaders--;
149bd33150aSjeremylt   return 0;
150bd33150aSjeremylt }
151bd33150aSjeremylt 
152bd33150aSjeremylt /**
1533ac43b2cSJeremy L Thompson   @brief Get the strided status of a CeedElemRestriction
1543ac43b2cSJeremy L Thompson 
1553ac43b2cSJeremy L Thompson   @param rstr             CeedElemRestriction
156fd364f38SJeremy L Thompson   @param[out] isstrided   Variable to store strided status, 1 if strided else 0
1573ac43b2cSJeremy L Thompson 
1583ac43b2cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1593ac43b2cSJeremy L Thompson 
1603ac43b2cSJeremy L Thompson   @ref Backend
1613ac43b2cSJeremy L Thompson **/
162fd364f38SJeremy L Thompson int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *isstrided) {
163fd364f38SJeremy L Thompson   *isstrided = rstr->strides ? 1 : 0;
1643ac43b2cSJeremy L Thompson   return 0;
1653ac43b2cSJeremy L Thompson }
1663ac43b2cSJeremy L Thompson 
1673ac43b2cSJeremy L Thompson /**
168a681ae63Sjeremylt   @brief Get the backend stride status of a CeedElemRestriction
1697a982d89SJeremy L. Thompson 
1707a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
171a681ae63Sjeremylt   @param[out] status      Variable to store stride status
1727a982d89SJeremy L. Thompson 
1737a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
1747a982d89SJeremy L. Thompson 
1757a982d89SJeremy L. Thompson   @ref Backend
1767a982d89SJeremy L. Thompson **/
177fd364f38SJeremy L Thompson int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr,
178fd364f38SJeremy L Thompson     bool *hasbackendstrides) {
179a681ae63Sjeremylt   if (!rstr->strides)
180a681ae63Sjeremylt     // LCOV_EXCL_START
181a681ae63Sjeremylt     return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data");
182a681ae63Sjeremylt   // LCOV_EXCL_STOP
1837a982d89SJeremy L. Thompson 
184fd364f38SJeremy L Thompson   *hasbackendstrides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) &&
185a681ae63Sjeremylt                         (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) &&
186a681ae63Sjeremylt                         (rstr->strides[2] == CEED_STRIDES_BACKEND[2]));
1877a982d89SJeremy L. Thompson   return 0;
1887a982d89SJeremy L. Thompson }
1897a982d89SJeremy L. Thompson 
1907a982d89SJeremy L. Thompson /**
19149fd234cSJeremy L Thompson 
19249fd234cSJeremy L Thompson   @brief Get the E-vector layout of a CeedElemRestriction
19349fd234cSJeremy L Thompson 
19449fd234cSJeremy L Thompson   @param rstr             CeedElemRestriction
19549fd234cSJeremy L Thompson   @param[out] layout      Variable to store layout array,
19649fd234cSJeremy L Thompson                             stored as [nodes, components, elements].
19749fd234cSJeremy L Thompson                             The data for node i, component j, element k in the
19849fd234cSJeremy L Thompson                             E-vector is given by
19995e93d34SJeremy L Thompson                             i*layout[0] + j*layout[1] + k*layout[2]
20049fd234cSJeremy L Thompson 
20149fd234cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
20249fd234cSJeremy L Thompson 
20349fd234cSJeremy L Thompson   @ref Backend
20449fd234cSJeremy L Thompson **/
20549fd234cSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr,
20649fd234cSJeremy L Thompson                                   CeedInt (*layout)[3]) {
20749fd234cSJeremy L Thompson   if (!rstr->layout[0])
20849fd234cSJeremy L Thompson     // LCOV_EXCL_START
20949fd234cSJeremy L Thompson     return CeedError(rstr->ceed, 1, "ElemRestriction has no layout data");
21049fd234cSJeremy L Thompson   // LCOV_EXCL_STOP
21149fd234cSJeremy L Thompson 
21249fd234cSJeremy L Thompson   for (int i = 0; i<3; i++)
21349fd234cSJeremy L Thompson     (*layout)[i] = rstr->layout[i];
21449fd234cSJeremy L Thompson   return 0;
21549fd234cSJeremy L Thompson }
21649fd234cSJeremy L Thompson 
21749fd234cSJeremy L Thompson /**
21849fd234cSJeremy L Thompson 
21949fd234cSJeremy L Thompson   @brief Set the E-vector layout of a CeedElemRestriction
22049fd234cSJeremy L Thompson 
22149fd234cSJeremy L Thompson   @param rstr             CeedElemRestriction
22249fd234cSJeremy L Thompson   @param layout           Variable to containing layout array,
22349fd234cSJeremy L Thompson                             stored as [nodes, components, elements].
22449fd234cSJeremy L Thompson                             The data for node i, component j, element k in the
22549fd234cSJeremy L Thompson                             E-vector is given by
22695e93d34SJeremy L Thompson                             i*layout[0] + j*layout[1] + k*layout[2]
22749fd234cSJeremy L Thompson 
22849fd234cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
22949fd234cSJeremy L Thompson 
23049fd234cSJeremy L Thompson   @ref Backend
23149fd234cSJeremy L Thompson **/
23249fd234cSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr,
23349fd234cSJeremy L Thompson                                   CeedInt layout[3]) {
23449fd234cSJeremy L Thompson   for (int i = 0; i<3; i++)
23549fd234cSJeremy L Thompson     rstr->layout[i] = layout[i];
23649fd234cSJeremy L Thompson   return 0;
23749fd234cSJeremy L Thompson }
23849fd234cSJeremy L Thompson 
23949fd234cSJeremy L Thompson /**
2407a982d89SJeremy L. Thompson   @brief Get the backend data of a CeedElemRestriction
2417a982d89SJeremy L. Thompson 
2427a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
2437a982d89SJeremy L. Thompson   @param[out] data        Variable to store data
2447a982d89SJeremy L. Thompson 
2457a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
2467a982d89SJeremy L. Thompson 
2477a982d89SJeremy L. Thompson   @ref Backend
2487a982d89SJeremy L. Thompson **/
249777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) {
250777ff853SJeremy L Thompson   *(void **)data = rstr->data;
2517a982d89SJeremy L. Thompson   return 0;
2527a982d89SJeremy L. Thompson }
2537a982d89SJeremy L. Thompson 
2547a982d89SJeremy L. Thompson /**
2557a982d89SJeremy L. Thompson   @brief Set the backend data of a CeedElemRestriction
2567a982d89SJeremy L. Thompson 
2577a982d89SJeremy L. Thompson   @param[out] rstr        CeedElemRestriction
2587a982d89SJeremy L. Thompson   @param data             Data to set
2597a982d89SJeremy L. Thompson 
2607a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
2617a982d89SJeremy L. Thompson 
2627a982d89SJeremy L. Thompson   @ref Backend
2637a982d89SJeremy L. Thompson **/
264777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) {
265777ff853SJeremy L Thompson   rstr->data = data;
2667a982d89SJeremy L. Thompson   return 0;
2677a982d89SJeremy L. Thompson }
2687a982d89SJeremy L. Thompson 
2697a982d89SJeremy L. Thompson /// @}
2707a982d89SJeremy L. Thompson 
27115910d16Sjeremylt /// @cond DOXYGEN_SKIP
27215910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none;
27315910d16Sjeremylt /// @endcond
27415910d16Sjeremylt 
2757a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2767a982d89SJeremy L. Thompson /// CeedElemRestriction Public API
2777a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2787a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser
279d7b241e6Sjeremylt /// @{
280d7b241e6Sjeremylt 
2817a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend
2827a982d89SJeremy L. Thompson const CeedInt CEED_STRIDES_BACKEND[3] = {};
2837a982d89SJeremy L. Thompson 
2844cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user
2857a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE =
2867a982d89SJeremy L. Thompson   &ceed_elemrestriction_none;
2877a982d89SJeremy L. Thompson 
288d7b241e6Sjeremylt /**
289b11c1e72Sjeremylt   @brief Create a CeedElemRestriction
290d7b241e6Sjeremylt 
291b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
292d979a051Sjeremylt   @param nelem      Number of elements described in the @a offsets array
293b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
294b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
29595bb1877Svaleriabarra                       (1 for scalar fields)
296d979a051Sjeremylt   @param compstride Stride between components for the same L-vector "node".
29795e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
29895e93d34SJeremy L Thompson                       the L-vector at index
2992db7ab32SJeremy L Thompson                         offsets[i + k*elemsize] + j*compstride.
300d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
301d979a051Sjeremylt                       the elements and fields given by this restriction.
302d979a051Sjeremylt   @param mtype      Memory type of the @a offsets array, see CeedMemType
303d979a051Sjeremylt   @param cmode      Copy mode for the @a offsets array, see CeedCopyMode
304d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
305d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
3068795c945Sjeremylt                       for the unknowns corresponding to element i, where
307d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
308d979a051Sjeremylt                       [0, @a lsize - 1].
3094ce2993fSjeremylt   @param[out] rstr  Address of the variable where the newly created
310b11c1e72Sjeremylt                       CeedElemRestriction will be stored
311d7b241e6Sjeremylt 
312b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
313dfdf5a53Sjeremylt 
3147a982d89SJeremy L. Thompson   @ref User
315b11c1e72Sjeremylt **/
316d979a051Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem, CeedInt elemsize,
317d979a051Sjeremylt                               CeedInt ncomp, CeedInt compstride,
318d979a051Sjeremylt                               CeedInt lsize, CeedMemType mtype,
319d979a051Sjeremylt                               CeedCopyMode cmode, const CeedInt *offsets,
3204ce2993fSjeremylt                               CeedElemRestriction *rstr) {
321d7b241e6Sjeremylt   int ierr;
322d7b241e6Sjeremylt 
3235fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
3245fe0d4faSjeremylt     Ceed delegate;
325aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
326aefd8378Sjeremylt     CeedChk(ierr);
3275fe0d4faSjeremylt 
3285fe0d4faSjeremylt     if (!delegate)
329c042f62fSJeremy L Thompson       // LCOV_EXCL_START
330d7b241e6Sjeremylt       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
331c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3325fe0d4faSjeremylt 
333d979a051Sjeremylt     ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize, ncomp,
334d979a051Sjeremylt                                      compstride, lsize, mtype, cmode,
335d979a051Sjeremylt                                      offsets, rstr); CeedChk(ierr);
3365fe0d4faSjeremylt     return 0;
3375fe0d4faSjeremylt   }
3385fe0d4faSjeremylt 
3394ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
3404ce2993fSjeremylt   (*rstr)->ceed = ceed;
341d7b241e6Sjeremylt   ceed->refcount++;
3424ce2993fSjeremylt   (*rstr)->refcount = 1;
3434ce2993fSjeremylt   (*rstr)->nelem = nelem;
3444ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
3454ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
346d979a051Sjeremylt   (*rstr)->compstride = compstride;
347d979a051Sjeremylt   (*rstr)->lsize = lsize;
3484ce2993fSjeremylt   (*rstr)->nblk = nelem;
3494ce2993fSjeremylt   (*rstr)->blksize = 1;
350d979a051Sjeremylt   ierr = ceed->ElemRestrictionCreate(mtype, cmode, offsets, *rstr);
351d979a051Sjeremylt   CeedChk(ierr);
352d7b241e6Sjeremylt   return 0;
353d7b241e6Sjeremylt }
354d7b241e6Sjeremylt 
355d7b241e6Sjeremylt /**
3567509a596Sjeremylt   @brief Create a strided CeedElemRestriction
357d7b241e6Sjeremylt 
358b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
3597509a596Sjeremylt   @param nelem      Number of elements described by the restriction
360b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
36195e93d34SJeremy L Thompson   @param ncomp      Number of field components per interpolation "node"
36295bb1877Svaleriabarra                       (1 for scalar fields)
363d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
364d979a051Sjeremylt                       the elements and fields given by this restriction.
3657509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
36695e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
36795e93d34SJeremy L Thompson                       the L-vector at index
36895e93d34SJeremy L Thompson                         i*strides[0] + j*strides[1] + k*strides[2].
36995e93d34SJeremy L Thompson                       @a CEED_STRIDES_BACKEND may be used with vectors created
37095e93d34SJeremy L Thompson                       by a Ceed backend.
3714ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
372b11c1e72Sjeremylt                       CeedElemRestriction will be stored
373d7b241e6Sjeremylt 
374b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
375dfdf5a53Sjeremylt 
3767a982d89SJeremy L. Thompson   @ref User
377b11c1e72Sjeremylt **/
3787509a596Sjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt nelem, CeedInt elemsize,
379d979a051Sjeremylt                                      CeedInt ncomp, CeedInt lsize,
3808621c6c6SJeremy L Thompson                                      const CeedInt strides[3],
381f90c8643Sjeremylt                                      CeedElemRestriction *rstr) {
382d7b241e6Sjeremylt   int ierr;
383d7b241e6Sjeremylt 
3845fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
3855fe0d4faSjeremylt     Ceed delegate;
386aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
387aefd8378Sjeremylt     CeedChk(ierr);
3885fe0d4faSjeremylt 
3895fe0d4faSjeremylt     if (!delegate)
390c042f62fSJeremy L Thompson       // LCOV_EXCL_START
3911d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
392c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3935fe0d4faSjeremylt 
394d979a051Sjeremylt     ierr = CeedElemRestrictionCreateStrided(delegate, nelem, elemsize, ncomp,
395d979a051Sjeremylt                                             lsize, strides, rstr);
396d979a051Sjeremylt     CeedChk(ierr);
3975fe0d4faSjeremylt     return 0;
3985fe0d4faSjeremylt   }
3995fe0d4faSjeremylt 
4004ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
4014ce2993fSjeremylt   (*rstr)->ceed = ceed;
402d7b241e6Sjeremylt   ceed->refcount++;
4034ce2993fSjeremylt   (*rstr)->refcount = 1;
4044ce2993fSjeremylt   (*rstr)->nelem = nelem;
4054ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
4064ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
407d979a051Sjeremylt   (*rstr)->lsize = lsize;
4084ce2993fSjeremylt   (*rstr)->nblk = nelem;
4094ce2993fSjeremylt   (*rstr)->blksize = 1;
4107509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
4117509a596Sjeremylt   for (int i = 0; i<3; i++)
4127509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
4131dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
4141dfeef1dSjeremylt                                      *rstr);
4154b8bea3bSJed Brown   CeedChk(ierr);
416d7b241e6Sjeremylt   return 0;
417d7b241e6Sjeremylt }
418d7b241e6Sjeremylt 
419d7b241e6Sjeremylt /**
420b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
421d7b241e6Sjeremylt 
422d7b241e6Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created.
423d979a051Sjeremylt   @param nelem      Number of elements described in the @a offsets array.
424b11c1e72Sjeremylt   @param elemsize   Size (number of unknowns) per element
425b11c1e72Sjeremylt   @param blksize    Number of elements in a block
42695bb1877Svaleriabarra   @param ncomp      Number of field components per interpolation node
42795bb1877Svaleriabarra                       (1 for scalar fields)
428d979a051Sjeremylt   @param compstride Stride between components for the same L-vector "node".
42995e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
43095e93d34SJeremy L Thompson                       the L-vector at index
4312db7ab32SJeremy L Thompson                         offsets[i + k*elemsize] + j*compstride.
432d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
433d979a051Sjeremylt                       the elements and fields given by this restriction.
434d979a051Sjeremylt   @param mtype      Memory type of the @a offsets array, see CeedMemType
435d979a051Sjeremylt   @param cmode      Copy mode for the @a offsets array, see CeedCopyMode
436d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
437d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
4388795c945Sjeremylt                       for the unknowns corresponding to element i, where
439d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
440d979a051Sjeremylt                       [0, @a lsize - 1]. The backend will permute and pad this
4418795c945Sjeremylt                       array to the desired ordering for the blocksize, which is
4428795c945Sjeremylt                       typically given by the backend. The default reordering is
4438795c945Sjeremylt                       to interlace elements.
4444ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
445b11c1e72Sjeremylt                       CeedElemRestriction will be stored
446d7b241e6Sjeremylt 
447b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
448dfdf5a53Sjeremylt 
4497a982d89SJeremy L. Thompson   @ref Backend
450b11c1e72Sjeremylt  **/
451d979a051Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize,
452d979a051Sjeremylt                                      CeedInt blksize, CeedInt ncomp,
453d979a051Sjeremylt                                      CeedInt compstride, CeedInt lsize,
454d979a051Sjeremylt                                      CeedMemType mtype, CeedCopyMode cmode,
455d979a051Sjeremylt                                      const CeedInt *offsets,
4564ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
457d7b241e6Sjeremylt   int ierr;
458d979a051Sjeremylt   CeedInt *blkoffsets;
459d7b241e6Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
460d7b241e6Sjeremylt 
4615fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
4625fe0d4faSjeremylt     Ceed delegate;
463aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
464aefd8378Sjeremylt     CeedChk(ierr);
4655fe0d4faSjeremylt 
4665fe0d4faSjeremylt     if (!delegate)
467c042f62fSJeremy L Thompson       // LCOV_EXCL_START
4681d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support "
4691d102b48SJeremy L Thompson                        "ElemRestrictionCreateBlocked");
470c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
4715fe0d4faSjeremylt 
472d979a051Sjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize, blksize,
473d979a051Sjeremylt                                             ncomp, compstride, lsize, mtype,
474d979a051Sjeremylt                                             cmode, offsets, rstr);
475d979a051Sjeremylt     CeedChk(ierr);
4765fe0d4faSjeremylt     return 0;
4775fe0d4faSjeremylt   }
478d7b241e6Sjeremylt 
4794ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
480d7b241e6Sjeremylt 
481d979a051Sjeremylt   ierr = CeedCalloc(nblk*blksize*elemsize, &blkoffsets); CeedChk(ierr);
482d979a051Sjeremylt   ierr = CeedPermutePadOffsets(offsets, blkoffsets, nblk, nelem, blksize,
4834b8bea3bSJed Brown                                elemsize);
484dfdf5a53Sjeremylt   CeedChk(ierr);
485d7b241e6Sjeremylt 
4864ce2993fSjeremylt   (*rstr)->ceed = ceed;
487d7b241e6Sjeremylt   ceed->refcount++;
4884ce2993fSjeremylt   (*rstr)->refcount = 1;
4894ce2993fSjeremylt   (*rstr)->nelem = nelem;
4904ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
4914ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
492d979a051Sjeremylt   (*rstr)->compstride = compstride;
493d979a051Sjeremylt   (*rstr)->lsize = lsize;
4944ce2993fSjeremylt   (*rstr)->nblk = nblk;
4954ce2993fSjeremylt   (*rstr)->blksize = blksize;
496667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
497d979a051Sjeremylt          (const CeedInt *) blkoffsets, *rstr); CeedChk(ierr);
498d7b241e6Sjeremylt 
4991d102b48SJeremy L Thompson   if (cmode == CEED_OWN_POINTER) {
500d979a051Sjeremylt     ierr = CeedFree(&offsets); CeedChk(ierr);
5011d102b48SJeremy L Thompson   }
502d7b241e6Sjeremylt 
503d7b241e6Sjeremylt   return 0;
504d7b241e6Sjeremylt }
505d7b241e6Sjeremylt 
506b11c1e72Sjeremylt /**
5077509a596Sjeremylt   @brief Create a blocked strided CeedElemRestriction
5087509a596Sjeremylt 
5097509a596Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
5107509a596Sjeremylt   @param nelem      Number of elements described by the restriction
5117509a596Sjeremylt   @param elemsize   Size (number of "nodes") per element
5127509a596Sjeremylt   @param blksize    Number of elements in a block
5137509a596Sjeremylt   @param ncomp      Number of field components per interpolation node
5147509a596Sjeremylt                       (1 for scalar fields)
515d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
516d979a051Sjeremylt                       the elements and fields given by this restriction.
5177509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
51895e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
51995e93d34SJeremy L Thompson                       the L-vector at index
52095e93d34SJeremy L Thompson                         i*strides[0] + j*strides[1] + k*strides[2].
52195e93d34SJeremy L Thompson                       @a CEED_STRIDES_BACKEND may be used with vectors created
52295e93d34SJeremy L Thompson                       by a Ceed backend.
5237509a596Sjeremylt   @param rstr       Address of the variable where the newly created
5247509a596Sjeremylt                       CeedElemRestriction will be stored
5257509a596Sjeremylt 
5267509a596Sjeremylt   @return An error code: 0 - success, otherwise - failure
5277509a596Sjeremylt 
5287a982d89SJeremy L. Thompson   @ref User
5297509a596Sjeremylt **/
5307509a596Sjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt nelem,
531d979a051Sjeremylt     CeedInt elemsize, CeedInt blksize, CeedInt ncomp, CeedInt lsize,
5328621c6c6SJeremy L Thompson     const CeedInt strides[3], CeedElemRestriction *rstr) {
5337509a596Sjeremylt   int ierr;
5347509a596Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
5357509a596Sjeremylt 
5367509a596Sjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
5377509a596Sjeremylt     Ceed delegate;
5387509a596Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
5397509a596Sjeremylt     CeedChk(ierr);
5407509a596Sjeremylt 
5417509a596Sjeremylt     if (!delegate)
5427509a596Sjeremylt       // LCOV_EXCL_START
5437509a596Sjeremylt       return CeedError(ceed, 1, "Backend does not support "
5447509a596Sjeremylt                        "ElemRestrictionCreateBlocked");
5457509a596Sjeremylt     // LCOV_EXCL_STOP
5467509a596Sjeremylt 
5477509a596Sjeremylt     ierr = CeedElemRestrictionCreateBlockedStrided(delegate, nelem, elemsize,
548d979a051Sjeremylt            blksize, ncomp, lsize, strides, rstr);
5497509a596Sjeremylt     CeedChk(ierr);
5507509a596Sjeremylt     return 0;
5517509a596Sjeremylt   }
5527509a596Sjeremylt 
5537509a596Sjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
5547509a596Sjeremylt 
5557509a596Sjeremylt   (*rstr)->ceed = ceed;
5567509a596Sjeremylt   ceed->refcount++;
5577509a596Sjeremylt   (*rstr)->refcount = 1;
5587509a596Sjeremylt   (*rstr)->nelem = nelem;
5597509a596Sjeremylt   (*rstr)->elemsize = elemsize;
5607509a596Sjeremylt   (*rstr)->ncomp = ncomp;
561d979a051Sjeremylt   (*rstr)->lsize = lsize;
5627509a596Sjeremylt   (*rstr)->nblk = nblk;
5637509a596Sjeremylt   (*rstr)->blksize = blksize;
5647509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
5657509a596Sjeremylt   for (int i = 0; i<3; i++)
5667509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
5677509a596Sjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
5687509a596Sjeremylt          NULL, *rstr); CeedChk(ierr);
5697509a596Sjeremylt 
5707509a596Sjeremylt   return 0;
5717509a596Sjeremylt }
5727509a596Sjeremylt 
5737509a596Sjeremylt /**
574b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
575b11c1e72Sjeremylt 
5764ce2993fSjeremylt   @param rstr  CeedElemRestriction
577b11c1e72Sjeremylt   @param lvec  The address of the L-vector to be created, or NULL
578b11c1e72Sjeremylt   @param evec  The address of the E-vector to be created, or NULL
579b11c1e72Sjeremylt 
580b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
581dfdf5a53Sjeremylt 
5827a982d89SJeremy L. Thompson   @ref User
583b11c1e72Sjeremylt **/
5844ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec,
585d7b241e6Sjeremylt                                     CeedVector *evec) {
586d7b241e6Sjeremylt   int ierr;
587d7b241e6Sjeremylt   CeedInt n, m;
588d979a051Sjeremylt   m = rstr->lsize;
5894ce2993fSjeremylt   n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
590d7b241e6Sjeremylt   if (lvec) {
5914ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr);
592d7b241e6Sjeremylt   }
593d7b241e6Sjeremylt   if (evec) {
5944ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr);
595d7b241e6Sjeremylt   }
596d7b241e6Sjeremylt   return 0;
597d7b241e6Sjeremylt }
598d7b241e6Sjeremylt 
599d7b241e6Sjeremylt /**
600d9e1f99aSValeria Barra   @brief Restrict an L-vector to an E-vector or apply its transpose
601d7b241e6Sjeremylt 
6024ce2993fSjeremylt   @param rstr    CeedElemRestriction
603d7b241e6Sjeremylt   @param tmode   Apply restriction or transpose
6044cc79fe7SJed Brown   @param u       Input vector (of size @a lsize when tmode=@ref CEED_NOTRANSPOSE)
605a8d32208Sjeremylt   @param ru      Output vector (of shape [@a nelem * @a elemsize] when
6064cc79fe7SJed Brown                    tmode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
6077aaeacdcSjeremylt                    by the backend.
6084cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
609b11c1e72Sjeremylt 
610b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
611dfdf5a53Sjeremylt 
6127a982d89SJeremy L. Thompson   @ref User
613b11c1e72Sjeremylt **/
6144ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode,
615a8d32208Sjeremylt                              CeedVector u, CeedVector ru,
616a8d32208Sjeremylt                              CeedRequest *request) {
617d7b241e6Sjeremylt   CeedInt m,n;
618d7b241e6Sjeremylt   int ierr;
619d7b241e6Sjeremylt 
620d7b241e6Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
6214ce2993fSjeremylt     m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
622d979a051Sjeremylt     n = rstr->lsize;
623d7b241e6Sjeremylt   } else {
624d979a051Sjeremylt     m = rstr->lsize;
6254ce2993fSjeremylt     n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
626d7b241e6Sjeremylt   }
627d7b241e6Sjeremylt   if (n != u->length)
628c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6291d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
6301d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
631c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
632a8d32208Sjeremylt   if (m != ru->length)
633c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6341d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
635a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
636c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
637074cb416Sjeremylt   ierr = rstr->Apply(rstr, tmode, u, ru, request); CeedChk(ierr);
638d7b241e6Sjeremylt 
639d7b241e6Sjeremylt   return 0;
640d7b241e6Sjeremylt }
641d7b241e6Sjeremylt 
642d7b241e6Sjeremylt /**
643d9e1f99aSValeria Barra   @brief Restrict an L-vector to a block of an E-vector or apply its transpose
644be9261b7Sjeremylt 
645be9261b7Sjeremylt   @param rstr    CeedElemRestriction
6461f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
6471f37b403Sjeremylt                    elements [0 : blksize] and block=3 will handle elements
6481f37b403Sjeremylt                    [3*blksize : 4*blksize]
649be9261b7Sjeremylt   @param tmode   Apply restriction or transpose
6504cc79fe7SJed Brown   @param u       Input vector (of size @a lsize when tmode=@ref CEED_NOTRANSPOSE)
651a8d32208Sjeremylt   @param ru      Output vector (of shape [@a blksize * @a elemsize] when
6524cc79fe7SJed Brown                    tmode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
6537aaeacdcSjeremylt                    by the backend.
6544cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
655be9261b7Sjeremylt 
656be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
657be9261b7Sjeremylt 
6587a982d89SJeremy L. Thompson   @ref Backend
659be9261b7Sjeremylt **/
660be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
661a8d32208Sjeremylt                                   CeedTransposeMode tmode, CeedVector u,
662a8d32208Sjeremylt                                   CeedVector ru, CeedRequest *request) {
663be9261b7Sjeremylt   CeedInt m,n;
664be9261b7Sjeremylt   int ierr;
665be9261b7Sjeremylt 
666be9261b7Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
667be9261b7Sjeremylt     m = rstr->blksize * rstr->elemsize * rstr->ncomp;
668d979a051Sjeremylt     n = rstr->lsize;
669be9261b7Sjeremylt   } else {
670d979a051Sjeremylt     m = rstr->lsize;
671be9261b7Sjeremylt     n = rstr->blksize * rstr->elemsize * rstr->ncomp;
672be9261b7Sjeremylt   }
673be9261b7Sjeremylt   if (n != u->length)
674c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6751d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
6761d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
677c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
678a8d32208Sjeremylt   if (m != ru->length)
679c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6801d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
681a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
682c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
683be9261b7Sjeremylt   if (rstr->blksize*block > rstr->nelem)
684c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6851d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > "
6861d102b48SJeremy L Thompson                      "total elements %d", block, rstr->blksize*block,
6871d102b48SJeremy L Thompson                      rstr->nelem);
688c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
689074cb416Sjeremylt   ierr = rstr->ApplyBlock(rstr, block, tmode, u, ru, request);
690be9261b7Sjeremylt   CeedChk(ierr);
691be9261b7Sjeremylt 
692be9261b7Sjeremylt   return 0;
693be9261b7Sjeremylt }
694be9261b7Sjeremylt 
695be9261b7Sjeremylt /**
696d979a051Sjeremylt   @brief Get the L-vector component stride
697a681ae63Sjeremylt 
698a681ae63Sjeremylt   @param rstr             CeedElemRestriction
699d979a051Sjeremylt   @param[out] compstride  Variable to store component stride
700a681ae63Sjeremylt 
701a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
702a681ae63Sjeremylt 
703a681ae63Sjeremylt   @ref Backend
704a681ae63Sjeremylt **/
705d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr,
706d979a051Sjeremylt                                      CeedInt *compstride) {
707d979a051Sjeremylt   *compstride = rstr->compstride;
708a681ae63Sjeremylt   return 0;
709a681ae63Sjeremylt }
710a681ae63Sjeremylt 
711a681ae63Sjeremylt /**
712a681ae63Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
713a681ae63Sjeremylt 
714a681ae63Sjeremylt   @param rstr             CeedElemRestriction
715a681ae63Sjeremylt   @param[out] numelem     Variable to store number of elements
716a681ae63Sjeremylt 
717a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
718a681ae63Sjeremylt 
719a681ae63Sjeremylt   @ref Backend
720a681ae63Sjeremylt **/
721a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
722a681ae63Sjeremylt                                       CeedInt *numelem) {
723a681ae63Sjeremylt   *numelem = rstr->nelem;
724a681ae63Sjeremylt   return 0;
725a681ae63Sjeremylt }
726a681ae63Sjeremylt 
727a681ae63Sjeremylt /**
728a681ae63Sjeremylt   @brief Get the size of elements in the CeedElemRestriction
729a681ae63Sjeremylt 
730a681ae63Sjeremylt   @param rstr             CeedElemRestriction
731a681ae63Sjeremylt   @param[out] elemsize    Variable to store size of elements
732a681ae63Sjeremylt 
733a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
734a681ae63Sjeremylt 
735a681ae63Sjeremylt   @ref Backend
736a681ae63Sjeremylt **/
737a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
738a681ae63Sjeremylt                                       CeedInt *elemsize) {
739a681ae63Sjeremylt   *elemsize = rstr->elemsize;
740a681ae63Sjeremylt   return 0;
741a681ae63Sjeremylt }
742a681ae63Sjeremylt 
743a681ae63Sjeremylt /**
744d979a051Sjeremylt   @brief Get the size of the l-vector for a CeedElemRestriction
745a681ae63Sjeremylt 
746a681ae63Sjeremylt   @param rstr             CeedElemRestriction
747a681ae63Sjeremylt   @param[out] numnodes    Variable to store number of nodes
748a681ae63Sjeremylt 
749a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
750a681ae63Sjeremylt 
751a681ae63Sjeremylt   @ref Backend
752a681ae63Sjeremylt **/
753d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr,
754d979a051Sjeremylt                                       CeedInt *lsize) {
755d979a051Sjeremylt   *lsize = rstr->lsize;
756a681ae63Sjeremylt   return 0;
757a681ae63Sjeremylt }
758a681ae63Sjeremylt 
759a681ae63Sjeremylt /**
760a681ae63Sjeremylt   @brief Get the number of components in the elements of a
761a681ae63Sjeremylt          CeedElemRestriction
762a681ae63Sjeremylt 
763a681ae63Sjeremylt   @param rstr             CeedElemRestriction
764a681ae63Sjeremylt   @param[out] numcomp     Variable to store number of components
765a681ae63Sjeremylt 
766a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
767a681ae63Sjeremylt 
768a681ae63Sjeremylt   @ref Backend
769a681ae63Sjeremylt **/
770a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
771a681ae63Sjeremylt                                         CeedInt *numcomp) {
772a681ae63Sjeremylt   *numcomp = rstr->ncomp;
773a681ae63Sjeremylt   return 0;
774a681ae63Sjeremylt }
775a681ae63Sjeremylt 
776a681ae63Sjeremylt /**
777a681ae63Sjeremylt   @brief Get the number of blocks in a CeedElemRestriction
778a681ae63Sjeremylt 
779a681ae63Sjeremylt   @param rstr             CeedElemRestriction
780a681ae63Sjeremylt   @param[out] numblock    Variable to store number of blocks
781a681ae63Sjeremylt 
782a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
783a681ae63Sjeremylt 
784a681ae63Sjeremylt   @ref Backend
785a681ae63Sjeremylt **/
786a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
787a681ae63Sjeremylt                                     CeedInt *numblock) {
788a681ae63Sjeremylt   *numblock = rstr->nblk;
789a681ae63Sjeremylt   return 0;
790a681ae63Sjeremylt }
791a681ae63Sjeremylt 
792a681ae63Sjeremylt /**
793a681ae63Sjeremylt   @brief Get the size of blocks in the CeedElemRestriction
794a681ae63Sjeremylt 
795a681ae63Sjeremylt   @param rstr             CeedElemRestriction
796a681ae63Sjeremylt   @param[out] blksize     Variable to store size of blocks
797a681ae63Sjeremylt 
798a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
799a681ae63Sjeremylt 
800a681ae63Sjeremylt   @ref Backend
801a681ae63Sjeremylt **/
802a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
803a681ae63Sjeremylt                                     CeedInt *blksize) {
804a681ae63Sjeremylt   *blksize = rstr->blksize;
805a681ae63Sjeremylt   return 0;
806a681ae63Sjeremylt }
807a681ae63Sjeremylt 
808a681ae63Sjeremylt /**
809d9e1f99aSValeria Barra   @brief Get the multiplicity of nodes in a CeedElemRestriction
8101469ee4dSjeremylt 
8111469ee4dSjeremylt   @param rstr             CeedElemRestriction
812d979a051Sjeremylt   @param[out] mult        Vector to store multiplicity (of size lsize)
8131469ee4dSjeremylt 
8141469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
8151469ee4dSjeremylt 
8167a982d89SJeremy L. Thompson   @ref User
8171469ee4dSjeremylt **/
8181469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
8191469ee4dSjeremylt                                        CeedVector mult) {
8201469ee4dSjeremylt   int ierr;
8211469ee4dSjeremylt   CeedVector evec;
8221469ee4dSjeremylt 
8231469ee4dSjeremylt   // Create and set evec
8241469ee4dSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr);
8251469ee4dSjeremylt   ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr);
826fa9eac48SJed Brown   ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr);
8271469ee4dSjeremylt 
8281469ee4dSjeremylt   // Apply to get multiplicity
829a8d32208Sjeremylt   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult,
830efc78312Sjeremylt                                   CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
8311469ee4dSjeremylt 
8321469ee4dSjeremylt   // Cleanup
8331469ee4dSjeremylt   ierr = CeedVectorDestroy(&evec); CeedChk(ierr);
8341469ee4dSjeremylt 
8351469ee4dSjeremylt   return 0;
8361469ee4dSjeremylt }
8371469ee4dSjeremylt 
8381469ee4dSjeremylt /**
839f02ca4a2SJed Brown   @brief View a CeedElemRestriction
840f02ca4a2SJed Brown 
841f02ca4a2SJed Brown   @param[in] rstr    CeedElemRestriction to view
842f02ca4a2SJed Brown   @param[in] stream  Stream to write; typically stdout/stderr or a file
843f02ca4a2SJed Brown 
844f02ca4a2SJed Brown   @return Error code: 0 - success, otherwise - failure
845f02ca4a2SJed Brown 
8467a982d89SJeremy L. Thompson   @ref User
847f02ca4a2SJed Brown **/
848f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
8497509a596Sjeremylt   char stridesstr[500];
8507509a596Sjeremylt   if (rstr->strides)
8517509a596Sjeremylt     sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1],
8527509a596Sjeremylt             rstr->strides[2]);
853d979a051Sjeremylt   else
854d979a051Sjeremylt     sprintf(stridesstr, "%d", rstr->compstride);
8557509a596Sjeremylt 
8560036de2cSjeremylt   fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d "
8570036de2cSjeremylt           "nodes each and %s %s\n", rstr->blksize > 1 ? "Blocked " : "",
858d979a051Sjeremylt           rstr->lsize, rstr->ncomp, rstr->nelem, rstr->elemsize,
859d979a051Sjeremylt           rstr->strides ? "strides" : "component stride", stridesstr);
860f02ca4a2SJed Brown   return 0;
861f02ca4a2SJed Brown }
862f02ca4a2SJed Brown 
863f02ca4a2SJed Brown /**
864b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
865b11c1e72Sjeremylt 
8664ce2993fSjeremylt   @param rstr  CeedElemRestriction to destroy
867b11c1e72Sjeremylt 
868b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
869dfdf5a53Sjeremylt 
8707a982d89SJeremy L. Thompson   @ref User
871b11c1e72Sjeremylt **/
8724ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
873d7b241e6Sjeremylt   int ierr;
874d7b241e6Sjeremylt 
875752c3701SJeremy L Thompson   if (!*rstr || --(*rstr)->refcount > 0) return 0;
876430758c8SJeremy L Thompson   if ((*rstr)->numreaders)
877430758c8SJeremy L Thompson     return CeedError((*rstr)->ceed, 1, "Cannot destroy CeedElemRestriction, "
878430758c8SJeremy L Thompson                      "a process has read access to the offset data");
8794ce2993fSjeremylt   if ((*rstr)->Destroy) {
8804ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
881d7b241e6Sjeremylt   }
8827509a596Sjeremylt   ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr);
8834ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
8844ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
885d7b241e6Sjeremylt   return 0;
886d7b241e6Sjeremylt }
887d7b241e6Sjeremylt 
888d7b241e6Sjeremylt /// @}
889