xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-elemrestriction.c (revision 752c3701a992135134df075f4ef18abc790b3495)
1d7b241e6Sjeremylt // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2d7b241e6Sjeremylt // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3d7b241e6Sjeremylt // reserved. See files LICENSE and NOTICE for details.
4d7b241e6Sjeremylt //
5d7b241e6Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software
6d7b241e6Sjeremylt // libraries and APIs for efficient high-order finite element and spectral
7d7b241e6Sjeremylt // element discretizations for exascale applications. For more information and
8d7b241e6Sjeremylt // source code availability see http://github.com/ceed.
9d7b241e6Sjeremylt //
10d7b241e6Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11d7b241e6Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office
12d7b241e6Sjeremylt // of Science and the National Nuclear Security Administration) responsible for
13d7b241e6Sjeremylt // the planning and preparation of a capable exascale ecosystem, including
14d7b241e6Sjeremylt // software, applications, hardware, advanced system engineering and early
15d7b241e6Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative.
16d7b241e6Sjeremylt 
17d7b241e6Sjeremylt #include <ceed-impl.h>
18d863ab9bSjeremylt #include <ceed-backend.h>
19d7b241e6Sjeremylt 
207a982d89SJeremy L. Thompson /// @file
217a982d89SJeremy L. Thompson /// Implementation of CeedElemRestriction interfaces
227a982d89SJeremy L. Thompson 
237a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
247a982d89SJeremy L. Thompson /// CeedElemRestriction Library Internal Functions
257a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
267a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionDeveloper
277a982d89SJeremy L. Thompson /// @{
287a982d89SJeremy L. Thompson 
297a982d89SJeremy L. Thompson /**
30d979a051Sjeremylt   @brief Permute and pad offsets for a blocked restriction
317a982d89SJeremy L. Thompson 
32d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
33d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
347a982d89SJeremy L. Thompson                       for the unknowns corresponding to element i, where
35d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
36d979a051Sjeremylt                       [0, @a lsize - 1].
37d979a051Sjeremylt   @param blkoffsets Array of permuted and padded offsets of
387a982d89SJeremy L. Thompson                       shape [@a nblk, @a elemsize, @a blksize].
397a982d89SJeremy L. Thompson   @param nblk       Number of blocks
407a982d89SJeremy L. Thompson   @param nelem      Number of elements
417a982d89SJeremy L. Thompson   @param blksize    Number of elements in a block
427a982d89SJeremy L. Thompson   @param elemsize   Size of each element
437a982d89SJeremy L. Thompson 
447a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
457a982d89SJeremy L. Thompson 
467a982d89SJeremy L. Thompson   @ref Utility
477a982d89SJeremy L. Thompson **/
48d979a051Sjeremylt int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blkoffsets,
497a982d89SJeremy L. Thompson                           CeedInt nblk, CeedInt nelem, CeedInt blksize,
507a982d89SJeremy L. Thompson                           CeedInt elemsize) {
517a982d89SJeremy L. Thompson   for (CeedInt e = 0; e < nblk*blksize; e+=blksize)
527a982d89SJeremy L. Thompson     for (int j = 0; j < blksize; j++)
537a982d89SJeremy L. Thompson       for (int k = 0; k < elemsize; k++)
54d979a051Sjeremylt         blkoffsets[e*elemsize + k*blksize + j]
55d979a051Sjeremylt           = offsets[CeedIntMin(e+j,nelem-1)*elemsize + k];
567a982d89SJeremy L. Thompson   return 0;
577a982d89SJeremy L. Thompson }
587a982d89SJeremy L. Thompson 
597a982d89SJeremy L. Thompson /// @}
607a982d89SJeremy L. Thompson 
617a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
627a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API
637a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
647a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend
657a982d89SJeremy L. Thompson /// @{
667a982d89SJeremy L. Thompson 
677a982d89SJeremy L. Thompson /**
687a982d89SJeremy L. Thompson   @brief Get the Ceed associated with a CeedElemRestriction
697a982d89SJeremy L. Thompson 
707a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
717a982d89SJeremy L. Thompson   @param[out] ceed        Variable to store Ceed
727a982d89SJeremy L. Thompson 
737a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
747a982d89SJeremy L. Thompson 
757a982d89SJeremy L. Thompson   @ref Backend
767a982d89SJeremy L. Thompson **/
777a982d89SJeremy L. Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) {
787a982d89SJeremy L. Thompson   *ceed = rstr->ceed;
797a982d89SJeremy L. Thompson   return 0;
807a982d89SJeremy L. Thompson }
817a982d89SJeremy L. Thompson 
827a982d89SJeremy L. Thompson /**
83a681ae63Sjeremylt 
84a681ae63Sjeremylt   @brief Get the strides of a strided CeedElemRestriction
857a982d89SJeremy L. Thompson 
867a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
87a681ae63Sjeremylt   @param[out] strides     Variable to store strides array
887a982d89SJeremy L. Thompson 
897a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
907a982d89SJeremy L. Thompson 
917a982d89SJeremy L. Thompson   @ref Backend
927a982d89SJeremy L. Thompson **/
93a681ae63Sjeremylt int CeedElemRestrictionGetStrides(CeedElemRestriction rstr,
94a681ae63Sjeremylt                                   CeedInt (*strides)[3]) {
95a681ae63Sjeremylt   if (!rstr->strides)
96a681ae63Sjeremylt     // LCOV_EXCL_START
97a681ae63Sjeremylt     return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data");
98a681ae63Sjeremylt   // LCOV_EXCL_STOP
99a681ae63Sjeremylt 
100a681ae63Sjeremylt   for (int i = 0; i<3; i++)
101a681ae63Sjeremylt     (*strides)[i] = rstr->strides[i];
1027a982d89SJeremy L. Thompson   return 0;
1037a982d89SJeremy L. Thompson }
1047a982d89SJeremy L. Thompson 
1057a982d89SJeremy L. Thompson /**
106bd33150aSjeremylt   @brief Get read-only access to a CeedElemRestriction offsets array by memtype
107bd33150aSjeremylt 
108bd33150aSjeremylt   @param rstr         CeedElemRestriction to retrieve offsets
109bd33150aSjeremylt   @param mtype        Memory type on which to access the array.  If the backend
110bd33150aSjeremylt                         uses a different memory type, this will perform a copy
111bd33150aSjeremylt                         (possibly cached).
112bd33150aSjeremylt   @param[out] offsets Array on memory type mtype
113bd33150aSjeremylt 
114bd33150aSjeremylt   @return An error code: 0 - success, otherwise - failure
115bd33150aSjeremylt 
116bd33150aSjeremylt   @ref User
117bd33150aSjeremylt **/
118bd33150aSjeremylt int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mtype,
119bd33150aSjeremylt                                   const CeedInt **offsets) {
120bd33150aSjeremylt   int ierr;
121bd33150aSjeremylt 
122bd33150aSjeremylt   if (!rstr->GetOffsets)
123bd33150aSjeremylt     // LCOV_EXCL_START
124bd33150aSjeremylt     return CeedError(rstr->ceed, 1, "Backend does not support GetOffsets");
125bd33150aSjeremylt   // LCOV_EXCL_STOP
126bd33150aSjeremylt 
127bd33150aSjeremylt   ierr = rstr->GetOffsets(rstr, mtype, offsets); CeedChk(ierr);
128430758c8SJeremy L Thompson   rstr->numreaders++;
129430758c8SJeremy L Thompson   return 0;
130430758c8SJeremy L Thompson }
131430758c8SJeremy L Thompson 
132430758c8SJeremy L Thompson /**
133430758c8SJeremy L Thompson   @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets()
134430758c8SJeremy L Thompson 
135430758c8SJeremy L Thompson   @param rstr    CeedElemRestriction to restore
136430758c8SJeremy L Thompson   @param offsets Array of offset data
137430758c8SJeremy L Thompson 
138430758c8SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
139430758c8SJeremy L Thompson 
140430758c8SJeremy L Thompson   @ref User
141430758c8SJeremy L Thompson **/
142430758c8SJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr,
143430758c8SJeremy L Thompson                                       const CeedInt **offsets) {
144430758c8SJeremy L Thompson   *offsets = NULL;
145430758c8SJeremy L Thompson   rstr->numreaders--;
146bd33150aSjeremylt   return 0;
147bd33150aSjeremylt }
148bd33150aSjeremylt 
149bd33150aSjeremylt /**
1503ac43b2cSJeremy L Thompson   @brief Get the strided status of a CeedElemRestriction
1513ac43b2cSJeremy L Thompson 
1523ac43b2cSJeremy L Thompson   @param rstr             CeedElemRestriction
153fd364f38SJeremy L Thompson   @param[out] isstrided   Variable to store strided status, 1 if strided else 0
1543ac43b2cSJeremy L Thompson 
1553ac43b2cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1563ac43b2cSJeremy L Thompson 
1573ac43b2cSJeremy L Thompson   @ref Backend
1583ac43b2cSJeremy L Thompson **/
159fd364f38SJeremy L Thompson int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *isstrided) {
160fd364f38SJeremy L Thompson   *isstrided = rstr->strides ? 1 : 0;
1613ac43b2cSJeremy L Thompson   return 0;
1623ac43b2cSJeremy L Thompson }
1633ac43b2cSJeremy L Thompson 
1643ac43b2cSJeremy L Thompson /**
165a681ae63Sjeremylt   @brief Get the backend stride status of a CeedElemRestriction
1667a982d89SJeremy L. Thompson 
1677a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
168a681ae63Sjeremylt   @param[out] status      Variable to store stride status
1697a982d89SJeremy L. Thompson 
1707a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
1717a982d89SJeremy L. Thompson 
1727a982d89SJeremy L. Thompson   @ref Backend
1737a982d89SJeremy L. Thompson **/
174fd364f38SJeremy L Thompson int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr,
175fd364f38SJeremy L Thompson     bool *hasbackendstrides) {
176a681ae63Sjeremylt   if (!rstr->strides)
177a681ae63Sjeremylt     // LCOV_EXCL_START
178a681ae63Sjeremylt     return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data");
179a681ae63Sjeremylt   // LCOV_EXCL_STOP
1807a982d89SJeremy L. Thompson 
181fd364f38SJeremy L Thompson   *hasbackendstrides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) &&
182a681ae63Sjeremylt                         (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) &&
183a681ae63Sjeremylt                         (rstr->strides[2] == CEED_STRIDES_BACKEND[2]));
1847a982d89SJeremy L. Thompson   return 0;
1857a982d89SJeremy L. Thompson }
1867a982d89SJeremy L. Thompson 
1877a982d89SJeremy L. Thompson /**
18849fd234cSJeremy L Thompson 
18949fd234cSJeremy L Thompson   @brief Get the E-vector layout of a CeedElemRestriction
19049fd234cSJeremy L Thompson 
19149fd234cSJeremy L Thompson   @param rstr             CeedElemRestriction
19249fd234cSJeremy L Thompson   @param[out] layout      Variable to store layout array,
19349fd234cSJeremy L Thompson                             stored as [nodes, components, elements].
19449fd234cSJeremy L Thompson                             The data for node i, component j, element k in the
19549fd234cSJeremy L Thompson                             E-vector is given by
19695e93d34SJeremy L Thompson                             i*layout[0] + j*layout[1] + k*layout[2]
19749fd234cSJeremy L Thompson 
19849fd234cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
19949fd234cSJeremy L Thompson 
20049fd234cSJeremy L Thompson   @ref Backend
20149fd234cSJeremy L Thompson **/
20249fd234cSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr,
20349fd234cSJeremy L Thompson                                   CeedInt (*layout)[3]) {
20449fd234cSJeremy L Thompson   if (!rstr->layout[0])
20549fd234cSJeremy L Thompson     // LCOV_EXCL_START
20649fd234cSJeremy L Thompson     return CeedError(rstr->ceed, 1, "ElemRestriction has no layout data");
20749fd234cSJeremy L Thompson   // LCOV_EXCL_STOP
20849fd234cSJeremy L Thompson 
20949fd234cSJeremy L Thompson   for (int i = 0; i<3; i++)
21049fd234cSJeremy L Thompson     (*layout)[i] = rstr->layout[i];
21149fd234cSJeremy L Thompson   return 0;
21249fd234cSJeremy L Thompson }
21349fd234cSJeremy L Thompson 
21449fd234cSJeremy L Thompson /**
21549fd234cSJeremy L Thompson 
21649fd234cSJeremy L Thompson   @brief Set the E-vector layout of a CeedElemRestriction
21749fd234cSJeremy L Thompson 
21849fd234cSJeremy L Thompson   @param rstr             CeedElemRestriction
21949fd234cSJeremy L Thompson   @param layout           Variable to containing layout array,
22049fd234cSJeremy L Thompson                             stored as [nodes, components, elements].
22149fd234cSJeremy L Thompson                             The data for node i, component j, element k in the
22249fd234cSJeremy L Thompson                             E-vector is given by
22395e93d34SJeremy L Thompson                             i*layout[0] + j*layout[1] + k*layout[2]
22449fd234cSJeremy L Thompson 
22549fd234cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
22649fd234cSJeremy L Thompson 
22749fd234cSJeremy L Thompson   @ref Backend
22849fd234cSJeremy L Thompson **/
22949fd234cSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr,
23049fd234cSJeremy L Thompson                                   CeedInt layout[3]) {
23149fd234cSJeremy L Thompson   for (int i = 0; i<3; i++)
23249fd234cSJeremy L Thompson     rstr->layout[i] = layout[i];
23349fd234cSJeremy L Thompson   return 0;
23449fd234cSJeremy L Thompson }
23549fd234cSJeremy L Thompson 
23649fd234cSJeremy L Thompson /**
2377a982d89SJeremy L. Thompson   @brief Get the backend data of a CeedElemRestriction
2387a982d89SJeremy L. Thompson 
2397a982d89SJeremy L. Thompson   @param rstr             CeedElemRestriction
2407a982d89SJeremy L. Thompson   @param[out] data        Variable to store data
2417a982d89SJeremy L. Thompson 
2427a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
2437a982d89SJeremy L. Thompson 
2447a982d89SJeremy L. Thompson   @ref Backend
2457a982d89SJeremy L. Thompson **/
2467a982d89SJeremy L. Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) {
2477a982d89SJeremy L. Thompson   *data = rstr->data;
2487a982d89SJeremy L. Thompson   return 0;
2497a982d89SJeremy L. Thompson }
2507a982d89SJeremy L. Thompson 
2517a982d89SJeremy L. Thompson /**
2527a982d89SJeremy L. Thompson   @brief Set the backend data of a CeedElemRestriction
2537a982d89SJeremy L. Thompson 
2547a982d89SJeremy L. Thompson   @param[out] rstr        CeedElemRestriction
2557a982d89SJeremy L. Thompson   @param data             Data to set
2567a982d89SJeremy L. Thompson 
2577a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
2587a982d89SJeremy L. Thompson 
2597a982d89SJeremy L. Thompson   @ref Backend
2607a982d89SJeremy L. Thompson **/
2617a982d89SJeremy L. Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) {
2627a982d89SJeremy L. Thompson   rstr->data = *data;
2637a982d89SJeremy L. Thompson   return 0;
2647a982d89SJeremy L. Thompson }
2657a982d89SJeremy L. Thompson 
2667a982d89SJeremy L. Thompson /// @}
2677a982d89SJeremy L. Thompson 
26815910d16Sjeremylt /// @cond DOXYGEN_SKIP
26915910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none;
27015910d16Sjeremylt /// @endcond
27115910d16Sjeremylt 
2727a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2737a982d89SJeremy L. Thompson /// CeedElemRestriction Public API
2747a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2757a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser
276d7b241e6Sjeremylt /// @{
277d7b241e6Sjeremylt 
2787a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend
2797a982d89SJeremy L. Thompson const CeedInt CEED_STRIDES_BACKEND[3] = {};
2807a982d89SJeremy L. Thompson 
2814cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user
2827a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE =
2837a982d89SJeremy L. Thompson   &ceed_elemrestriction_none;
2847a982d89SJeremy L. Thompson 
285d7b241e6Sjeremylt /**
286b11c1e72Sjeremylt   @brief Create a CeedElemRestriction
287d7b241e6Sjeremylt 
288b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
289d979a051Sjeremylt   @param nelem      Number of elements described in the @a offsets array
290b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
291b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
29295bb1877Svaleriabarra                       (1 for scalar fields)
293d979a051Sjeremylt   @param compstride Stride between components for the same L-vector "node".
29495e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
29595e93d34SJeremy L Thompson                       the L-vector at index
2962db7ab32SJeremy L Thompson                         offsets[i + k*elemsize] + j*compstride.
297d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
298d979a051Sjeremylt                       the elements and fields given by this restriction.
299d979a051Sjeremylt   @param mtype      Memory type of the @a offsets array, see CeedMemType
300d979a051Sjeremylt   @param cmode      Copy mode for the @a offsets array, see CeedCopyMode
301d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
302d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
3038795c945Sjeremylt                       for the unknowns corresponding to element i, where
304d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
305d979a051Sjeremylt                       [0, @a lsize - 1].
3064ce2993fSjeremylt   @param[out] rstr  Address of the variable where the newly created
307b11c1e72Sjeremylt                       CeedElemRestriction will be stored
308d7b241e6Sjeremylt 
309b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
310dfdf5a53Sjeremylt 
3117a982d89SJeremy L. Thompson   @ref User
312b11c1e72Sjeremylt **/
313d979a051Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem, CeedInt elemsize,
314d979a051Sjeremylt                               CeedInt ncomp, CeedInt compstride,
315d979a051Sjeremylt                               CeedInt lsize, CeedMemType mtype,
316d979a051Sjeremylt                               CeedCopyMode cmode, const CeedInt *offsets,
3174ce2993fSjeremylt                               CeedElemRestriction *rstr) {
318d7b241e6Sjeremylt   int ierr;
319d7b241e6Sjeremylt 
3205fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
3215fe0d4faSjeremylt     Ceed delegate;
322aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
323aefd8378Sjeremylt     CeedChk(ierr);
3245fe0d4faSjeremylt 
3255fe0d4faSjeremylt     if (!delegate)
326c042f62fSJeremy L Thompson       // LCOV_EXCL_START
327d7b241e6Sjeremylt       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
328c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3295fe0d4faSjeremylt 
330d979a051Sjeremylt     ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize, ncomp,
331d979a051Sjeremylt                                      compstride, lsize, mtype, cmode,
332d979a051Sjeremylt                                      offsets, rstr); CeedChk(ierr);
3335fe0d4faSjeremylt     return 0;
3345fe0d4faSjeremylt   }
3355fe0d4faSjeremylt 
3364ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
3374ce2993fSjeremylt   (*rstr)->ceed = ceed;
338d7b241e6Sjeremylt   ceed->refcount++;
3394ce2993fSjeremylt   (*rstr)->refcount = 1;
3404ce2993fSjeremylt   (*rstr)->nelem = nelem;
3414ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
3424ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
343d979a051Sjeremylt   (*rstr)->compstride = compstride;
344d979a051Sjeremylt   (*rstr)->lsize = lsize;
3454ce2993fSjeremylt   (*rstr)->nblk = nelem;
3464ce2993fSjeremylt   (*rstr)->blksize = 1;
347d979a051Sjeremylt   ierr = ceed->ElemRestrictionCreate(mtype, cmode, offsets, *rstr);
348d979a051Sjeremylt   CeedChk(ierr);
349d7b241e6Sjeremylt   return 0;
350d7b241e6Sjeremylt }
351d7b241e6Sjeremylt 
352d7b241e6Sjeremylt /**
3537509a596Sjeremylt   @brief Create a strided CeedElemRestriction
354d7b241e6Sjeremylt 
355b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
3567509a596Sjeremylt   @param nelem      Number of elements described by the restriction
357b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
35895e93d34SJeremy L Thompson   @param ncomp      Number of field components per interpolation "node"
35995bb1877Svaleriabarra                       (1 for scalar fields)
360d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
361d979a051Sjeremylt                       the elements and fields given by this restriction.
3627509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
36395e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
36495e93d34SJeremy L Thompson                       the L-vector at index
36595e93d34SJeremy L Thompson                         i*strides[0] + j*strides[1] + k*strides[2].
36695e93d34SJeremy L Thompson                       @a CEED_STRIDES_BACKEND may be used with vectors created
36795e93d34SJeremy L Thompson                       by a Ceed backend.
3684ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
369b11c1e72Sjeremylt                       CeedElemRestriction will be stored
370d7b241e6Sjeremylt 
371b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
372dfdf5a53Sjeremylt 
3737a982d89SJeremy L. Thompson   @ref User
374b11c1e72Sjeremylt **/
3757509a596Sjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt nelem, CeedInt elemsize,
376d979a051Sjeremylt                                      CeedInt ncomp, CeedInt lsize,
3778621c6c6SJeremy L Thompson                                      const CeedInt strides[3],
378f90c8643Sjeremylt                                      CeedElemRestriction *rstr) {
379d7b241e6Sjeremylt   int ierr;
380d7b241e6Sjeremylt 
3815fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
3825fe0d4faSjeremylt     Ceed delegate;
383aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
384aefd8378Sjeremylt     CeedChk(ierr);
3855fe0d4faSjeremylt 
3865fe0d4faSjeremylt     if (!delegate)
387c042f62fSJeremy L Thompson       // LCOV_EXCL_START
3881d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
389c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3905fe0d4faSjeremylt 
391d979a051Sjeremylt     ierr = CeedElemRestrictionCreateStrided(delegate, nelem, elemsize, ncomp,
392d979a051Sjeremylt                                             lsize, strides, rstr);
393d979a051Sjeremylt     CeedChk(ierr);
3945fe0d4faSjeremylt     return 0;
3955fe0d4faSjeremylt   }
3965fe0d4faSjeremylt 
3974ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
3984ce2993fSjeremylt   (*rstr)->ceed = ceed;
399d7b241e6Sjeremylt   ceed->refcount++;
4004ce2993fSjeremylt   (*rstr)->refcount = 1;
4014ce2993fSjeremylt   (*rstr)->nelem = nelem;
4024ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
4034ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
404d979a051Sjeremylt   (*rstr)->lsize = lsize;
4054ce2993fSjeremylt   (*rstr)->nblk = nelem;
4064ce2993fSjeremylt   (*rstr)->blksize = 1;
4077509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
4087509a596Sjeremylt   for (int i = 0; i<3; i++)
4097509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
4101dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
4111dfeef1dSjeremylt                                      *rstr);
4124b8bea3bSJed Brown   CeedChk(ierr);
413d7b241e6Sjeremylt   return 0;
414d7b241e6Sjeremylt }
415d7b241e6Sjeremylt 
416d7b241e6Sjeremylt /**
417b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
418d7b241e6Sjeremylt 
419d7b241e6Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created.
420d979a051Sjeremylt   @param nelem      Number of elements described in the @a offsets array.
421b11c1e72Sjeremylt   @param elemsize   Size (number of unknowns) per element
422b11c1e72Sjeremylt   @param blksize    Number of elements in a block
42395bb1877Svaleriabarra   @param ncomp      Number of field components per interpolation node
42495bb1877Svaleriabarra                       (1 for scalar fields)
425d979a051Sjeremylt   @param compstride Stride between components for the same L-vector "node".
42695e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
42795e93d34SJeremy L Thompson                       the L-vector at index
4282db7ab32SJeremy L Thompson                         offsets[i + k*elemsize] + j*compstride.
429d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
430d979a051Sjeremylt                       the elements and fields given by this restriction.
431d979a051Sjeremylt   @param mtype      Memory type of the @a offsets array, see CeedMemType
432d979a051Sjeremylt   @param cmode      Copy mode for the @a offsets array, see CeedCopyMode
433d979a051Sjeremylt   @param offsets    Array of shape [@a nelem, @a elemsize]. Row i holds the
434d979a051Sjeremylt                       ordered list of the offsets (into the input CeedVector)
4358795c945Sjeremylt                       for the unknowns corresponding to element i, where
436d979a051Sjeremylt                       0 <= i < @a nelem. All offsets must be in the range
437d979a051Sjeremylt                       [0, @a lsize - 1]. The backend will permute and pad this
4388795c945Sjeremylt                       array to the desired ordering for the blocksize, which is
4398795c945Sjeremylt                       typically given by the backend. The default reordering is
4408795c945Sjeremylt                       to interlace elements.
4414ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
442b11c1e72Sjeremylt                       CeedElemRestriction will be stored
443d7b241e6Sjeremylt 
444b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
445dfdf5a53Sjeremylt 
4467a982d89SJeremy L. Thompson   @ref Backend
447b11c1e72Sjeremylt  **/
448d979a051Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize,
449d979a051Sjeremylt                                      CeedInt blksize, CeedInt ncomp,
450d979a051Sjeremylt                                      CeedInt compstride, CeedInt lsize,
451d979a051Sjeremylt                                      CeedMemType mtype, CeedCopyMode cmode,
452d979a051Sjeremylt                                      const CeedInt *offsets,
4534ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
454d7b241e6Sjeremylt   int ierr;
455d979a051Sjeremylt   CeedInt *blkoffsets;
456d7b241e6Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
457d7b241e6Sjeremylt 
4585fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
4595fe0d4faSjeremylt     Ceed delegate;
460aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
461aefd8378Sjeremylt     CeedChk(ierr);
4625fe0d4faSjeremylt 
4635fe0d4faSjeremylt     if (!delegate)
464c042f62fSJeremy L Thompson       // LCOV_EXCL_START
4651d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support "
4661d102b48SJeremy L Thompson                        "ElemRestrictionCreateBlocked");
467c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
4685fe0d4faSjeremylt 
469d979a051Sjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize, blksize,
470d979a051Sjeremylt                                             ncomp, compstride, lsize, mtype,
471d979a051Sjeremylt                                             cmode, offsets, rstr);
472d979a051Sjeremylt     CeedChk(ierr);
4735fe0d4faSjeremylt     return 0;
4745fe0d4faSjeremylt   }
475d7b241e6Sjeremylt 
4764ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
477d7b241e6Sjeremylt 
478d979a051Sjeremylt   ierr = CeedCalloc(nblk*blksize*elemsize, &blkoffsets); CeedChk(ierr);
479d979a051Sjeremylt   ierr = CeedPermutePadOffsets(offsets, blkoffsets, nblk, nelem, blksize,
4804b8bea3bSJed Brown                                elemsize);
481dfdf5a53Sjeremylt   CeedChk(ierr);
482d7b241e6Sjeremylt 
4834ce2993fSjeremylt   (*rstr)->ceed = ceed;
484d7b241e6Sjeremylt   ceed->refcount++;
4854ce2993fSjeremylt   (*rstr)->refcount = 1;
4864ce2993fSjeremylt   (*rstr)->nelem = nelem;
4874ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
4884ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
489d979a051Sjeremylt   (*rstr)->compstride = compstride;
490d979a051Sjeremylt   (*rstr)->lsize = lsize;
4914ce2993fSjeremylt   (*rstr)->nblk = nblk;
4924ce2993fSjeremylt   (*rstr)->blksize = blksize;
493667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
494d979a051Sjeremylt          (const CeedInt *) blkoffsets, *rstr); CeedChk(ierr);
495d7b241e6Sjeremylt 
4961d102b48SJeremy L Thompson   if (cmode == CEED_OWN_POINTER) {
497d979a051Sjeremylt     ierr = CeedFree(&offsets); CeedChk(ierr);
4981d102b48SJeremy L Thompson   }
499d7b241e6Sjeremylt 
500d7b241e6Sjeremylt   return 0;
501d7b241e6Sjeremylt }
502d7b241e6Sjeremylt 
503b11c1e72Sjeremylt /**
5047509a596Sjeremylt   @brief Create a blocked strided CeedElemRestriction
5057509a596Sjeremylt 
5067509a596Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
5077509a596Sjeremylt   @param nelem      Number of elements described by the restriction
5087509a596Sjeremylt   @param elemsize   Size (number of "nodes") per element
5097509a596Sjeremylt   @param blksize    Number of elements in a block
5107509a596Sjeremylt   @param ncomp      Number of field components per interpolation node
5117509a596Sjeremylt                       (1 for scalar fields)
512d979a051Sjeremylt   @param lsize      The size of the L-vector. This vector may be larger than
513d979a051Sjeremylt                       the elements and fields given by this restriction.
5147509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
51595e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
51695e93d34SJeremy L Thompson                       the L-vector at index
51795e93d34SJeremy L Thompson                         i*strides[0] + j*strides[1] + k*strides[2].
51895e93d34SJeremy L Thompson                       @a CEED_STRIDES_BACKEND may be used with vectors created
51995e93d34SJeremy L Thompson                       by a Ceed backend.
5207509a596Sjeremylt   @param rstr       Address of the variable where the newly created
5217509a596Sjeremylt                       CeedElemRestriction will be stored
5227509a596Sjeremylt 
5237509a596Sjeremylt   @return An error code: 0 - success, otherwise - failure
5247509a596Sjeremylt 
5257a982d89SJeremy L. Thompson   @ref User
5267509a596Sjeremylt **/
5277509a596Sjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt nelem,
528d979a051Sjeremylt     CeedInt elemsize, CeedInt blksize, CeedInt ncomp, CeedInt lsize,
5298621c6c6SJeremy L Thompson     const CeedInt strides[3], CeedElemRestriction *rstr) {
5307509a596Sjeremylt   int ierr;
5317509a596Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
5327509a596Sjeremylt 
5337509a596Sjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
5347509a596Sjeremylt     Ceed delegate;
5357509a596Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
5367509a596Sjeremylt     CeedChk(ierr);
5377509a596Sjeremylt 
5387509a596Sjeremylt     if (!delegate)
5397509a596Sjeremylt       // LCOV_EXCL_START
5407509a596Sjeremylt       return CeedError(ceed, 1, "Backend does not support "
5417509a596Sjeremylt                        "ElemRestrictionCreateBlocked");
5427509a596Sjeremylt     // LCOV_EXCL_STOP
5437509a596Sjeremylt 
5447509a596Sjeremylt     ierr = CeedElemRestrictionCreateBlockedStrided(delegate, nelem, elemsize,
545d979a051Sjeremylt            blksize, ncomp, lsize, strides, rstr);
5467509a596Sjeremylt     CeedChk(ierr);
5477509a596Sjeremylt     return 0;
5487509a596Sjeremylt   }
5497509a596Sjeremylt 
5507509a596Sjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
5517509a596Sjeremylt 
5527509a596Sjeremylt   (*rstr)->ceed = ceed;
5537509a596Sjeremylt   ceed->refcount++;
5547509a596Sjeremylt   (*rstr)->refcount = 1;
5557509a596Sjeremylt   (*rstr)->nelem = nelem;
5567509a596Sjeremylt   (*rstr)->elemsize = elemsize;
5577509a596Sjeremylt   (*rstr)->ncomp = ncomp;
558d979a051Sjeremylt   (*rstr)->lsize = lsize;
5597509a596Sjeremylt   (*rstr)->nblk = nblk;
5607509a596Sjeremylt   (*rstr)->blksize = blksize;
5617509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
5627509a596Sjeremylt   for (int i = 0; i<3; i++)
5637509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
5647509a596Sjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
5657509a596Sjeremylt          NULL, *rstr); CeedChk(ierr);
5667509a596Sjeremylt 
5677509a596Sjeremylt   return 0;
5687509a596Sjeremylt }
5697509a596Sjeremylt 
5707509a596Sjeremylt /**
571b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
572b11c1e72Sjeremylt 
5734ce2993fSjeremylt   @param rstr  CeedElemRestriction
574b11c1e72Sjeremylt   @param lvec  The address of the L-vector to be created, or NULL
575b11c1e72Sjeremylt   @param evec  The address of the E-vector to be created, or NULL
576b11c1e72Sjeremylt 
577b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
578dfdf5a53Sjeremylt 
5797a982d89SJeremy L. Thompson   @ref User
580b11c1e72Sjeremylt **/
5814ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec,
582d7b241e6Sjeremylt                                     CeedVector *evec) {
583d7b241e6Sjeremylt   int ierr;
584d7b241e6Sjeremylt   CeedInt n, m;
585d979a051Sjeremylt   m = rstr->lsize;
5864ce2993fSjeremylt   n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
587d7b241e6Sjeremylt   if (lvec) {
5884ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr);
589d7b241e6Sjeremylt   }
590d7b241e6Sjeremylt   if (evec) {
5914ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr);
592d7b241e6Sjeremylt   }
593d7b241e6Sjeremylt   return 0;
594d7b241e6Sjeremylt }
595d7b241e6Sjeremylt 
596d7b241e6Sjeremylt /**
597d9e1f99aSValeria Barra   @brief Restrict an L-vector to an E-vector or apply its transpose
598d7b241e6Sjeremylt 
5994ce2993fSjeremylt   @param rstr    CeedElemRestriction
600d7b241e6Sjeremylt   @param tmode   Apply restriction or transpose
6014cc79fe7SJed Brown   @param u       Input vector (of size @a lsize when tmode=@ref CEED_NOTRANSPOSE)
602a8d32208Sjeremylt   @param ru      Output vector (of shape [@a nelem * @a elemsize] when
6034cc79fe7SJed Brown                    tmode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
6047aaeacdcSjeremylt                    by the backend.
6054cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
606b11c1e72Sjeremylt 
607b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
608dfdf5a53Sjeremylt 
6097a982d89SJeremy L. Thompson   @ref User
610b11c1e72Sjeremylt **/
6114ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode,
612a8d32208Sjeremylt                              CeedVector u, CeedVector ru,
613a8d32208Sjeremylt                              CeedRequest *request) {
614d7b241e6Sjeremylt   CeedInt m,n;
615d7b241e6Sjeremylt   int ierr;
616d7b241e6Sjeremylt 
617d7b241e6Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
6184ce2993fSjeremylt     m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
619d979a051Sjeremylt     n = rstr->lsize;
620d7b241e6Sjeremylt   } else {
621d979a051Sjeremylt     m = rstr->lsize;
6224ce2993fSjeremylt     n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
623d7b241e6Sjeremylt   }
624d7b241e6Sjeremylt   if (n != u->length)
625c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6261d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
6271d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
628c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
629a8d32208Sjeremylt   if (m != ru->length)
630c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6311d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
632a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
633c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
634074cb416Sjeremylt   ierr = rstr->Apply(rstr, tmode, u, ru, request); CeedChk(ierr);
635d7b241e6Sjeremylt 
636d7b241e6Sjeremylt   return 0;
637d7b241e6Sjeremylt }
638d7b241e6Sjeremylt 
639d7b241e6Sjeremylt /**
640d9e1f99aSValeria Barra   @brief Restrict an L-vector to a block of an E-vector or apply its transpose
641be9261b7Sjeremylt 
642be9261b7Sjeremylt   @param rstr    CeedElemRestriction
6431f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
6441f37b403Sjeremylt                    elements [0 : blksize] and block=3 will handle elements
6451f37b403Sjeremylt                    [3*blksize : 4*blksize]
646be9261b7Sjeremylt   @param tmode   Apply restriction or transpose
6474cc79fe7SJed Brown   @param u       Input vector (of size @a lsize when tmode=@ref CEED_NOTRANSPOSE)
648a8d32208Sjeremylt   @param ru      Output vector (of shape [@a blksize * @a elemsize] when
6494cc79fe7SJed Brown                    tmode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
6507aaeacdcSjeremylt                    by the backend.
6514cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
652be9261b7Sjeremylt 
653be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
654be9261b7Sjeremylt 
6557a982d89SJeremy L. Thompson   @ref Backend
656be9261b7Sjeremylt **/
657be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
658a8d32208Sjeremylt                                   CeedTransposeMode tmode, CeedVector u,
659a8d32208Sjeremylt                                   CeedVector ru, CeedRequest *request) {
660be9261b7Sjeremylt   CeedInt m,n;
661be9261b7Sjeremylt   int ierr;
662be9261b7Sjeremylt 
663be9261b7Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
664be9261b7Sjeremylt     m = rstr->blksize * rstr->elemsize * rstr->ncomp;
665d979a051Sjeremylt     n = rstr->lsize;
666be9261b7Sjeremylt   } else {
667d979a051Sjeremylt     m = rstr->lsize;
668be9261b7Sjeremylt     n = rstr->blksize * rstr->elemsize * rstr->ncomp;
669be9261b7Sjeremylt   }
670be9261b7Sjeremylt   if (n != u->length)
671c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6721d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
6731d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
674c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
675a8d32208Sjeremylt   if (m != ru->length)
676c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6771d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
678a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
679c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
680be9261b7Sjeremylt   if (rstr->blksize*block > rstr->nelem)
681c042f62fSJeremy L Thompson     // LCOV_EXCL_START
6821d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > "
6831d102b48SJeremy L Thompson                      "total elements %d", block, rstr->blksize*block,
6841d102b48SJeremy L Thompson                      rstr->nelem);
685c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
686074cb416Sjeremylt   ierr = rstr->ApplyBlock(rstr, block, tmode, u, ru, request);
687be9261b7Sjeremylt   CeedChk(ierr);
688be9261b7Sjeremylt 
689be9261b7Sjeremylt   return 0;
690be9261b7Sjeremylt }
691be9261b7Sjeremylt 
692be9261b7Sjeremylt /**
693d979a051Sjeremylt   @brief Get the L-vector component stride
694a681ae63Sjeremylt 
695a681ae63Sjeremylt   @param rstr             CeedElemRestriction
696d979a051Sjeremylt   @param[out] compstride  Variable to store component stride
697a681ae63Sjeremylt 
698a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
699a681ae63Sjeremylt 
700a681ae63Sjeremylt   @ref Backend
701a681ae63Sjeremylt **/
702d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr,
703d979a051Sjeremylt                                      CeedInt *compstride) {
704d979a051Sjeremylt   *compstride = rstr->compstride;
705a681ae63Sjeremylt   return 0;
706a681ae63Sjeremylt }
707a681ae63Sjeremylt 
708a681ae63Sjeremylt /**
709a681ae63Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
710a681ae63Sjeremylt 
711a681ae63Sjeremylt   @param rstr             CeedElemRestriction
712a681ae63Sjeremylt   @param[out] numelem     Variable to store number of elements
713a681ae63Sjeremylt 
714a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
715a681ae63Sjeremylt 
716a681ae63Sjeremylt   @ref Backend
717a681ae63Sjeremylt **/
718a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
719a681ae63Sjeremylt                                       CeedInt *numelem) {
720a681ae63Sjeremylt   *numelem = rstr->nelem;
721a681ae63Sjeremylt   return 0;
722a681ae63Sjeremylt }
723a681ae63Sjeremylt 
724a681ae63Sjeremylt /**
725a681ae63Sjeremylt   @brief Get the size of elements in the CeedElemRestriction
726a681ae63Sjeremylt 
727a681ae63Sjeremylt   @param rstr             CeedElemRestriction
728a681ae63Sjeremylt   @param[out] elemsize    Variable to store size of elements
729a681ae63Sjeremylt 
730a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
731a681ae63Sjeremylt 
732a681ae63Sjeremylt   @ref Backend
733a681ae63Sjeremylt **/
734a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
735a681ae63Sjeremylt                                       CeedInt *elemsize) {
736a681ae63Sjeremylt   *elemsize = rstr->elemsize;
737a681ae63Sjeremylt   return 0;
738a681ae63Sjeremylt }
739a681ae63Sjeremylt 
740a681ae63Sjeremylt /**
741d979a051Sjeremylt   @brief Get the size of the l-vector for a CeedElemRestriction
742a681ae63Sjeremylt 
743a681ae63Sjeremylt   @param rstr             CeedElemRestriction
744a681ae63Sjeremylt   @param[out] numnodes    Variable to store number of nodes
745a681ae63Sjeremylt 
746a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
747a681ae63Sjeremylt 
748a681ae63Sjeremylt   @ref Backend
749a681ae63Sjeremylt **/
750d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr,
751d979a051Sjeremylt                                       CeedInt *lsize) {
752d979a051Sjeremylt   *lsize = rstr->lsize;
753a681ae63Sjeremylt   return 0;
754a681ae63Sjeremylt }
755a681ae63Sjeremylt 
756a681ae63Sjeremylt /**
757a681ae63Sjeremylt   @brief Get the number of components in the elements of a
758a681ae63Sjeremylt          CeedElemRestriction
759a681ae63Sjeremylt 
760a681ae63Sjeremylt   @param rstr             CeedElemRestriction
761a681ae63Sjeremylt   @param[out] numcomp     Variable to store number of components
762a681ae63Sjeremylt 
763a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
764a681ae63Sjeremylt 
765a681ae63Sjeremylt   @ref Backend
766a681ae63Sjeremylt **/
767a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
768a681ae63Sjeremylt                                         CeedInt *numcomp) {
769a681ae63Sjeremylt   *numcomp = rstr->ncomp;
770a681ae63Sjeremylt   return 0;
771a681ae63Sjeremylt }
772a681ae63Sjeremylt 
773a681ae63Sjeremylt /**
774a681ae63Sjeremylt   @brief Get the number of blocks in a CeedElemRestriction
775a681ae63Sjeremylt 
776a681ae63Sjeremylt   @param rstr             CeedElemRestriction
777a681ae63Sjeremylt   @param[out] numblock    Variable to store number of blocks
778a681ae63Sjeremylt 
779a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
780a681ae63Sjeremylt 
781a681ae63Sjeremylt   @ref Backend
782a681ae63Sjeremylt **/
783a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
784a681ae63Sjeremylt                                     CeedInt *numblock) {
785a681ae63Sjeremylt   *numblock = rstr->nblk;
786a681ae63Sjeremylt   return 0;
787a681ae63Sjeremylt }
788a681ae63Sjeremylt 
789a681ae63Sjeremylt /**
790a681ae63Sjeremylt   @brief Get the size of blocks in the CeedElemRestriction
791a681ae63Sjeremylt 
792a681ae63Sjeremylt   @param rstr             CeedElemRestriction
793a681ae63Sjeremylt   @param[out] blksize     Variable to store size of blocks
794a681ae63Sjeremylt 
795a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
796a681ae63Sjeremylt 
797a681ae63Sjeremylt   @ref Backend
798a681ae63Sjeremylt **/
799a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
800a681ae63Sjeremylt                                     CeedInt *blksize) {
801a681ae63Sjeremylt   *blksize = rstr->blksize;
802a681ae63Sjeremylt   return 0;
803a681ae63Sjeremylt }
804a681ae63Sjeremylt 
805a681ae63Sjeremylt /**
806d9e1f99aSValeria Barra   @brief Get the multiplicity of nodes in a CeedElemRestriction
8071469ee4dSjeremylt 
8081469ee4dSjeremylt   @param rstr             CeedElemRestriction
809d979a051Sjeremylt   @param[out] mult        Vector to store multiplicity (of size lsize)
8101469ee4dSjeremylt 
8111469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
8121469ee4dSjeremylt 
8137a982d89SJeremy L. Thompson   @ref User
8141469ee4dSjeremylt **/
8151469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
8161469ee4dSjeremylt                                        CeedVector mult) {
8171469ee4dSjeremylt   int ierr;
8181469ee4dSjeremylt   CeedVector evec;
8191469ee4dSjeremylt 
8201469ee4dSjeremylt   // Create and set evec
8211469ee4dSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr);
8221469ee4dSjeremylt   ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr);
823fa9eac48SJed Brown   ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr);
8241469ee4dSjeremylt 
8251469ee4dSjeremylt   // Apply to get multiplicity
826a8d32208Sjeremylt   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult,
827efc78312Sjeremylt                                   CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
8281469ee4dSjeremylt 
8291469ee4dSjeremylt   // Cleanup
8301469ee4dSjeremylt   ierr = CeedVectorDestroy(&evec); CeedChk(ierr);
8311469ee4dSjeremylt 
8321469ee4dSjeremylt   return 0;
8331469ee4dSjeremylt }
8341469ee4dSjeremylt 
8351469ee4dSjeremylt /**
836f02ca4a2SJed Brown   @brief View a CeedElemRestriction
837f02ca4a2SJed Brown 
838f02ca4a2SJed Brown   @param[in] rstr    CeedElemRestriction to view
839f02ca4a2SJed Brown   @param[in] stream  Stream to write; typically stdout/stderr or a file
840f02ca4a2SJed Brown 
841f02ca4a2SJed Brown   @return Error code: 0 - success, otherwise - failure
842f02ca4a2SJed Brown 
8437a982d89SJeremy L. Thompson   @ref User
844f02ca4a2SJed Brown **/
845f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
8467509a596Sjeremylt   char stridesstr[500];
8477509a596Sjeremylt   if (rstr->strides)
8487509a596Sjeremylt     sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1],
8497509a596Sjeremylt             rstr->strides[2]);
850d979a051Sjeremylt   else
851d979a051Sjeremylt     sprintf(stridesstr, "%d", rstr->compstride);
8527509a596Sjeremylt 
8530036de2cSjeremylt   fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d "
8540036de2cSjeremylt           "nodes each and %s %s\n", rstr->blksize > 1 ? "Blocked " : "",
855d979a051Sjeremylt           rstr->lsize, rstr->ncomp, rstr->nelem, rstr->elemsize,
856d979a051Sjeremylt           rstr->strides ? "strides" : "component stride", stridesstr);
857f02ca4a2SJed Brown   return 0;
858f02ca4a2SJed Brown }
859f02ca4a2SJed Brown 
860f02ca4a2SJed Brown /**
861b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
862b11c1e72Sjeremylt 
8634ce2993fSjeremylt   @param rstr  CeedElemRestriction to destroy
864b11c1e72Sjeremylt 
865b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
866dfdf5a53Sjeremylt 
8677a982d89SJeremy L. Thompson   @ref User
868b11c1e72Sjeremylt **/
8694ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
870d7b241e6Sjeremylt   int ierr;
871d7b241e6Sjeremylt 
872*752c3701SJeremy L Thompson   if (!*rstr || --(*rstr)->refcount > 0) return 0;
873430758c8SJeremy L Thompson   if ((*rstr)->numreaders)
874430758c8SJeremy L Thompson     return CeedError((*rstr)->ceed, 1, "Cannot destroy CeedElemRestriction, "
875430758c8SJeremy L Thompson                      "a process has read access to the offset data");
8764ce2993fSjeremylt   if ((*rstr)->Destroy) {
8774ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
878d7b241e6Sjeremylt   }
8797509a596Sjeremylt   ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr);
8804ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
8814ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
882d7b241e6Sjeremylt   return 0;
883d7b241e6Sjeremylt }
884d7b241e6Sjeremylt 
885d7b241e6Sjeremylt /// @}
886