xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-elemrestriction.c (revision b435c5a60b1833cef613d6281360673b9d9fef16)
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 
17ec3da8bcSJed Brown #include <ceed/ceed.h>
18ec3da8bcSJed Brown #include <ceed/backend.h>
193d576824SJeremy L Thompson #include <ceed-impl.h>
203d576824SJeremy L Thompson #include <stdbool.h>
213d576824SJeremy L Thompson #include <stdio.h>
22d7b241e6Sjeremylt 
237a982d89SJeremy L. Thompson /// @file
247a982d89SJeremy L. Thompson /// Implementation of CeedElemRestriction interfaces
257a982d89SJeremy L. Thompson 
267a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
277a982d89SJeremy L. Thompson /// CeedElemRestriction Library Internal Functions
287a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
297a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionDeveloper
307a982d89SJeremy L. Thompson /// @{
317a982d89SJeremy L. Thompson 
327a982d89SJeremy L. Thompson /**
33d979a051Sjeremylt   @brief Permute and pad offsets for a blocked restriction
347a982d89SJeremy L. Thompson 
35d1d35e2fSjeremylt   @param offsets     Array of shape [@a num_elem, @a elem_size]. 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
38d1d35e2fSjeremylt                        0 <= i < @a num_elem. All offsets must be in the range
39d1d35e2fSjeremylt                        [0, @a l_size - 1].
40d1d35e2fSjeremylt   @param blk_offsets Array of permuted and padded offsets of
41d1d35e2fSjeremylt                        shape [@a num_blk, @a elem_size, @a blk_size].
42d1d35e2fSjeremylt   @param num_blk     Number of blocks
43d1d35e2fSjeremylt   @param num_elem    Number of elements
44d1d35e2fSjeremylt   @param blk_size    Number of elements in a block
45d1d35e2fSjeremylt   @param elem_size   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 **/
51d1d35e2fSjeremylt int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blk_offsets,
52d1d35e2fSjeremylt                           CeedInt num_blk, CeedInt num_elem, CeedInt blk_size,
53d1d35e2fSjeremylt                           CeedInt elem_size) {
54d1d35e2fSjeremylt   for (CeedInt e=0; e<num_blk*blk_size; e+=blk_size)
55d1d35e2fSjeremylt     for (int j=0; j<blk_size; j++)
56d1d35e2fSjeremylt       for (int k=0; k<elem_size; k++)
57d1d35e2fSjeremylt         blk_offsets[e*elem_size + k*blk_size + j]
58d1d35e2fSjeremylt           = offsets[CeedIntMin(e+j,num_elem-1)*elem_size + k];
59e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
607a982d89SJeremy L. Thompson }
617a982d89SJeremy L. Thompson 
627a982d89SJeremy L. Thompson /// @}
637a982d89SJeremy L. Thompson 
647a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
657a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API
667a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
677a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend
687a982d89SJeremy L. Thompson /// @{
697a982d89SJeremy L. Thompson 
707a982d89SJeremy L. Thompson /**
71a681ae63Sjeremylt 
72a681ae63Sjeremylt   @brief Get the strides of a strided CeedElemRestriction
737a982d89SJeremy L. Thompson 
747a982d89SJeremy L. Thompson   @param rstr          CeedElemRestriction
75a681ae63Sjeremylt   @param[out] strides  Variable to store strides array
767a982d89SJeremy L. Thompson 
777a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
787a982d89SJeremy L. Thompson 
797a982d89SJeremy L. Thompson   @ref Backend
807a982d89SJeremy L. Thompson **/
81a681ae63Sjeremylt int CeedElemRestrictionGetStrides(CeedElemRestriction rstr,
82a681ae63Sjeremylt                                   CeedInt (*strides)[3]) {
83a681ae63Sjeremylt   if (!rstr->strides)
84a681ae63Sjeremylt     // LCOV_EXCL_START
85e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_MINOR,
86e15f9bd0SJeremy L Thompson                      "ElemRestriction has no stride data");
87a681ae63Sjeremylt   // LCOV_EXCL_STOP
88a681ae63Sjeremylt 
89a681ae63Sjeremylt   for (int i=0; i<3; i++)
90a681ae63Sjeremylt     (*strides)[i] = rstr->strides[i];
91e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
927a982d89SJeremy L. Thompson }
937a982d89SJeremy L. Thompson 
947a982d89SJeremy L. Thompson /**
95bd33150aSjeremylt   @brief Get read-only access to a CeedElemRestriction offsets array by memtype
96bd33150aSjeremylt 
97bd33150aSjeremylt   @param rstr          CeedElemRestriction to retrieve offsets
98d1d35e2fSjeremylt   @param mem_type      Memory type on which to access the array.  If the backend
99bd33150aSjeremylt                          uses a different memory type, this will perform a copy
100bd33150aSjeremylt                          (possibly cached).
101d1d35e2fSjeremylt   @param[out] offsets  Array on memory type mem_type
102bd33150aSjeremylt 
103bd33150aSjeremylt   @return An error code: 0 - success, otherwise - failure
104bd33150aSjeremylt 
105bd33150aSjeremylt   @ref User
106bd33150aSjeremylt **/
107d1d35e2fSjeremylt int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr,
108d1d35e2fSjeremylt                                   CeedMemType mem_type,
109bd33150aSjeremylt                                   const CeedInt **offsets) {
110bd33150aSjeremylt   int ierr;
111bd33150aSjeremylt 
112bd33150aSjeremylt   if (!rstr->GetOffsets)
113bd33150aSjeremylt     // LCOV_EXCL_START
114e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_UNSUPPORTED,
115e15f9bd0SJeremy L Thompson                      "Backend does not support GetOffsets");
116bd33150aSjeremylt   // LCOV_EXCL_STOP
117bd33150aSjeremylt 
118d1d35e2fSjeremylt   ierr = rstr->GetOffsets(rstr, mem_type, offsets); CeedChk(ierr);
119d1d35e2fSjeremylt   rstr->num_readers++;
120e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
121430758c8SJeremy L Thompson }
122430758c8SJeremy L Thompson 
123430758c8SJeremy L Thompson /**
124430758c8SJeremy L Thompson   @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets()
125430758c8SJeremy L Thompson 
126430758c8SJeremy L Thompson   @param rstr     CeedElemRestriction to restore
127430758c8SJeremy L Thompson   @param offsets  Array of offset data
128430758c8SJeremy L Thompson 
129430758c8SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
130430758c8SJeremy L Thompson 
131430758c8SJeremy L Thompson   @ref User
132430758c8SJeremy L Thompson **/
133430758c8SJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr,
134430758c8SJeremy L Thompson                                       const CeedInt **offsets) {
135430758c8SJeremy L Thompson   *offsets = NULL;
136d1d35e2fSjeremylt   rstr->num_readers--;
137e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
138bd33150aSjeremylt }
139bd33150aSjeremylt 
140bd33150aSjeremylt /**
1413ac43b2cSJeremy L Thompson   @brief Get the strided status of a CeedElemRestriction
1423ac43b2cSJeremy L Thompson 
1433ac43b2cSJeremy L Thompson   @param rstr             CeedElemRestriction
144d1d35e2fSjeremylt   @param[out] is_strided  Variable to store strided status, 1 if strided else 0
1453ac43b2cSJeremy L Thompson 
1463ac43b2cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
1473ac43b2cSJeremy L Thompson 
1483ac43b2cSJeremy L Thompson   @ref Backend
1493ac43b2cSJeremy L Thompson **/
150d1d35e2fSjeremylt int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) {
151d1d35e2fSjeremylt   *is_strided = rstr->strides ? true : false;
152e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1533ac43b2cSJeremy L Thompson }
1543ac43b2cSJeremy L Thompson 
1553ac43b2cSJeremy L Thompson /**
156*b435c5a6Srezgarshakeri   @brief Get oriented status of a CeedElemRestriction
157*b435c5a6Srezgarshakeri 
158*b435c5a6Srezgarshakeri   @param rstr             CeedElemRestriction
159*b435c5a6Srezgarshakeri   @param[out] is_oriented  Variable to store oriented status, 1 if oriented else 0
160*b435c5a6Srezgarshakeri 
161*b435c5a6Srezgarshakeri   @return An error code: 0 - success, otherwise - failure
162*b435c5a6Srezgarshakeri 
163*b435c5a6Srezgarshakeri   @ref Backend
164*b435c5a6Srezgarshakeri **/
165*b435c5a6Srezgarshakeri int CeedElemRestrictionIsOriented(CeedElemRestriction rstr, bool *is_oriented) {
166*b435c5a6Srezgarshakeri   *is_oriented = rstr->is_oriented;
167*b435c5a6Srezgarshakeri   return CEED_ERROR_SUCCESS;
168*b435c5a6Srezgarshakeri }
169*b435c5a6Srezgarshakeri 
170*b435c5a6Srezgarshakeri /**
171a681ae63Sjeremylt   @brief Get the backend stride status of a CeedElemRestriction
1727a982d89SJeremy L. Thompson 
1737a982d89SJeremy L. Thompson   @param rstr                      CeedElemRestriction
17496b902e2Sjeremylt   @param[out] has_backend_strides  Variable to store stride status
1757a982d89SJeremy L. Thompson 
1767a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
1777a982d89SJeremy L. Thompson 
1787a982d89SJeremy L. Thompson   @ref Backend
1797a982d89SJeremy L. Thompson **/
180fd364f38SJeremy L Thompson int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr,
181d1d35e2fSjeremylt     bool *has_backend_strides) {
182a681ae63Sjeremylt   if (!rstr->strides)
183a681ae63Sjeremylt     // LCOV_EXCL_START
184e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_MINOR,
185e15f9bd0SJeremy L Thompson                      "ElemRestriction has no stride data");
186a681ae63Sjeremylt   // LCOV_EXCL_STOP
1877a982d89SJeremy L. Thompson 
188d1d35e2fSjeremylt   *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) &&
189a681ae63Sjeremylt                           (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) &&
190a681ae63Sjeremylt                           (rstr->strides[2] == CEED_STRIDES_BACKEND[2]));
191e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1927a982d89SJeremy L. Thompson }
1937a982d89SJeremy L. Thompson 
1947a982d89SJeremy L. Thompson /**
19549fd234cSJeremy L Thompson 
19649fd234cSJeremy L Thompson   @brief Get the E-vector layout of a CeedElemRestriction
19749fd234cSJeremy L Thompson 
19849fd234cSJeremy L Thompson   @param rstr         CeedElemRestriction
19949fd234cSJeremy L Thompson   @param[out] layout  Variable to store layout array,
20049fd234cSJeremy L Thompson                         stored as [nodes, components, elements].
20149fd234cSJeremy L Thompson                         The data for node i, component j, element k in the
20249fd234cSJeremy L Thompson                         E-vector is given by
20395e93d34SJeremy L Thompson                         i*layout[0] + j*layout[1] + k*layout[2]
20449fd234cSJeremy L Thompson 
20549fd234cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
20649fd234cSJeremy L Thompson 
20749fd234cSJeremy L Thompson   @ref Backend
20849fd234cSJeremy L Thompson **/
20949fd234cSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr,
21049fd234cSJeremy L Thompson                                   CeedInt (*layout)[3]) {
21149fd234cSJeremy L Thompson   if (!rstr->layout[0])
21249fd234cSJeremy L Thompson     // LCOV_EXCL_START
213e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_MINOR,
214e15f9bd0SJeremy L Thompson                      "ElemRestriction has no layout data");
21549fd234cSJeremy L Thompson   // LCOV_EXCL_STOP
21649fd234cSJeremy L Thompson 
21749fd234cSJeremy L Thompson   for (int i=0; i<3; i++)
21849fd234cSJeremy L Thompson     (*layout)[i] = rstr->layout[i];
219e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
22049fd234cSJeremy L Thompson }
22149fd234cSJeremy L Thompson 
22249fd234cSJeremy L Thompson /**
22349fd234cSJeremy L Thompson 
22449fd234cSJeremy L Thompson   @brief Set the E-vector layout of a CeedElemRestriction
22549fd234cSJeremy L Thompson 
22649fd234cSJeremy L Thompson   @param rstr    CeedElemRestriction
22749fd234cSJeremy L Thompson   @param layout  Variable to containing layout array,
22849fd234cSJeremy L Thompson                    stored as [nodes, components, elements].
22949fd234cSJeremy L Thompson                    The data for node i, component j, element k in the
23049fd234cSJeremy L Thompson                    E-vector is given by
23195e93d34SJeremy L Thompson                    i*layout[0] + j*layout[1] + k*layout[2]
23249fd234cSJeremy L Thompson 
23349fd234cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
23449fd234cSJeremy L Thompson 
23549fd234cSJeremy L Thompson   @ref Backend
23649fd234cSJeremy L Thompson **/
23749fd234cSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr,
23849fd234cSJeremy L Thompson                                   CeedInt layout[3]) {
23949fd234cSJeremy L Thompson   for (int i = 0; i<3; i++)
24049fd234cSJeremy L Thompson     rstr->layout[i] = layout[i];
241e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
24249fd234cSJeremy L Thompson }
24349fd234cSJeremy L Thompson 
24449fd234cSJeremy L Thompson /**
2457a982d89SJeremy L. Thompson   @brief Get the backend data of a CeedElemRestriction
2467a982d89SJeremy L. Thompson 
2477a982d89SJeremy L. Thompson   @param rstr       CeedElemRestriction
2487a982d89SJeremy L. Thompson   @param[out] data  Variable to store data
2497a982d89SJeremy L. Thompson 
2507a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
2517a982d89SJeremy L. Thompson 
2527a982d89SJeremy L. Thompson   @ref Backend
2537a982d89SJeremy L. Thompson **/
254777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) {
255777ff853SJeremy L Thompson   *(void **)data = rstr->data;
256e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2577a982d89SJeremy L. Thompson }
2587a982d89SJeremy L. Thompson 
2597a982d89SJeremy L. Thompson /**
2607a982d89SJeremy L. Thompson   @brief Set the backend data of a CeedElemRestriction
2617a982d89SJeremy L. Thompson 
2627a982d89SJeremy L. Thompson   @param[out] rstr  CeedElemRestriction
2637a982d89SJeremy L. Thompson   @param data       Data to set
2647a982d89SJeremy L. Thompson 
2657a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
2667a982d89SJeremy L. Thompson 
2677a982d89SJeremy L. Thompson   @ref Backend
2687a982d89SJeremy L. Thompson **/
269777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) {
270777ff853SJeremy L Thompson   rstr->data = data;
271e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2727a982d89SJeremy L. Thompson }
2737a982d89SJeremy L. Thompson 
27434359f16Sjeremylt /**
27534359f16Sjeremylt   @brief Increment the reference counter for a CeedElemRestriction
27634359f16Sjeremylt 
27734359f16Sjeremylt   @param rstr  ElemRestriction to increment the reference counter
27834359f16Sjeremylt 
27934359f16Sjeremylt   @return An error code: 0 - success, otherwise - failure
28034359f16Sjeremylt 
28134359f16Sjeremylt   @ref Backend
28234359f16Sjeremylt **/
2839560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) {
28434359f16Sjeremylt   rstr->ref_count++;
28534359f16Sjeremylt   return CEED_ERROR_SUCCESS;
28634359f16Sjeremylt }
28734359f16Sjeremylt 
2887a982d89SJeremy L. Thompson /// @}
2897a982d89SJeremy L. Thompson 
29015910d16Sjeremylt /// @cond DOXYGEN_SKIP
29115910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none;
29215910d16Sjeremylt /// @endcond
29315910d16Sjeremylt 
2947a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2957a982d89SJeremy L. Thompson /// CeedElemRestriction Public API
2967a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2977a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser
298d7b241e6Sjeremylt /// @{
299d7b241e6Sjeremylt 
3007a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend
30145f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0};
3027a982d89SJeremy L. Thompson 
3034cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user
3047a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE =
3057a982d89SJeremy L. Thompson   &ceed_elemrestriction_none;
3067a982d89SJeremy L. Thompson 
307d7b241e6Sjeremylt /**
308b11c1e72Sjeremylt   @brief Create a CeedElemRestriction
309d7b241e6Sjeremylt 
310b11c1e72Sjeremylt   @param ceed         A Ceed object where the CeedElemRestriction will be created
311d1d35e2fSjeremylt   @param num_elem     Number of elements described in the @a offsets array
312d1d35e2fSjeremylt   @param elem_size    Size (number of "nodes") per element
313d1d35e2fSjeremylt   @param num_comp     Number of field components per interpolation node
31495bb1877Svaleriabarra                         (1 for scalar fields)
315d1d35e2fSjeremylt   @param comp_stride  Stride between components for the same L-vector "node".
31695e93d34SJeremy L Thompson                         Data for node i, component j, element k can be found in
31795e93d34SJeremy L Thompson                         the L-vector at index
318d1d35e2fSjeremylt                         offsets[i + k*elem_size] + j*comp_stride.
319d1d35e2fSjeremylt   @param l_size       The size of the L-vector. This vector may be larger than
320d979a051Sjeremylt                         the elements and fields given by this restriction.
321d1d35e2fSjeremylt   @param mem_type     Memory type of the @a offsets array, see CeedMemType
322d1d35e2fSjeremylt   @param copy_mode    Copy mode for the @a offsets array, see CeedCopyMode
323d1d35e2fSjeremylt   @param offsets      Array of shape [@a num_elem, @a elem_size]. Row i holds the
324d979a051Sjeremylt                         ordered list of the offsets (into the input CeedVector)
3258795c945Sjeremylt                         for the unknowns corresponding to element i, where
326d1d35e2fSjeremylt                         0 <= i < @a num_elem. All offsets must be in the range
327d1d35e2fSjeremylt                         [0, @a l_size - 1].
3284ce2993fSjeremylt   @param[out] rstr    Address of the variable where the newly created
329b11c1e72Sjeremylt                         CeedElemRestriction will be stored
330d7b241e6Sjeremylt 
331b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
332dfdf5a53Sjeremylt 
3337a982d89SJeremy L. Thompson   @ref User
334b11c1e72Sjeremylt **/
335d1d35e2fSjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size,
336d1d35e2fSjeremylt                               CeedInt num_comp, CeedInt comp_stride,
337d1d35e2fSjeremylt                               CeedInt l_size, CeedMemType mem_type,
338d1d35e2fSjeremylt                               CeedCopyMode copy_mode, const CeedInt *offsets,
3394ce2993fSjeremylt                               CeedElemRestriction *rstr) {
340d7b241e6Sjeremylt   int ierr;
341d7b241e6Sjeremylt 
3425fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
3435fe0d4faSjeremylt     Ceed delegate;
344aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
345aefd8378Sjeremylt     CeedChk(ierr);
3465fe0d4faSjeremylt 
3475fe0d4faSjeremylt     if (!delegate)
348c042f62fSJeremy L Thompson       // LCOV_EXCL_START
349e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
350e15f9bd0SJeremy L Thompson                        "Backend does not support ElemRestrictionCreate");
351c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3525fe0d4faSjeremylt 
353d1d35e2fSjeremylt     ierr = CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp,
354d1d35e2fSjeremylt                                      comp_stride, l_size, mem_type, copy_mode,
355d979a051Sjeremylt                                      offsets, rstr); CeedChk(ierr);
356e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
3575fe0d4faSjeremylt   }
3585fe0d4faSjeremylt 
3594ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
3604ce2993fSjeremylt   (*rstr)->ceed = ceed;
3619560d06aSjeremylt   ierr = CeedReference(ceed); CeedChk(ierr);
362d1d35e2fSjeremylt   (*rstr)->ref_count = 1;
363d1d35e2fSjeremylt   (*rstr)->num_elem = num_elem;
364d1d35e2fSjeremylt   (*rstr)->elem_size = elem_size;
365d1d35e2fSjeremylt   (*rstr)->num_comp = num_comp;
366d1d35e2fSjeremylt   (*rstr)->comp_stride = comp_stride;
367d1d35e2fSjeremylt   (*rstr)->l_size = l_size;
368d1d35e2fSjeremylt   (*rstr)->num_blk = num_elem;
369d1d35e2fSjeremylt   (*rstr)->blk_size = 1;
370*b435c5a6Srezgarshakeri   (*rstr)->is_oriented = 0;
371d1d35e2fSjeremylt   ierr = ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr);
372d979a051Sjeremylt   CeedChk(ierr);
373e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
374d7b241e6Sjeremylt }
375d7b241e6Sjeremylt 
376d7b241e6Sjeremylt /**
377fc0567d9Srezgarshakeri   @brief Create a CeedElemRestriction with orientation sign
378fc0567d9Srezgarshakeri 
379fc0567d9Srezgarshakeri   @param ceed         A Ceed object where the CeedElemRestriction will be created
380fc0567d9Srezgarshakeri   @param num_elem     Number of elements described in the @a offsets array
381fc0567d9Srezgarshakeri   @param elem_size    Size (number of "nodes") per element
382fc0567d9Srezgarshakeri   @param num_comp     Number of field components per interpolation node
383fc0567d9Srezgarshakeri                         (1 for scalar fields)
384fc0567d9Srezgarshakeri   @param comp_stride  Stride between components for the same L-vector "node".
385fc0567d9Srezgarshakeri                         Data for node i, component j, element k can be found in
386fc0567d9Srezgarshakeri                         the L-vector at index
387fc0567d9Srezgarshakeri                         offsets[i + k*elem_size] + j*comp_stride.
388fc0567d9Srezgarshakeri   @param l_size       The size of the L-vector. This vector may be larger than
389fc0567d9Srezgarshakeri                         the elements and fields given by this restriction.
390fc0567d9Srezgarshakeri   @param mem_type     Memory type of the @a offsets array, see CeedMemType
391fc0567d9Srezgarshakeri   @param copy_mode    Copy mode for the @a offsets array, see CeedCopyMode
392fc0567d9Srezgarshakeri   @param offsets      Array of shape [@a num_elem, @a elem_size]. Row i holds the
393fc0567d9Srezgarshakeri                         ordered list of the offsets (into the input CeedVector)
394fc0567d9Srezgarshakeri                         for the unknowns corresponding to element i, where
395fc0567d9Srezgarshakeri                         0 <= i < @a num_elem. All offsets must be in the range
396fc0567d9Srezgarshakeri                         [0, @a l_size - 1].
397fc0567d9Srezgarshakeri   @param orient       Array of shape [@a num_elem, @a elem_size] with bool false
398fc0567d9Srezgarshakeri                         for positively oriented and true to flip the orientation.
399fc0567d9Srezgarshakeri   @param[out] rstr    Address of the variable where the newly created
400fc0567d9Srezgarshakeri                         CeedElemRestriction will be stored
401fc0567d9Srezgarshakeri 
402fc0567d9Srezgarshakeri   @return An error code: 0 - success, otherwise - failure
403fc0567d9Srezgarshakeri 
404fc0567d9Srezgarshakeri   @ref User
405fc0567d9Srezgarshakeri **/
406fc0567d9Srezgarshakeri int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem,
407fc0567d9Srezgarshakeri                                       CeedInt elem_size, CeedInt num_comp,
408fc0567d9Srezgarshakeri                                       CeedInt comp_stride, CeedInt l_size,
409fc0567d9Srezgarshakeri                                       CeedMemType mem_type, CeedCopyMode copy_mode,
410fc0567d9Srezgarshakeri                                       const CeedInt *offsets, const bool *orient,
411fc0567d9Srezgarshakeri                                       CeedElemRestriction *rstr) {
412fc0567d9Srezgarshakeri   int ierr;
413fc0567d9Srezgarshakeri 
414c7745053SRezgar Shakeri   if (!ceed->ElemRestrictionCreateOriented) {
415fc0567d9Srezgarshakeri     Ceed delegate;
416fc0567d9Srezgarshakeri     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
417fc0567d9Srezgarshakeri     CeedChk(ierr);
418fc0567d9Srezgarshakeri 
419fc0567d9Srezgarshakeri     if (!delegate)
420fc0567d9Srezgarshakeri       // LCOV_EXCL_START
421fc0567d9Srezgarshakeri       return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
42261e7462cSRezgar Shakeri                        "Backend does not implement ElemRestrictionCreateOriented");
423fc0567d9Srezgarshakeri     // LCOV_EXCL_STOP
424fc0567d9Srezgarshakeri 
425fc0567d9Srezgarshakeri     ierr = CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size,
426c7745053SRezgar Shakeri            num_comp, comp_stride, l_size, mem_type, copy_mode, offsets,
4274dd06d33Srezgarshakeri            orient, rstr); CeedChk(ierr);
428fc0567d9Srezgarshakeri     return CEED_ERROR_SUCCESS;
429fc0567d9Srezgarshakeri   }
430fc0567d9Srezgarshakeri 
431fc0567d9Srezgarshakeri   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
432fc0567d9Srezgarshakeri   (*rstr)->ceed = ceed;
433fc0567d9Srezgarshakeri   ierr = CeedReference(ceed); CeedChk(ierr);
434fc0567d9Srezgarshakeri   (*rstr)->ref_count = 1;
435fc0567d9Srezgarshakeri   (*rstr)->num_elem = num_elem;
436fc0567d9Srezgarshakeri   (*rstr)->elem_size = elem_size;
437fc0567d9Srezgarshakeri   (*rstr)->num_comp = num_comp;
438fc0567d9Srezgarshakeri   (*rstr)->comp_stride = comp_stride;
439fc0567d9Srezgarshakeri   (*rstr)->l_size = l_size;
440fc0567d9Srezgarshakeri   (*rstr)->num_blk = num_elem;
441fc0567d9Srezgarshakeri   (*rstr)->blk_size = 1;
442*b435c5a6Srezgarshakeri   (*rstr)->is_oriented = 1;
4434dd06d33Srezgarshakeri   ierr = ceed->ElemRestrictionCreateOriented(mem_type, copy_mode,
4444dd06d33Srezgarshakeri          offsets, orient, *rstr); CeedChk(ierr);
445fc0567d9Srezgarshakeri   return CEED_ERROR_SUCCESS;
446fc0567d9Srezgarshakeri }
447fc0567d9Srezgarshakeri 
448fc0567d9Srezgarshakeri /**
4497509a596Sjeremylt   @brief Create a strided CeedElemRestriction
450d7b241e6Sjeremylt 
451b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
452d1d35e2fSjeremylt   @param num_elem   Number of elements described by the restriction
453d1d35e2fSjeremylt   @param elem_size  Size (number of "nodes") per element
454d1d35e2fSjeremylt   @param num_comp   Number of field components per interpolation "node"
45595bb1877Svaleriabarra                       (1 for scalar fields)
456d1d35e2fSjeremylt   @param l_size     The size of the L-vector. This vector may be larger than
457d979a051Sjeremylt                       the elements and fields given by this restriction.
4587509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
45995e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
46095e93d34SJeremy L Thompson                       the L-vector at index
46195e93d34SJeremy L Thompson                       i*strides[0] + j*strides[1] + k*strides[2].
46295e93d34SJeremy L Thompson                       @a CEED_STRIDES_BACKEND may be used with vectors created
46395e93d34SJeremy L Thompson                       by a Ceed backend.
4644ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
465b11c1e72Sjeremylt                       CeedElemRestriction will be stored
466d7b241e6Sjeremylt 
467b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
468dfdf5a53Sjeremylt 
4697a982d89SJeremy L. Thompson   @ref User
470b11c1e72Sjeremylt **/
471d1d35e2fSjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem,
472d1d35e2fSjeremylt                                      CeedInt elem_size,
473d1d35e2fSjeremylt                                      CeedInt num_comp, CeedInt l_size,
4748621c6c6SJeremy L Thompson                                      const CeedInt strides[3],
475f90c8643Sjeremylt                                      CeedElemRestriction *rstr) {
476d7b241e6Sjeremylt   int ierr;
477d7b241e6Sjeremylt 
4785fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
4795fe0d4faSjeremylt     Ceed delegate;
480aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
481aefd8378Sjeremylt     CeedChk(ierr);
4825fe0d4faSjeremylt 
4835fe0d4faSjeremylt     if (!delegate)
484c042f62fSJeremy L Thompson       // LCOV_EXCL_START
485e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
486e15f9bd0SJeremy L Thompson                        "Backend does not support ElemRestrictionCreate");
487c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
4885fe0d4faSjeremylt 
489d1d35e2fSjeremylt     ierr = CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp,
490d1d35e2fSjeremylt                                             l_size, strides, rstr);
491d979a051Sjeremylt     CeedChk(ierr);
492e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
4935fe0d4faSjeremylt   }
4945fe0d4faSjeremylt 
4954ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
4964ce2993fSjeremylt   (*rstr)->ceed = ceed;
4979560d06aSjeremylt   ierr = CeedReference(ceed); CeedChk(ierr);
498d1d35e2fSjeremylt   (*rstr)->ref_count = 1;
499d1d35e2fSjeremylt   (*rstr)->num_elem = num_elem;
500d1d35e2fSjeremylt   (*rstr)->elem_size = elem_size;
501d1d35e2fSjeremylt   (*rstr)->num_comp = num_comp;
502d1d35e2fSjeremylt   (*rstr)->l_size = l_size;
503d1d35e2fSjeremylt   (*rstr)->num_blk = num_elem;
504d1d35e2fSjeremylt   (*rstr)->blk_size = 1;
505*b435c5a6Srezgarshakeri   (*rstr)->is_oriented = 0;
5067509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
5077509a596Sjeremylt   for (int i=0; i<3; i++)
5087509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
5091dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
5101dfeef1dSjeremylt                                      *rstr);
5114b8bea3bSJed Brown   CeedChk(ierr);
512e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
513d7b241e6Sjeremylt }
514d7b241e6Sjeremylt 
515d7b241e6Sjeremylt /**
516b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
517d7b241e6Sjeremylt 
518d7b241e6Sjeremylt   @param ceed         A Ceed object where the CeedElemRestriction will be created.
519d1d35e2fSjeremylt   @param num_elem     Number of elements described in the @a offsets array.
520d1d35e2fSjeremylt   @param elem_size    Size (number of unknowns) per element
521d1d35e2fSjeremylt   @param blk_size     Number of elements in a block
522d1d35e2fSjeremylt   @param num_comp     Number of field components per interpolation node
52395bb1877Svaleriabarra                         (1 for scalar fields)
524d1d35e2fSjeremylt   @param comp_stride  Stride between components for the same L-vector "node".
52595e93d34SJeremy L Thompson                         Data for node i, component j, element k can be found in
52695e93d34SJeremy L Thompson                         the L-vector at index
527d1d35e2fSjeremylt                         offsets[i + k*elem_size] + j*comp_stride.
528d1d35e2fSjeremylt   @param l_size       The size of the L-vector. This vector may be larger than
529d979a051Sjeremylt                         the elements and fields given by this restriction.
530d1d35e2fSjeremylt   @param mem_type     Memory type of the @a offsets array, see CeedMemType
531d1d35e2fSjeremylt   @param copy_mode    Copy mode for the @a offsets array, see CeedCopyMode
532d1d35e2fSjeremylt   @param offsets      Array of shape [@a num_elem, @a elem_size]. Row i holds the
533d979a051Sjeremylt                         ordered list of the offsets (into the input CeedVector)
5348795c945Sjeremylt                         for the unknowns corresponding to element i, where
535d1d35e2fSjeremylt                         0 <= i < @a num_elem. All offsets must be in the range
536d1d35e2fSjeremylt                         [0, @a l_size - 1]. The backend will permute and pad this
5378795c945Sjeremylt                         array to the desired ordering for the blocksize, which is
5388795c945Sjeremylt                         typically given by the backend. The default reordering is
5398795c945Sjeremylt                         to interlace elements.
5404ce2993fSjeremylt   @param rstr         Address of the variable where the newly created
541b11c1e72Sjeremylt                         CeedElemRestriction will be stored
542d7b241e6Sjeremylt 
543b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
544dfdf5a53Sjeremylt 
5457a982d89SJeremy L. Thompson   @ref Backend
546b11c1e72Sjeremylt  **/
547d1d35e2fSjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem,
548d1d35e2fSjeremylt                                      CeedInt elem_size,
549d1d35e2fSjeremylt                                      CeedInt blk_size, CeedInt num_comp,
550d1d35e2fSjeremylt                                      CeedInt comp_stride, CeedInt l_size,
551d1d35e2fSjeremylt                                      CeedMemType mem_type, CeedCopyMode copy_mode,
552d979a051Sjeremylt                                      const CeedInt *offsets,
5534ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
554d7b241e6Sjeremylt   int ierr;
555d1d35e2fSjeremylt   CeedInt *blk_offsets;
556d1d35e2fSjeremylt   CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size);
557d7b241e6Sjeremylt 
5585fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
5595fe0d4faSjeremylt     Ceed delegate;
560aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
561aefd8378Sjeremylt     CeedChk(ierr);
5625fe0d4faSjeremylt 
5635fe0d4faSjeremylt     if (!delegate)
564c042f62fSJeremy L Thompson       // LCOV_EXCL_START
565e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support "
5661d102b48SJeremy L Thompson                        "ElemRestrictionCreateBlocked");
567c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
5685fe0d4faSjeremylt 
569d1d35e2fSjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size,
570d1d35e2fSjeremylt                                             num_comp, comp_stride, l_size, mem_type,
571d1d35e2fSjeremylt                                             copy_mode, offsets, rstr);
572d979a051Sjeremylt     CeedChk(ierr);
573e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
5745fe0d4faSjeremylt   }
575d7b241e6Sjeremylt 
5764ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
577d7b241e6Sjeremylt 
578d1d35e2fSjeremylt   ierr = CeedCalloc(num_blk*blk_size*elem_size, &blk_offsets); CeedChk(ierr);
579d1d35e2fSjeremylt   ierr = CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size,
580d1d35e2fSjeremylt                                elem_size); CeedChk(ierr);
581d7b241e6Sjeremylt 
5824ce2993fSjeremylt   (*rstr)->ceed = ceed;
5839560d06aSjeremylt   ierr = CeedReference(ceed); CeedChk(ierr);
584d1d35e2fSjeremylt   (*rstr)->ref_count = 1;
585d1d35e2fSjeremylt   (*rstr)->num_elem = num_elem;
586d1d35e2fSjeremylt   (*rstr)->elem_size = elem_size;
587d1d35e2fSjeremylt   (*rstr)->num_comp = num_comp;
588d1d35e2fSjeremylt   (*rstr)->comp_stride = comp_stride;
589d1d35e2fSjeremylt   (*rstr)->l_size = l_size;
590d1d35e2fSjeremylt   (*rstr)->num_blk = num_blk;
591d1d35e2fSjeremylt   (*rstr)->blk_size = blk_size;
592*b435c5a6Srezgarshakeri   (*rstr)->is_oriented = 0;
593667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
594d1d35e2fSjeremylt          (const CeedInt *) blk_offsets, *rstr); CeedChk(ierr);
595d1d35e2fSjeremylt   if (copy_mode == CEED_OWN_POINTER) {
596d979a051Sjeremylt     ierr = CeedFree(&offsets); CeedChk(ierr);
5971d102b48SJeremy L Thompson   }
598e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
599d7b241e6Sjeremylt }
600d7b241e6Sjeremylt 
601b11c1e72Sjeremylt /**
6027509a596Sjeremylt   @brief Create a blocked strided CeedElemRestriction
6037509a596Sjeremylt 
6047509a596Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
605d1d35e2fSjeremylt   @param num_elem   Number of elements described by the restriction
606d1d35e2fSjeremylt   @param elem_size  Size (number of "nodes") per element
607d1d35e2fSjeremylt   @param blk_size   Number of elements in a block
608d1d35e2fSjeremylt   @param num_comp   Number of field components per interpolation node
6097509a596Sjeremylt                       (1 for scalar fields)
610d1d35e2fSjeremylt   @param l_size     The size of the L-vector. This vector may be larger than
611d979a051Sjeremylt                       the elements and fields given by this restriction.
6127509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
61395e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
61495e93d34SJeremy L Thompson                       the L-vector at index
61595e93d34SJeremy L Thompson                       i*strides[0] + j*strides[1] + k*strides[2].
61695e93d34SJeremy L Thompson                       @a CEED_STRIDES_BACKEND may be used with vectors created
61795e93d34SJeremy L Thompson                       by a Ceed backend.
6187509a596Sjeremylt   @param rstr       Address of the variable where the newly created
6197509a596Sjeremylt                       CeedElemRestriction will be stored
6207509a596Sjeremylt 
6217509a596Sjeremylt   @return An error code: 0 - success, otherwise - failure
6227509a596Sjeremylt 
6237a982d89SJeremy L. Thompson   @ref User
6247509a596Sjeremylt **/
625d1d35e2fSjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem,
626d1d35e2fSjeremylt     CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt l_size,
6278621c6c6SJeremy L Thompson     const CeedInt strides[3], CeedElemRestriction *rstr) {
6287509a596Sjeremylt   int ierr;
629d1d35e2fSjeremylt   CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size);
6307509a596Sjeremylt 
6317509a596Sjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
6327509a596Sjeremylt     Ceed delegate;
6337509a596Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
6347509a596Sjeremylt     CeedChk(ierr);
6357509a596Sjeremylt 
6367509a596Sjeremylt     if (!delegate)
6377509a596Sjeremylt       // LCOV_EXCL_START
638e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support "
6397509a596Sjeremylt                        "ElemRestrictionCreateBlocked");
6407509a596Sjeremylt     // LCOV_EXCL_STOP
6417509a596Sjeremylt 
642d1d35e2fSjeremylt     ierr = CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size,
643d1d35e2fSjeremylt            blk_size, num_comp, l_size, strides, rstr); CeedChk(ierr);
644e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
6457509a596Sjeremylt   }
6467509a596Sjeremylt 
6477509a596Sjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
6487509a596Sjeremylt 
6497509a596Sjeremylt   (*rstr)->ceed = ceed;
6509560d06aSjeremylt   ierr = CeedReference(ceed); CeedChk(ierr);
651d1d35e2fSjeremylt   (*rstr)->ref_count = 1;
652d1d35e2fSjeremylt   (*rstr)->num_elem = num_elem;
653d1d35e2fSjeremylt   (*rstr)->elem_size = elem_size;
654d1d35e2fSjeremylt   (*rstr)->num_comp = num_comp;
655d1d35e2fSjeremylt   (*rstr)->l_size = l_size;
656d1d35e2fSjeremylt   (*rstr)->num_blk = num_blk;
657d1d35e2fSjeremylt   (*rstr)->blk_size = blk_size;
658*b435c5a6Srezgarshakeri   (*rstr)->is_oriented = 0;
6597509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
6607509a596Sjeremylt   for (int i=0; i<3; i++)
6617509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
6627509a596Sjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
6637509a596Sjeremylt          NULL, *rstr); CeedChk(ierr);
664e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
6657509a596Sjeremylt }
6667509a596Sjeremylt 
6677509a596Sjeremylt /**
6689560d06aSjeremylt   @brief Copy the pointer to a CeedElemRestriction. Both pointers should
6699560d06aSjeremylt            be destroyed with `CeedElemRestrictionDestroy()`;
6709560d06aSjeremylt            Note: If `*rstr_copy` is non-NULL, then it is assumed that
6719560d06aSjeremylt            `*rstr_copy` is a pointer to a CeedElemRestriction. This
6729560d06aSjeremylt            CeedElemRestriction will be destroyed if `*rstr_copy` is the
6739560d06aSjeremylt            only reference to this CeedElemRestriction.
6749560d06aSjeremylt 
6759560d06aSjeremylt   @param rstr            CeedElemRestriction to copy reference to
6769560d06aSjeremylt   @param[out] rstr_copy  Variable to store copied reference
6779560d06aSjeremylt 
6789560d06aSjeremylt   @return An error code: 0 - success, otherwise - failure
6799560d06aSjeremylt 
6809560d06aSjeremylt   @ref User
6819560d06aSjeremylt **/
6829560d06aSjeremylt int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr,
6839560d06aSjeremylt                                      CeedElemRestriction *rstr_copy) {
6849560d06aSjeremylt   int ierr;
6859560d06aSjeremylt 
6869560d06aSjeremylt   ierr = CeedElemRestrictionReference(rstr); CeedChk(ierr);
6879560d06aSjeremylt   ierr = CeedElemRestrictionDestroy(rstr_copy); CeedChk(ierr);
6889560d06aSjeremylt   *rstr_copy = rstr;
6899560d06aSjeremylt   return CEED_ERROR_SUCCESS;
6909560d06aSjeremylt }
6919560d06aSjeremylt 
6929560d06aSjeremylt /**
693b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
694b11c1e72Sjeremylt 
6954ce2993fSjeremylt   @param rstr   CeedElemRestriction
696d1d35e2fSjeremylt   @param l_vec  The address of the L-vector to be created, or NULL
697d1d35e2fSjeremylt   @param e_vec  The address of the E-vector to be created, or NULL
698b11c1e72Sjeremylt 
699b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
700dfdf5a53Sjeremylt 
7017a982d89SJeremy L. Thompson   @ref User
702b11c1e72Sjeremylt **/
703d1d35e2fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec,
704d1d35e2fSjeremylt                                     CeedVector *e_vec) {
705d7b241e6Sjeremylt   int ierr;
706d1d35e2fSjeremylt   CeedInt e_size, l_size;
707d1d35e2fSjeremylt   l_size = rstr->l_size;
708d1d35e2fSjeremylt   e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp;
709d1d35e2fSjeremylt   if (l_vec) {
710d1d35e2fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, l_size, l_vec); CeedChk(ierr);
711d7b241e6Sjeremylt   }
712d1d35e2fSjeremylt   if (e_vec) {
713d1d35e2fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, e_size, e_vec); CeedChk(ierr);
714d7b241e6Sjeremylt   }
715e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
716d7b241e6Sjeremylt }
717d7b241e6Sjeremylt 
718d7b241e6Sjeremylt /**
719d9e1f99aSValeria Barra   @brief Restrict an L-vector to an E-vector or apply its transpose
720d7b241e6Sjeremylt 
7214ce2993fSjeremylt   @param rstr    CeedElemRestriction
722d1d35e2fSjeremylt   @param t_mode  Apply restriction or transpose
723d1d35e2fSjeremylt   @param u       Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE)
724d1d35e2fSjeremylt   @param ru      Output vector (of shape [@a num_elem * @a elem_size] when
725d1d35e2fSjeremylt                    t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
7267aaeacdcSjeremylt                    by the backend.
7274cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
728b11c1e72Sjeremylt 
729b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
730dfdf5a53Sjeremylt 
7317a982d89SJeremy L. Thompson   @ref User
732b11c1e72Sjeremylt **/
733d1d35e2fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode,
734a8d32208Sjeremylt                              CeedVector u, CeedVector ru,
735a8d32208Sjeremylt                              CeedRequest *request) {
736d7b241e6Sjeremylt   CeedInt m, n;
737d7b241e6Sjeremylt   int ierr;
738d7b241e6Sjeremylt 
739d1d35e2fSjeremylt   if (t_mode == CEED_NOTRANSPOSE) {
740d1d35e2fSjeremylt     m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp;
741d1d35e2fSjeremylt     n = rstr->l_size;
742d7b241e6Sjeremylt   } else {
743d1d35e2fSjeremylt     m = rstr->l_size;
744d1d35e2fSjeremylt     n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp;
745d7b241e6Sjeremylt   }
746d7b241e6Sjeremylt   if (n != u->length)
747c042f62fSJeremy L Thompson     // LCOV_EXCL_START
748e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
749e15f9bd0SJeremy L Thompson                      "Input vector size %d not compatible with "
7501d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
751c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
752a8d32208Sjeremylt   if (m != ru->length)
753c042f62fSJeremy L Thompson     // LCOV_EXCL_START
754e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
755e15f9bd0SJeremy L Thompson                      "Output vector size %d not compatible with "
756a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
757c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
758d1d35e2fSjeremylt   ierr = rstr->Apply(rstr, t_mode, u, ru, request); CeedChk(ierr);
759e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
760d7b241e6Sjeremylt }
761d7b241e6Sjeremylt 
762d7b241e6Sjeremylt /**
763d9e1f99aSValeria Barra   @brief Restrict an L-vector to a block of an E-vector or apply its transpose
764be9261b7Sjeremylt 
765be9261b7Sjeremylt   @param rstr    CeedElemRestriction
7661f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
767d1d35e2fSjeremylt                    elements [0 : blk_size] and block=3 will handle elements
768d1d35e2fSjeremylt                    [3*blk_size : 4*blk_size]
769d1d35e2fSjeremylt   @param t_mode  Apply restriction or transpose
770d1d35e2fSjeremylt   @param u       Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE)
771d1d35e2fSjeremylt   @param ru      Output vector (of shape [@a blk_size * @a elem_size] when
772d1d35e2fSjeremylt                    t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
7737aaeacdcSjeremylt                    by the backend.
7744cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
775be9261b7Sjeremylt 
776be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
777be9261b7Sjeremylt 
7787a982d89SJeremy L. Thompson   @ref Backend
779be9261b7Sjeremylt **/
780be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
781d1d35e2fSjeremylt                                   CeedTransposeMode t_mode, CeedVector u,
782a8d32208Sjeremylt                                   CeedVector ru, CeedRequest *request) {
783be9261b7Sjeremylt   CeedInt m, n;
784be9261b7Sjeremylt   int ierr;
785be9261b7Sjeremylt 
786d1d35e2fSjeremylt   if (t_mode == CEED_NOTRANSPOSE) {
787d1d35e2fSjeremylt     m = rstr->blk_size * rstr->elem_size * rstr->num_comp;
788d1d35e2fSjeremylt     n = rstr->l_size;
789be9261b7Sjeremylt   } else {
790d1d35e2fSjeremylt     m = rstr->l_size;
791d1d35e2fSjeremylt     n = rstr->blk_size * rstr->elem_size * rstr->num_comp;
792be9261b7Sjeremylt   }
793be9261b7Sjeremylt   if (n != u->length)
794c042f62fSJeremy L Thompson     // LCOV_EXCL_START
795e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
796e15f9bd0SJeremy L Thompson                      "Input vector size %d not compatible with "
7971d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
798c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
799a8d32208Sjeremylt   if (m != ru->length)
800c042f62fSJeremy L Thompson     // LCOV_EXCL_START
801e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
802e15f9bd0SJeremy L Thompson                      "Output vector size %d not compatible with "
803a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
804c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
805d1d35e2fSjeremylt   if (rstr->blk_size*block > rstr->num_elem)
806c042f62fSJeremy L Thompson     // LCOV_EXCL_START
807e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
808e15f9bd0SJeremy L Thompson                      "Cannot retrieve block %d, element %d > "
809d1d35e2fSjeremylt                      "total elements %d", block, rstr->blk_size*block,
810d1d35e2fSjeremylt                      rstr->num_elem);
811c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
812d1d35e2fSjeremylt   ierr = rstr->ApplyBlock(rstr, block, t_mode, u, ru, request);
813be9261b7Sjeremylt   CeedChk(ierr);
814e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
815be9261b7Sjeremylt }
816be9261b7Sjeremylt 
817be9261b7Sjeremylt /**
818b7c9bbdaSJeremy L Thompson   @brief Get the Ceed associated with a CeedElemRestriction
819b7c9bbdaSJeremy L Thompson 
820b7c9bbdaSJeremy L Thompson   @param rstr       CeedElemRestriction
821b7c9bbdaSJeremy L Thompson   @param[out] ceed  Variable to store Ceed
822b7c9bbdaSJeremy L Thompson 
823b7c9bbdaSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
824b7c9bbdaSJeremy L Thompson 
825b7c9bbdaSJeremy L Thompson   @ref Advanced
826b7c9bbdaSJeremy L Thompson **/
827b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) {
828b7c9bbdaSJeremy L Thompson   *ceed = rstr->ceed;
829b7c9bbdaSJeremy L Thompson   return CEED_ERROR_SUCCESS;
830b7c9bbdaSJeremy L Thompson }
831b7c9bbdaSJeremy L Thompson 
832b7c9bbdaSJeremy L Thompson /**
833d979a051Sjeremylt   @brief Get the L-vector component stride
834a681ae63Sjeremylt 
835a681ae63Sjeremylt   @param rstr              CeedElemRestriction
836d1d35e2fSjeremylt   @param[out] comp_stride  Variable to store component stride
837a681ae63Sjeremylt 
838a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
839a681ae63Sjeremylt 
840b7c9bbdaSJeremy L Thompson   @ref Advanced
841a681ae63Sjeremylt **/
842d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr,
843d1d35e2fSjeremylt                                      CeedInt *comp_stride) {
844d1d35e2fSjeremylt   *comp_stride = rstr->comp_stride;
845e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
846a681ae63Sjeremylt }
847a681ae63Sjeremylt 
848a681ae63Sjeremylt /**
849a681ae63Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
850a681ae63Sjeremylt 
851a681ae63Sjeremylt   @param rstr           CeedElemRestriction
852d1d35e2fSjeremylt   @param[out] num_elem  Variable to store number of elements
853a681ae63Sjeremylt 
854a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
855a681ae63Sjeremylt 
856b7c9bbdaSJeremy L Thompson   @ref Advanced
857a681ae63Sjeremylt **/
858a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
859d1d35e2fSjeremylt                                       CeedInt *num_elem) {
860d1d35e2fSjeremylt   *num_elem = rstr->num_elem;
861e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
862a681ae63Sjeremylt }
863a681ae63Sjeremylt 
864a681ae63Sjeremylt /**
865a681ae63Sjeremylt   @brief Get the size of elements in the CeedElemRestriction
866a681ae63Sjeremylt 
867a681ae63Sjeremylt   @param rstr            CeedElemRestriction
868d1d35e2fSjeremylt   @param[out] elem_size  Variable to store size of elements
869a681ae63Sjeremylt 
870a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
871a681ae63Sjeremylt 
872b7c9bbdaSJeremy L Thompson   @ref Advanced
873a681ae63Sjeremylt **/
874a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
875d1d35e2fSjeremylt                                       CeedInt *elem_size) {
876d1d35e2fSjeremylt   *elem_size = rstr->elem_size;
877e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
878a681ae63Sjeremylt }
879a681ae63Sjeremylt 
880a681ae63Sjeremylt /**
881d979a051Sjeremylt   @brief Get the size of the l-vector for a CeedElemRestriction
882a681ae63Sjeremylt 
883a681ae63Sjeremylt   @param rstr         CeedElemRestriction
884d1d35e2fSjeremylt   @param[out] l_size  Variable to store number of nodes
885a681ae63Sjeremylt 
886a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
887a681ae63Sjeremylt 
888b7c9bbdaSJeremy L Thompson   @ref Advanced
889a681ae63Sjeremylt **/
890d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr,
891d1d35e2fSjeremylt                                       CeedInt *l_size) {
892d1d35e2fSjeremylt   *l_size = rstr->l_size;
893e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
894a681ae63Sjeremylt }
895a681ae63Sjeremylt 
896a681ae63Sjeremylt /**
897a681ae63Sjeremylt   @brief Get the number of components in the elements of a
898a681ae63Sjeremylt          CeedElemRestriction
899a681ae63Sjeremylt 
900a681ae63Sjeremylt   @param rstr           CeedElemRestriction
901d1d35e2fSjeremylt   @param[out] num_comp  Variable to store number of components
902a681ae63Sjeremylt 
903a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
904a681ae63Sjeremylt 
905b7c9bbdaSJeremy L Thompson   @ref Advanced
906a681ae63Sjeremylt **/
907a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
908d1d35e2fSjeremylt                                         CeedInt *num_comp) {
909d1d35e2fSjeremylt   *num_comp = rstr->num_comp;
910e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
911a681ae63Sjeremylt }
912a681ae63Sjeremylt 
913a681ae63Sjeremylt /**
914a681ae63Sjeremylt   @brief Get the number of blocks in a CeedElemRestriction
915a681ae63Sjeremylt 
916a681ae63Sjeremylt   @param rstr            CeedElemRestriction
917d1d35e2fSjeremylt   @param[out] num_block  Variable to store number of blocks
918a681ae63Sjeremylt 
919a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
920a681ae63Sjeremylt 
921b7c9bbdaSJeremy L Thompson   @ref Advanced
922a681ae63Sjeremylt **/
923a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
924d1d35e2fSjeremylt                                     CeedInt *num_block) {
925d1d35e2fSjeremylt   *num_block = rstr->num_blk;
926e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
927a681ae63Sjeremylt }
928a681ae63Sjeremylt 
929a681ae63Sjeremylt /**
930a681ae63Sjeremylt   @brief Get the size of blocks in the CeedElemRestriction
931a681ae63Sjeremylt 
932a681ae63Sjeremylt   @param rstr           CeedElemRestriction
933d1d35e2fSjeremylt   @param[out] blk_size  Variable to store size of blocks
934a681ae63Sjeremylt 
935a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
936a681ae63Sjeremylt 
937b7c9bbdaSJeremy L Thompson   @ref Advanced
938a681ae63Sjeremylt **/
939a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
940d1d35e2fSjeremylt                                     CeedInt *blk_size) {
941d1d35e2fSjeremylt   *blk_size = rstr->blk_size;
942e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
943a681ae63Sjeremylt }
944a681ae63Sjeremylt 
945a681ae63Sjeremylt /**
946d9e1f99aSValeria Barra   @brief Get the multiplicity of nodes in a CeedElemRestriction
9471469ee4dSjeremylt 
9481469ee4dSjeremylt   @param rstr       CeedElemRestriction
949d1d35e2fSjeremylt   @param[out] mult  Vector to store multiplicity (of size l_size)
9501469ee4dSjeremylt 
9511469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
9521469ee4dSjeremylt 
9537a982d89SJeremy L. Thompson   @ref User
9541469ee4dSjeremylt **/
9551469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
9561469ee4dSjeremylt                                        CeedVector mult) {
9571469ee4dSjeremylt   int ierr;
958d1d35e2fSjeremylt   CeedVector e_vec;
9591469ee4dSjeremylt 
96025509ebbSRezgar Shakeri   // Create e_vec to hold intermediate computation in E^T (E 1)
961d1d35e2fSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &e_vec); CeedChk(ierr);
9621469ee4dSjeremylt 
96325509ebbSRezgar Shakeri   // Compute e_vec = E * 1
96425509ebbSRezgar Shakeri   ierr = CeedVectorSetValue(mult, 1.0); CeedChk(ierr);
96525509ebbSRezgar Shakeri   ierr = CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec,
96625509ebbSRezgar Shakeri                                   CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
96725509ebbSRezgar Shakeri   // Compute multiplicity, mult = E^T * e_vec = E^T (E 1)
96825509ebbSRezgar Shakeri   ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr);
969d1d35e2fSjeremylt   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult,
970efc78312Sjeremylt                                   CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
9711469ee4dSjeremylt   // Cleanup
972d1d35e2fSjeremylt   ierr = CeedVectorDestroy(&e_vec); CeedChk(ierr);
973e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
9741469ee4dSjeremylt }
9751469ee4dSjeremylt 
9761469ee4dSjeremylt /**
977f02ca4a2SJed Brown   @brief View a CeedElemRestriction
978f02ca4a2SJed Brown 
979f02ca4a2SJed Brown   @param[in] rstr    CeedElemRestriction to view
980f02ca4a2SJed Brown   @param[in] stream  Stream to write; typically stdout/stderr or a file
981f02ca4a2SJed Brown 
982f02ca4a2SJed Brown   @return Error code: 0 - success, otherwise - failure
983f02ca4a2SJed Brown 
9847a982d89SJeremy L. Thompson   @ref User
985f02ca4a2SJed Brown **/
986f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
9877509a596Sjeremylt   char stridesstr[500];
9887509a596Sjeremylt   if (rstr->strides)
9897509a596Sjeremylt     sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1],
9907509a596Sjeremylt             rstr->strides[2]);
991d979a051Sjeremylt   else
992d1d35e2fSjeremylt     sprintf(stridesstr, "%d", rstr->comp_stride);
9937509a596Sjeremylt 
9940036de2cSjeremylt   fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d "
995d1d35e2fSjeremylt           "nodes each and %s %s\n", rstr->blk_size > 1 ? "Blocked " : "",
996d1d35e2fSjeremylt           rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size,
997d979a051Sjeremylt           rstr->strides ? "strides" : "component stride", stridesstr);
998e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
999f02ca4a2SJed Brown }
1000f02ca4a2SJed Brown 
1001f02ca4a2SJed Brown /**
1002b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
1003b11c1e72Sjeremylt 
10044ce2993fSjeremylt   @param rstr  CeedElemRestriction to destroy
1005b11c1e72Sjeremylt 
1006b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
1007dfdf5a53Sjeremylt 
10087a982d89SJeremy L. Thompson   @ref User
1009b11c1e72Sjeremylt **/
10104ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
1011d7b241e6Sjeremylt   int ierr;
1012d7b241e6Sjeremylt 
1013d1d35e2fSjeremylt   if (!*rstr || --(*rstr)->ref_count > 0) return CEED_ERROR_SUCCESS;
1014d1d35e2fSjeremylt   if ((*rstr)->num_readers)
10158229195eSjeremylt     // LCOV_EXCL_START
1016e15f9bd0SJeremy L Thompson     return CeedError((*rstr)->ceed, CEED_ERROR_ACCESS,
1017e15f9bd0SJeremy L Thompson                      "Cannot destroy CeedElemRestriction, "
1018430758c8SJeremy L Thompson                      "a process has read access to the offset data");
10198229195eSjeremylt   // LCOV_EXCL_STOP
10204ce2993fSjeremylt   if ((*rstr)->Destroy) {
10214ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
1022d7b241e6Sjeremylt   }
10237509a596Sjeremylt   ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr);
10244ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
10254ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
1026e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1027d7b241e6Sjeremylt }
1028d7b241e6Sjeremylt 
1029d7b241e6Sjeremylt /// @}
1030