xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-elemrestriction.c (revision fc0567d9dd43c4a8f0744c44d73ac6beb4777ae6)
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 /**
156a681ae63Sjeremylt   @brief Get the backend stride status of a CeedElemRestriction
1577a982d89SJeremy L. Thompson 
1587a982d89SJeremy L. Thompson   @param rstr                      CeedElemRestriction
15996b902e2Sjeremylt   @param[out] has_backend_strides  Variable to store stride status
1607a982d89SJeremy L. Thompson 
1617a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
1627a982d89SJeremy L. Thompson 
1637a982d89SJeremy L. Thompson   @ref Backend
1647a982d89SJeremy L. Thompson **/
165fd364f38SJeremy L Thompson int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr,
166d1d35e2fSjeremylt     bool *has_backend_strides) {
167a681ae63Sjeremylt   if (!rstr->strides)
168a681ae63Sjeremylt     // LCOV_EXCL_START
169e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_MINOR,
170e15f9bd0SJeremy L Thompson                      "ElemRestriction has no stride data");
171a681ae63Sjeremylt   // LCOV_EXCL_STOP
1727a982d89SJeremy L. Thompson 
173d1d35e2fSjeremylt   *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) &&
174a681ae63Sjeremylt                           (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) &&
175a681ae63Sjeremylt                           (rstr->strides[2] == CEED_STRIDES_BACKEND[2]));
176e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1777a982d89SJeremy L. Thompson }
1787a982d89SJeremy L. Thompson 
1797a982d89SJeremy L. Thompson /**
18049fd234cSJeremy L Thompson 
18149fd234cSJeremy L Thompson   @brief Get the E-vector layout of a CeedElemRestriction
18249fd234cSJeremy L Thompson 
18349fd234cSJeremy L Thompson   @param rstr         CeedElemRestriction
18449fd234cSJeremy L Thompson   @param[out] layout  Variable to store layout array,
18549fd234cSJeremy L Thompson                         stored as [nodes, components, elements].
18649fd234cSJeremy L Thompson                         The data for node i, component j, element k in the
18749fd234cSJeremy L Thompson                         E-vector is given by
18895e93d34SJeremy L Thompson                         i*layout[0] + j*layout[1] + k*layout[2]
18949fd234cSJeremy L Thompson 
19049fd234cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
19149fd234cSJeremy L Thompson 
19249fd234cSJeremy L Thompson   @ref Backend
19349fd234cSJeremy L Thompson **/
19449fd234cSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr,
19549fd234cSJeremy L Thompson                                   CeedInt (*layout)[3]) {
19649fd234cSJeremy L Thompson   if (!rstr->layout[0])
19749fd234cSJeremy L Thompson     // LCOV_EXCL_START
198e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_MINOR,
199e15f9bd0SJeremy L Thompson                      "ElemRestriction has no layout data");
20049fd234cSJeremy L Thompson   // LCOV_EXCL_STOP
20149fd234cSJeremy L Thompson 
20249fd234cSJeremy L Thompson   for (int i=0; i<3; i++)
20349fd234cSJeremy L Thompson     (*layout)[i] = rstr->layout[i];
204e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
20549fd234cSJeremy L Thompson }
20649fd234cSJeremy L Thompson 
20749fd234cSJeremy L Thompson /**
20849fd234cSJeremy L Thompson 
20949fd234cSJeremy L Thompson   @brief Set the E-vector layout of a CeedElemRestriction
21049fd234cSJeremy L Thompson 
21149fd234cSJeremy L Thompson   @param rstr    CeedElemRestriction
21249fd234cSJeremy L Thompson   @param layout  Variable to containing layout array,
21349fd234cSJeremy L Thompson                    stored as [nodes, components, elements].
21449fd234cSJeremy L Thompson                    The data for node i, component j, element k in the
21549fd234cSJeremy L Thompson                    E-vector is given by
21695e93d34SJeremy L Thompson                    i*layout[0] + j*layout[1] + k*layout[2]
21749fd234cSJeremy L Thompson 
21849fd234cSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
21949fd234cSJeremy L Thompson 
22049fd234cSJeremy L Thompson   @ref Backend
22149fd234cSJeremy L Thompson **/
22249fd234cSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr,
22349fd234cSJeremy L Thompson                                   CeedInt layout[3]) {
22449fd234cSJeremy L Thompson   for (int i = 0; i<3; i++)
22549fd234cSJeremy L Thompson     rstr->layout[i] = layout[i];
226e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
22749fd234cSJeremy L Thompson }
22849fd234cSJeremy L Thompson 
22949fd234cSJeremy L Thompson /**
2307a982d89SJeremy L. Thompson   @brief Get the backend data of a CeedElemRestriction
2317a982d89SJeremy L. Thompson 
2327a982d89SJeremy L. Thompson   @param rstr       CeedElemRestriction
2337a982d89SJeremy L. Thompson   @param[out] data  Variable to store data
2347a982d89SJeremy L. Thompson 
2357a982d89SJeremy L. Thompson   @return An error code: 0 - success, otherwise - failure
2367a982d89SJeremy L. Thompson 
2377a982d89SJeremy L. Thompson   @ref Backend
2387a982d89SJeremy L. Thompson **/
239777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) {
240777ff853SJeremy L Thompson   *(void **)data = rstr->data;
241e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2427a982d89SJeremy L. Thompson }
2437a982d89SJeremy L. Thompson 
2447a982d89SJeremy L. Thompson /**
2457a982d89SJeremy L. Thompson   @brief Set the backend data of a CeedElemRestriction
2467a982d89SJeremy L. Thompson 
2477a982d89SJeremy L. Thompson   @param[out] rstr  CeedElemRestriction
2487a982d89SJeremy L. Thompson   @param data       Data to set
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 CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) {
255777ff853SJeremy L Thompson   rstr->data = data;
256e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2577a982d89SJeremy L. Thompson }
2587a982d89SJeremy L. Thompson 
25934359f16Sjeremylt /**
26034359f16Sjeremylt   @brief Increment the reference counter for a CeedElemRestriction
26134359f16Sjeremylt 
26234359f16Sjeremylt   @param rstr  ElemRestriction to increment the reference counter
26334359f16Sjeremylt 
26434359f16Sjeremylt   @return An error code: 0 - success, otherwise - failure
26534359f16Sjeremylt 
26634359f16Sjeremylt   @ref Backend
26734359f16Sjeremylt **/
2689560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) {
26934359f16Sjeremylt   rstr->ref_count++;
27034359f16Sjeremylt   return CEED_ERROR_SUCCESS;
27134359f16Sjeremylt }
27234359f16Sjeremylt 
2737a982d89SJeremy L. Thompson /// @}
2747a982d89SJeremy L. Thompson 
27515910d16Sjeremylt /// @cond DOXYGEN_SKIP
27615910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none;
27715910d16Sjeremylt /// @endcond
27815910d16Sjeremylt 
2797a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2807a982d89SJeremy L. Thompson /// CeedElemRestriction Public API
2817a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2827a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser
283d7b241e6Sjeremylt /// @{
284d7b241e6Sjeremylt 
2857a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend
28645f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0};
2877a982d89SJeremy L. Thompson 
2884cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user
2897a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE =
2907a982d89SJeremy L. Thompson   &ceed_elemrestriction_none;
2917a982d89SJeremy L. Thompson 
292d7b241e6Sjeremylt /**
293b11c1e72Sjeremylt   @brief Create a CeedElemRestriction
294d7b241e6Sjeremylt 
295b11c1e72Sjeremylt   @param ceed         A Ceed object where the CeedElemRestriction will be created
296d1d35e2fSjeremylt   @param num_elem     Number of elements described in the @a offsets array
297d1d35e2fSjeremylt   @param elem_size    Size (number of "nodes") per element
298d1d35e2fSjeremylt   @param num_comp     Number of field components per interpolation node
29995bb1877Svaleriabarra                         (1 for scalar fields)
300d1d35e2fSjeremylt   @param comp_stride  Stride between components for the same L-vector "node".
30195e93d34SJeremy L Thompson                         Data for node i, component j, element k can be found in
30295e93d34SJeremy L Thompson                         the L-vector at index
303d1d35e2fSjeremylt                         offsets[i + k*elem_size] + j*comp_stride.
304d1d35e2fSjeremylt   @param l_size       The size of the L-vector. This vector may be larger than
305d979a051Sjeremylt                         the elements and fields given by this restriction.
306d1d35e2fSjeremylt   @param mem_type     Memory type of the @a offsets array, see CeedMemType
307d1d35e2fSjeremylt   @param copy_mode    Copy mode for the @a offsets array, see CeedCopyMode
308d1d35e2fSjeremylt   @param offsets      Array of shape [@a num_elem, @a elem_size]. Row i holds the
309d979a051Sjeremylt                         ordered list of the offsets (into the input CeedVector)
3108795c945Sjeremylt                         for the unknowns corresponding to element i, where
311d1d35e2fSjeremylt                         0 <= i < @a num_elem. All offsets must be in the range
312d1d35e2fSjeremylt                         [0, @a l_size - 1].
3134ce2993fSjeremylt   @param[out] rstr    Address of the variable where the newly created
314b11c1e72Sjeremylt                         CeedElemRestriction will be stored
315d7b241e6Sjeremylt 
316b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
317dfdf5a53Sjeremylt 
3187a982d89SJeremy L. Thompson   @ref User
319b11c1e72Sjeremylt **/
320d1d35e2fSjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size,
321d1d35e2fSjeremylt                               CeedInt num_comp, CeedInt comp_stride,
322d1d35e2fSjeremylt                               CeedInt l_size, CeedMemType mem_type,
323d1d35e2fSjeremylt                               CeedCopyMode copy_mode, const CeedInt *offsets,
3244ce2993fSjeremylt                               CeedElemRestriction *rstr) {
325d7b241e6Sjeremylt   int ierr;
326d7b241e6Sjeremylt 
3275fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
3285fe0d4faSjeremylt     Ceed delegate;
329aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
330aefd8378Sjeremylt     CeedChk(ierr);
3315fe0d4faSjeremylt 
3325fe0d4faSjeremylt     if (!delegate)
333c042f62fSJeremy L Thompson       // LCOV_EXCL_START
334e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
335e15f9bd0SJeremy L Thompson                        "Backend does not support ElemRestrictionCreate");
336c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
3375fe0d4faSjeremylt 
338d1d35e2fSjeremylt     ierr = CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp,
339d1d35e2fSjeremylt                                      comp_stride, l_size, mem_type, copy_mode,
340d979a051Sjeremylt                                      offsets, rstr); CeedChk(ierr);
341e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
3425fe0d4faSjeremylt   }
3435fe0d4faSjeremylt 
3444ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
3454ce2993fSjeremylt   (*rstr)->ceed = ceed;
3469560d06aSjeremylt   ierr = CeedReference(ceed); CeedChk(ierr);
347d1d35e2fSjeremylt   (*rstr)->ref_count = 1;
348d1d35e2fSjeremylt   (*rstr)->num_elem = num_elem;
349d1d35e2fSjeremylt   (*rstr)->elem_size = elem_size;
350d1d35e2fSjeremylt   (*rstr)->num_comp = num_comp;
351d1d35e2fSjeremylt   (*rstr)->comp_stride = comp_stride;
352d1d35e2fSjeremylt   (*rstr)->l_size = l_size;
353d1d35e2fSjeremylt   (*rstr)->num_blk = num_elem;
354d1d35e2fSjeremylt   (*rstr)->blk_size = 1;
355d1d35e2fSjeremylt   ierr = ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr);
356d979a051Sjeremylt   CeedChk(ierr);
357e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
358d7b241e6Sjeremylt }
359d7b241e6Sjeremylt 
360d7b241e6Sjeremylt /**
361*fc0567d9Srezgarshakeri   @brief Create a CeedElemRestriction with orientation sign
362*fc0567d9Srezgarshakeri 
363*fc0567d9Srezgarshakeri   @param ceed         A Ceed object where the CeedElemRestriction will be created
364*fc0567d9Srezgarshakeri   @param num_elem     Number of elements described in the @a offsets array
365*fc0567d9Srezgarshakeri   @param elem_size    Size (number of "nodes") per element
366*fc0567d9Srezgarshakeri   @param num_comp     Number of field components per interpolation node
367*fc0567d9Srezgarshakeri                         (1 for scalar fields)
368*fc0567d9Srezgarshakeri   @param comp_stride  Stride between components for the same L-vector "node".
369*fc0567d9Srezgarshakeri                         Data for node i, component j, element k can be found in
370*fc0567d9Srezgarshakeri                         the L-vector at index
371*fc0567d9Srezgarshakeri                         offsets[i + k*elem_size] + j*comp_stride.
372*fc0567d9Srezgarshakeri   @param l_size       The size of the L-vector. This vector may be larger than
373*fc0567d9Srezgarshakeri                         the elements and fields given by this restriction.
374*fc0567d9Srezgarshakeri   @param mem_type     Memory type of the @a offsets array, see CeedMemType
375*fc0567d9Srezgarshakeri   @param copy_mode    Copy mode for the @a offsets array, see CeedCopyMode
376*fc0567d9Srezgarshakeri   @param offsets      Array of shape [@a num_elem, @a elem_size]. Row i holds the
377*fc0567d9Srezgarshakeri                         ordered list of the offsets (into the input CeedVector)
378*fc0567d9Srezgarshakeri                         for the unknowns corresponding to element i, where
379*fc0567d9Srezgarshakeri                         0 <= i < @a num_elem. All offsets must be in the range
380*fc0567d9Srezgarshakeri                         [0, @a l_size - 1].
381*fc0567d9Srezgarshakeri   @param orient       Array of shape [@a num_elem, @a elem_size] with bool false
382*fc0567d9Srezgarshakeri                         for positively oriented and true to flip the orientation.
383*fc0567d9Srezgarshakeri   @param scale        An scalar value that scales the dofs in assembly.
384*fc0567d9Srezgarshakeri   @param[out] rstr    Address of the variable where the newly created
385*fc0567d9Srezgarshakeri                         CeedElemRestriction will be stored
386*fc0567d9Srezgarshakeri 
387*fc0567d9Srezgarshakeri   @return An error code: 0 - success, otherwise - failure
388*fc0567d9Srezgarshakeri 
389*fc0567d9Srezgarshakeri   @ref User
390*fc0567d9Srezgarshakeri **/
391*fc0567d9Srezgarshakeri int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem,
392*fc0567d9Srezgarshakeri                                       CeedInt elem_size, CeedInt num_comp,
393*fc0567d9Srezgarshakeri                                       CeedInt comp_stride, CeedInt l_size,
394*fc0567d9Srezgarshakeri                                       CeedMemType mem_type, CeedCopyMode copy_mode,
395*fc0567d9Srezgarshakeri                                       const CeedInt *offsets, const bool *orient,
396*fc0567d9Srezgarshakeri                                       CeedElemRestriction *rstr) {
397*fc0567d9Srezgarshakeri   int ierr;
398*fc0567d9Srezgarshakeri 
399*fc0567d9Srezgarshakeri   if (!ceed->ElemRestrictionCreate) {
400*fc0567d9Srezgarshakeri     Ceed delegate;
401*fc0567d9Srezgarshakeri     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
402*fc0567d9Srezgarshakeri     CeedChk(ierr);
403*fc0567d9Srezgarshakeri 
404*fc0567d9Srezgarshakeri     if (!delegate)
405*fc0567d9Srezgarshakeri       // LCOV_EXCL_START
406*fc0567d9Srezgarshakeri       return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
407*fc0567d9Srezgarshakeri                        "Backend does not support ElemRestrictionCreateOriented");
408*fc0567d9Srezgarshakeri     // LCOV_EXCL_STOP
409*fc0567d9Srezgarshakeri 
410*fc0567d9Srezgarshakeri     ierr = CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size,
411*fc0567d9Srezgarshakeri            num_comp,
412*fc0567d9Srezgarshakeri            comp_stride, l_size, mem_type, copy_mode,
413*fc0567d9Srezgarshakeri            offsets, orient, rstr); CeedChk(ierr);
414*fc0567d9Srezgarshakeri     return CEED_ERROR_SUCCESS;
415*fc0567d9Srezgarshakeri   }
416*fc0567d9Srezgarshakeri 
417*fc0567d9Srezgarshakeri   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
418*fc0567d9Srezgarshakeri   (*rstr)->ceed = ceed;
419*fc0567d9Srezgarshakeri   ierr = CeedReference(ceed); CeedChk(ierr);
420*fc0567d9Srezgarshakeri   (*rstr)->ref_count = 1;
421*fc0567d9Srezgarshakeri   (*rstr)->num_elem = num_elem;
422*fc0567d9Srezgarshakeri   (*rstr)->elem_size = elem_size;
423*fc0567d9Srezgarshakeri   (*rstr)->num_comp = num_comp;
424*fc0567d9Srezgarshakeri   (*rstr)->comp_stride = comp_stride;
425*fc0567d9Srezgarshakeri   (*rstr)->l_size = l_size;
426*fc0567d9Srezgarshakeri   (*rstr)->num_blk = num_elem;
427*fc0567d9Srezgarshakeri   (*rstr)->blk_size = 1;
428*fc0567d9Srezgarshakeri   ierr = ceed->ElemRestrictionCreateOriented(mem_type, copy_mode, offsets, orient,
429*fc0567d9Srezgarshakeri          *rstr);
430*fc0567d9Srezgarshakeri   CeedChk(ierr);
431*fc0567d9Srezgarshakeri   return CEED_ERROR_SUCCESS;
432*fc0567d9Srezgarshakeri }
433*fc0567d9Srezgarshakeri 
434*fc0567d9Srezgarshakeri /**
4357509a596Sjeremylt   @brief Create a strided CeedElemRestriction
436d7b241e6Sjeremylt 
437b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
438d1d35e2fSjeremylt   @param num_elem   Number of elements described by the restriction
439d1d35e2fSjeremylt   @param elem_size  Size (number of "nodes") per element
440d1d35e2fSjeremylt   @param num_comp   Number of field components per interpolation "node"
44195bb1877Svaleriabarra                       (1 for scalar fields)
442d1d35e2fSjeremylt   @param l_size     The size of the L-vector. This vector may be larger than
443d979a051Sjeremylt                       the elements and fields given by this restriction.
4447509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
44595e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
44695e93d34SJeremy L Thompson                       the L-vector at index
44795e93d34SJeremy L Thompson                       i*strides[0] + j*strides[1] + k*strides[2].
44895e93d34SJeremy L Thompson                       @a CEED_STRIDES_BACKEND may be used with vectors created
44995e93d34SJeremy L Thompson                       by a Ceed backend.
4504ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
451b11c1e72Sjeremylt                       CeedElemRestriction will be stored
452d7b241e6Sjeremylt 
453b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
454dfdf5a53Sjeremylt 
4557a982d89SJeremy L. Thompson   @ref User
456b11c1e72Sjeremylt **/
457d1d35e2fSjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem,
458d1d35e2fSjeremylt                                      CeedInt elem_size,
459d1d35e2fSjeremylt                                      CeedInt num_comp, CeedInt l_size,
4608621c6c6SJeremy L Thompson                                      const CeedInt strides[3],
461f90c8643Sjeremylt                                      CeedElemRestriction *rstr) {
462d7b241e6Sjeremylt   int ierr;
463d7b241e6Sjeremylt 
4645fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
4655fe0d4faSjeremylt     Ceed delegate;
466aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
467aefd8378Sjeremylt     CeedChk(ierr);
4685fe0d4faSjeremylt 
4695fe0d4faSjeremylt     if (!delegate)
470c042f62fSJeremy L Thompson       // LCOV_EXCL_START
471e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
472e15f9bd0SJeremy L Thompson                        "Backend does not support ElemRestrictionCreate");
473c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
4745fe0d4faSjeremylt 
475d1d35e2fSjeremylt     ierr = CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp,
476d1d35e2fSjeremylt                                             l_size, strides, rstr);
477d979a051Sjeremylt     CeedChk(ierr);
478e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
4795fe0d4faSjeremylt   }
4805fe0d4faSjeremylt 
4814ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
4824ce2993fSjeremylt   (*rstr)->ceed = ceed;
4839560d06aSjeremylt   ierr = CeedReference(ceed); CeedChk(ierr);
484d1d35e2fSjeremylt   (*rstr)->ref_count = 1;
485d1d35e2fSjeremylt   (*rstr)->num_elem = num_elem;
486d1d35e2fSjeremylt   (*rstr)->elem_size = elem_size;
487d1d35e2fSjeremylt   (*rstr)->num_comp = num_comp;
488d1d35e2fSjeremylt   (*rstr)->l_size = l_size;
489d1d35e2fSjeremylt   (*rstr)->num_blk = num_elem;
490d1d35e2fSjeremylt   (*rstr)->blk_size = 1;
4917509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
4927509a596Sjeremylt   for (int i=0; i<3; i++)
4937509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
4941dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
4951dfeef1dSjeremylt                                      *rstr);
4964b8bea3bSJed Brown   CeedChk(ierr);
497e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
498d7b241e6Sjeremylt }
499d7b241e6Sjeremylt 
500d7b241e6Sjeremylt /**
501b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
502d7b241e6Sjeremylt 
503d7b241e6Sjeremylt   @param ceed         A Ceed object where the CeedElemRestriction will be created.
504d1d35e2fSjeremylt   @param num_elem     Number of elements described in the @a offsets array.
505d1d35e2fSjeremylt   @param elem_size    Size (number of unknowns) per element
506d1d35e2fSjeremylt   @param blk_size     Number of elements in a block
507d1d35e2fSjeremylt   @param num_comp     Number of field components per interpolation node
50895bb1877Svaleriabarra                         (1 for scalar fields)
509d1d35e2fSjeremylt   @param comp_stride  Stride between components for the same L-vector "node".
51095e93d34SJeremy L Thompson                         Data for node i, component j, element k can be found in
51195e93d34SJeremy L Thompson                         the L-vector at index
512d1d35e2fSjeremylt                         offsets[i + k*elem_size] + j*comp_stride.
513d1d35e2fSjeremylt   @param l_size       The size of the L-vector. This vector may be larger than
514d979a051Sjeremylt                         the elements and fields given by this restriction.
515d1d35e2fSjeremylt   @param mem_type     Memory type of the @a offsets array, see CeedMemType
516d1d35e2fSjeremylt   @param copy_mode    Copy mode for the @a offsets array, see CeedCopyMode
517d1d35e2fSjeremylt   @param offsets      Array of shape [@a num_elem, @a elem_size]. Row i holds the
518d979a051Sjeremylt                         ordered list of the offsets (into the input CeedVector)
5198795c945Sjeremylt                         for the unknowns corresponding to element i, where
520d1d35e2fSjeremylt                         0 <= i < @a num_elem. All offsets must be in the range
521d1d35e2fSjeremylt                         [0, @a l_size - 1]. The backend will permute and pad this
5228795c945Sjeremylt                         array to the desired ordering for the blocksize, which is
5238795c945Sjeremylt                         typically given by the backend. The default reordering is
5248795c945Sjeremylt                         to interlace elements.
5254ce2993fSjeremylt   @param rstr         Address of the variable where the newly created
526b11c1e72Sjeremylt                         CeedElemRestriction will be stored
527d7b241e6Sjeremylt 
528b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
529dfdf5a53Sjeremylt 
5307a982d89SJeremy L. Thompson   @ref Backend
531b11c1e72Sjeremylt  **/
532d1d35e2fSjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem,
533d1d35e2fSjeremylt                                      CeedInt elem_size,
534d1d35e2fSjeremylt                                      CeedInt blk_size, CeedInt num_comp,
535d1d35e2fSjeremylt                                      CeedInt comp_stride, CeedInt l_size,
536d1d35e2fSjeremylt                                      CeedMemType mem_type, CeedCopyMode copy_mode,
537d979a051Sjeremylt                                      const CeedInt *offsets,
5384ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
539d7b241e6Sjeremylt   int ierr;
540d1d35e2fSjeremylt   CeedInt *blk_offsets;
541d1d35e2fSjeremylt   CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size);
542d7b241e6Sjeremylt 
5435fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
5445fe0d4faSjeremylt     Ceed delegate;
545aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
546aefd8378Sjeremylt     CeedChk(ierr);
5475fe0d4faSjeremylt 
5485fe0d4faSjeremylt     if (!delegate)
549c042f62fSJeremy L Thompson       // LCOV_EXCL_START
550e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support "
5511d102b48SJeremy L Thompson                        "ElemRestrictionCreateBlocked");
552c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
5535fe0d4faSjeremylt 
554d1d35e2fSjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size,
555d1d35e2fSjeremylt                                             num_comp, comp_stride, l_size, mem_type,
556d1d35e2fSjeremylt                                             copy_mode, offsets, rstr);
557d979a051Sjeremylt     CeedChk(ierr);
558e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
5595fe0d4faSjeremylt   }
560d7b241e6Sjeremylt 
5614ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
562d7b241e6Sjeremylt 
563d1d35e2fSjeremylt   ierr = CeedCalloc(num_blk*blk_size*elem_size, &blk_offsets); CeedChk(ierr);
564d1d35e2fSjeremylt   ierr = CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size,
565d1d35e2fSjeremylt                                elem_size); CeedChk(ierr);
566d7b241e6Sjeremylt 
5674ce2993fSjeremylt   (*rstr)->ceed = ceed;
5689560d06aSjeremylt   ierr = CeedReference(ceed); CeedChk(ierr);
569d1d35e2fSjeremylt   (*rstr)->ref_count = 1;
570d1d35e2fSjeremylt   (*rstr)->num_elem = num_elem;
571d1d35e2fSjeremylt   (*rstr)->elem_size = elem_size;
572d1d35e2fSjeremylt   (*rstr)->num_comp = num_comp;
573d1d35e2fSjeremylt   (*rstr)->comp_stride = comp_stride;
574d1d35e2fSjeremylt   (*rstr)->l_size = l_size;
575d1d35e2fSjeremylt   (*rstr)->num_blk = num_blk;
576d1d35e2fSjeremylt   (*rstr)->blk_size = blk_size;
577667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
578d1d35e2fSjeremylt          (const CeedInt *) blk_offsets, *rstr); CeedChk(ierr);
579d1d35e2fSjeremylt   if (copy_mode == CEED_OWN_POINTER) {
580d979a051Sjeremylt     ierr = CeedFree(&offsets); CeedChk(ierr);
5811d102b48SJeremy L Thompson   }
582e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
583d7b241e6Sjeremylt }
584d7b241e6Sjeremylt 
585b11c1e72Sjeremylt /**
5867509a596Sjeremylt   @brief Create a blocked strided CeedElemRestriction
5877509a596Sjeremylt 
5887509a596Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
589d1d35e2fSjeremylt   @param num_elem   Number of elements described by the restriction
590d1d35e2fSjeremylt   @param elem_size  Size (number of "nodes") per element
591d1d35e2fSjeremylt   @param blk_size   Number of elements in a block
592d1d35e2fSjeremylt   @param num_comp   Number of field components per interpolation node
5937509a596Sjeremylt                       (1 for scalar fields)
594d1d35e2fSjeremylt   @param l_size     The size of the L-vector. This vector may be larger than
595d979a051Sjeremylt                       the elements and fields given by this restriction.
5967509a596Sjeremylt   @param strides    Array for strides between [nodes, components, elements].
59795e93d34SJeremy L Thompson                       Data for node i, component j, element k can be found in
59895e93d34SJeremy L Thompson                       the L-vector at index
59995e93d34SJeremy L Thompson                       i*strides[0] + j*strides[1] + k*strides[2].
60095e93d34SJeremy L Thompson                       @a CEED_STRIDES_BACKEND may be used with vectors created
60195e93d34SJeremy L Thompson                       by a Ceed backend.
6027509a596Sjeremylt   @param rstr       Address of the variable where the newly created
6037509a596Sjeremylt                       CeedElemRestriction will be stored
6047509a596Sjeremylt 
6057509a596Sjeremylt   @return An error code: 0 - success, otherwise - failure
6067509a596Sjeremylt 
6077a982d89SJeremy L. Thompson   @ref User
6087509a596Sjeremylt **/
609d1d35e2fSjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem,
610d1d35e2fSjeremylt     CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt l_size,
6118621c6c6SJeremy L Thompson     const CeedInt strides[3], CeedElemRestriction *rstr) {
6127509a596Sjeremylt   int ierr;
613d1d35e2fSjeremylt   CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size);
6147509a596Sjeremylt 
6157509a596Sjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
6167509a596Sjeremylt     Ceed delegate;
6177509a596Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
6187509a596Sjeremylt     CeedChk(ierr);
6197509a596Sjeremylt 
6207509a596Sjeremylt     if (!delegate)
6217509a596Sjeremylt       // LCOV_EXCL_START
622e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support "
6237509a596Sjeremylt                        "ElemRestrictionCreateBlocked");
6247509a596Sjeremylt     // LCOV_EXCL_STOP
6257509a596Sjeremylt 
626d1d35e2fSjeremylt     ierr = CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size,
627d1d35e2fSjeremylt            blk_size, num_comp, l_size, strides, rstr); CeedChk(ierr);
628e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
6297509a596Sjeremylt   }
6307509a596Sjeremylt 
6317509a596Sjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
6327509a596Sjeremylt 
6337509a596Sjeremylt   (*rstr)->ceed = ceed;
6349560d06aSjeremylt   ierr = CeedReference(ceed); CeedChk(ierr);
635d1d35e2fSjeremylt   (*rstr)->ref_count = 1;
636d1d35e2fSjeremylt   (*rstr)->num_elem = num_elem;
637d1d35e2fSjeremylt   (*rstr)->elem_size = elem_size;
638d1d35e2fSjeremylt   (*rstr)->num_comp = num_comp;
639d1d35e2fSjeremylt   (*rstr)->l_size = l_size;
640d1d35e2fSjeremylt   (*rstr)->num_blk = num_blk;
641d1d35e2fSjeremylt   (*rstr)->blk_size = blk_size;
6427509a596Sjeremylt   ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
6437509a596Sjeremylt   for (int i=0; i<3; i++)
6447509a596Sjeremylt     (*rstr)->strides[i] = strides[i];
6457509a596Sjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
6467509a596Sjeremylt          NULL, *rstr); CeedChk(ierr);
647e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
6487509a596Sjeremylt }
6497509a596Sjeremylt 
6507509a596Sjeremylt /**
6519560d06aSjeremylt   @brief Copy the pointer to a CeedElemRestriction. Both pointers should
6529560d06aSjeremylt            be destroyed with `CeedElemRestrictionDestroy()`;
6539560d06aSjeremylt            Note: If `*rstr_copy` is non-NULL, then it is assumed that
6549560d06aSjeremylt            `*rstr_copy` is a pointer to a CeedElemRestriction. This
6559560d06aSjeremylt            CeedElemRestriction will be destroyed if `*rstr_copy` is the
6569560d06aSjeremylt            only reference to this CeedElemRestriction.
6579560d06aSjeremylt 
6589560d06aSjeremylt   @param rstr            CeedElemRestriction to copy reference to
6599560d06aSjeremylt   @param[out] rstr_copy  Variable to store copied reference
6609560d06aSjeremylt 
6619560d06aSjeremylt   @return An error code: 0 - success, otherwise - failure
6629560d06aSjeremylt 
6639560d06aSjeremylt   @ref User
6649560d06aSjeremylt **/
6659560d06aSjeremylt int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr,
6669560d06aSjeremylt                                      CeedElemRestriction *rstr_copy) {
6679560d06aSjeremylt   int ierr;
6689560d06aSjeremylt 
6699560d06aSjeremylt   ierr = CeedElemRestrictionReference(rstr); CeedChk(ierr);
6709560d06aSjeremylt   ierr = CeedElemRestrictionDestroy(rstr_copy); CeedChk(ierr);
6719560d06aSjeremylt   *rstr_copy = rstr;
6729560d06aSjeremylt   return CEED_ERROR_SUCCESS;
6739560d06aSjeremylt }
6749560d06aSjeremylt 
6759560d06aSjeremylt /**
676b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
677b11c1e72Sjeremylt 
6784ce2993fSjeremylt   @param rstr   CeedElemRestriction
679d1d35e2fSjeremylt   @param l_vec  The address of the L-vector to be created, or NULL
680d1d35e2fSjeremylt   @param e_vec  The address of the E-vector to be created, or NULL
681b11c1e72Sjeremylt 
682b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
683dfdf5a53Sjeremylt 
6847a982d89SJeremy L. Thompson   @ref User
685b11c1e72Sjeremylt **/
686d1d35e2fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec,
687d1d35e2fSjeremylt                                     CeedVector *e_vec) {
688d7b241e6Sjeremylt   int ierr;
689d1d35e2fSjeremylt   CeedInt e_size, l_size;
690d1d35e2fSjeremylt   l_size = rstr->l_size;
691d1d35e2fSjeremylt   e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp;
692d1d35e2fSjeremylt   if (l_vec) {
693d1d35e2fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, l_size, l_vec); CeedChk(ierr);
694d7b241e6Sjeremylt   }
695d1d35e2fSjeremylt   if (e_vec) {
696d1d35e2fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, e_size, e_vec); CeedChk(ierr);
697d7b241e6Sjeremylt   }
698e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
699d7b241e6Sjeremylt }
700d7b241e6Sjeremylt 
701d7b241e6Sjeremylt /**
702d9e1f99aSValeria Barra   @brief Restrict an L-vector to an E-vector or apply its transpose
703d7b241e6Sjeremylt 
7044ce2993fSjeremylt   @param rstr    CeedElemRestriction
705d1d35e2fSjeremylt   @param t_mode  Apply restriction or transpose
706d1d35e2fSjeremylt   @param u       Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE)
707d1d35e2fSjeremylt   @param ru      Output vector (of shape [@a num_elem * @a elem_size] when
708d1d35e2fSjeremylt                    t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
7097aaeacdcSjeremylt                    by the backend.
7104cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
711b11c1e72Sjeremylt 
712b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
713dfdf5a53Sjeremylt 
7147a982d89SJeremy L. Thompson   @ref User
715b11c1e72Sjeremylt **/
716d1d35e2fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode,
717a8d32208Sjeremylt                              CeedVector u, CeedVector ru,
718a8d32208Sjeremylt                              CeedRequest *request) {
719d7b241e6Sjeremylt   CeedInt m, n;
720d7b241e6Sjeremylt   int ierr;
721d7b241e6Sjeremylt 
722d1d35e2fSjeremylt   if (t_mode == CEED_NOTRANSPOSE) {
723d1d35e2fSjeremylt     m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp;
724d1d35e2fSjeremylt     n = rstr->l_size;
725d7b241e6Sjeremylt   } else {
726d1d35e2fSjeremylt     m = rstr->l_size;
727d1d35e2fSjeremylt     n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp;
728d7b241e6Sjeremylt   }
729d7b241e6Sjeremylt   if (n != u->length)
730c042f62fSJeremy L Thompson     // LCOV_EXCL_START
731e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
732e15f9bd0SJeremy L Thompson                      "Input vector size %d not compatible with "
7331d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
734c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
735a8d32208Sjeremylt   if (m != ru->length)
736c042f62fSJeremy L Thompson     // LCOV_EXCL_START
737e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
738e15f9bd0SJeremy L Thompson                      "Output vector size %d not compatible with "
739a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
740c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
741d1d35e2fSjeremylt   ierr = rstr->Apply(rstr, t_mode, u, ru, request); CeedChk(ierr);
742e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
743d7b241e6Sjeremylt }
744d7b241e6Sjeremylt 
745d7b241e6Sjeremylt /**
746d9e1f99aSValeria Barra   @brief Restrict an L-vector to a block of an E-vector or apply its transpose
747be9261b7Sjeremylt 
748be9261b7Sjeremylt   @param rstr    CeedElemRestriction
7491f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
750d1d35e2fSjeremylt                    elements [0 : blk_size] and block=3 will handle elements
751d1d35e2fSjeremylt                    [3*blk_size : 4*blk_size]
752d1d35e2fSjeremylt   @param t_mode  Apply restriction or transpose
753d1d35e2fSjeremylt   @param u       Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE)
754d1d35e2fSjeremylt   @param ru      Output vector (of shape [@a blk_size * @a elem_size] when
755d1d35e2fSjeremylt                    t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided
7567aaeacdcSjeremylt                    by the backend.
7574cc79fe7SJed Brown   @param request Request or @ref CEED_REQUEST_IMMEDIATE
758be9261b7Sjeremylt 
759be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
760be9261b7Sjeremylt 
7617a982d89SJeremy L. Thompson   @ref Backend
762be9261b7Sjeremylt **/
763be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
764d1d35e2fSjeremylt                                   CeedTransposeMode t_mode, CeedVector u,
765a8d32208Sjeremylt                                   CeedVector ru, CeedRequest *request) {
766be9261b7Sjeremylt   CeedInt m, n;
767be9261b7Sjeremylt   int ierr;
768be9261b7Sjeremylt 
769d1d35e2fSjeremylt   if (t_mode == CEED_NOTRANSPOSE) {
770d1d35e2fSjeremylt     m = rstr->blk_size * rstr->elem_size * rstr->num_comp;
771d1d35e2fSjeremylt     n = rstr->l_size;
772be9261b7Sjeremylt   } else {
773d1d35e2fSjeremylt     m = rstr->l_size;
774d1d35e2fSjeremylt     n = rstr->blk_size * rstr->elem_size * rstr->num_comp;
775be9261b7Sjeremylt   }
776be9261b7Sjeremylt   if (n != u->length)
777c042f62fSJeremy L Thompson     // LCOV_EXCL_START
778e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
779e15f9bd0SJeremy L Thompson                      "Input vector size %d not compatible with "
7801d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
781c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
782a8d32208Sjeremylt   if (m != ru->length)
783c042f62fSJeremy L Thompson     // LCOV_EXCL_START
784e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
785e15f9bd0SJeremy L Thompson                      "Output vector size %d not compatible with "
786a8d32208Sjeremylt                      "element restriction (%d, %d)", ru->length, m, n);
787c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
788d1d35e2fSjeremylt   if (rstr->blk_size*block > rstr->num_elem)
789c042f62fSJeremy L Thompson     // LCOV_EXCL_START
790e15f9bd0SJeremy L Thompson     return CeedError(rstr->ceed, CEED_ERROR_DIMENSION,
791e15f9bd0SJeremy L Thompson                      "Cannot retrieve block %d, element %d > "
792d1d35e2fSjeremylt                      "total elements %d", block, rstr->blk_size*block,
793d1d35e2fSjeremylt                      rstr->num_elem);
794c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
795d1d35e2fSjeremylt   ierr = rstr->ApplyBlock(rstr, block, t_mode, u, ru, request);
796be9261b7Sjeremylt   CeedChk(ierr);
797e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
798be9261b7Sjeremylt }
799be9261b7Sjeremylt 
800be9261b7Sjeremylt /**
801b7c9bbdaSJeremy L Thompson   @brief Get the Ceed associated with a CeedElemRestriction
802b7c9bbdaSJeremy L Thompson 
803b7c9bbdaSJeremy L Thompson   @param rstr       CeedElemRestriction
804b7c9bbdaSJeremy L Thompson   @param[out] ceed  Variable to store Ceed
805b7c9bbdaSJeremy L Thompson 
806b7c9bbdaSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
807b7c9bbdaSJeremy L Thompson 
808b7c9bbdaSJeremy L Thompson   @ref Advanced
809b7c9bbdaSJeremy L Thompson **/
810b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) {
811b7c9bbdaSJeremy L Thompson   *ceed = rstr->ceed;
812b7c9bbdaSJeremy L Thompson   return CEED_ERROR_SUCCESS;
813b7c9bbdaSJeremy L Thompson }
814b7c9bbdaSJeremy L Thompson 
815b7c9bbdaSJeremy L Thompson /**
816d979a051Sjeremylt   @brief Get the L-vector component stride
817a681ae63Sjeremylt 
818a681ae63Sjeremylt   @param rstr              CeedElemRestriction
819d1d35e2fSjeremylt   @param[out] comp_stride  Variable to store component stride
820a681ae63Sjeremylt 
821a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
822a681ae63Sjeremylt 
823b7c9bbdaSJeremy L Thompson   @ref Advanced
824a681ae63Sjeremylt **/
825d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr,
826d1d35e2fSjeremylt                                      CeedInt *comp_stride) {
827d1d35e2fSjeremylt   *comp_stride = rstr->comp_stride;
828e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
829a681ae63Sjeremylt }
830a681ae63Sjeremylt 
831a681ae63Sjeremylt /**
832a681ae63Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
833a681ae63Sjeremylt 
834a681ae63Sjeremylt   @param rstr           CeedElemRestriction
835d1d35e2fSjeremylt   @param[out] num_elem  Variable to store number of elements
836a681ae63Sjeremylt 
837a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
838a681ae63Sjeremylt 
839b7c9bbdaSJeremy L Thompson   @ref Advanced
840a681ae63Sjeremylt **/
841a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
842d1d35e2fSjeremylt                                       CeedInt *num_elem) {
843d1d35e2fSjeremylt   *num_elem = rstr->num_elem;
844e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
845a681ae63Sjeremylt }
846a681ae63Sjeremylt 
847a681ae63Sjeremylt /**
848a681ae63Sjeremylt   @brief Get the size of elements in the CeedElemRestriction
849a681ae63Sjeremylt 
850a681ae63Sjeremylt   @param rstr            CeedElemRestriction
851d1d35e2fSjeremylt   @param[out] elem_size  Variable to store size of elements
852a681ae63Sjeremylt 
853a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
854a681ae63Sjeremylt 
855b7c9bbdaSJeremy L Thompson   @ref Advanced
856a681ae63Sjeremylt **/
857a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
858d1d35e2fSjeremylt                                       CeedInt *elem_size) {
859d1d35e2fSjeremylt   *elem_size = rstr->elem_size;
860e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
861a681ae63Sjeremylt }
862a681ae63Sjeremylt 
863a681ae63Sjeremylt /**
864d979a051Sjeremylt   @brief Get the size of the l-vector for a CeedElemRestriction
865a681ae63Sjeremylt 
866a681ae63Sjeremylt   @param rstr         CeedElemRestriction
867d1d35e2fSjeremylt   @param[out] l_size  Variable to store number of nodes
868a681ae63Sjeremylt 
869a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
870a681ae63Sjeremylt 
871b7c9bbdaSJeremy L Thompson   @ref Advanced
872a681ae63Sjeremylt **/
873d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr,
874d1d35e2fSjeremylt                                       CeedInt *l_size) {
875d1d35e2fSjeremylt   *l_size = rstr->l_size;
876e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
877a681ae63Sjeremylt }
878a681ae63Sjeremylt 
879a681ae63Sjeremylt /**
880a681ae63Sjeremylt   @brief Get the number of components in the elements of a
881a681ae63Sjeremylt          CeedElemRestriction
882a681ae63Sjeremylt 
883a681ae63Sjeremylt   @param rstr           CeedElemRestriction
884d1d35e2fSjeremylt   @param[out] num_comp  Variable to store number of components
885a681ae63Sjeremylt 
886a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
887a681ae63Sjeremylt 
888b7c9bbdaSJeremy L Thompson   @ref Advanced
889a681ae63Sjeremylt **/
890a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
891d1d35e2fSjeremylt                                         CeedInt *num_comp) {
892d1d35e2fSjeremylt   *num_comp = rstr->num_comp;
893e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
894a681ae63Sjeremylt }
895a681ae63Sjeremylt 
896a681ae63Sjeremylt /**
897a681ae63Sjeremylt   @brief Get the number of blocks in a CeedElemRestriction
898a681ae63Sjeremylt 
899a681ae63Sjeremylt   @param rstr            CeedElemRestriction
900d1d35e2fSjeremylt   @param[out] num_block  Variable to store number of blocks
901a681ae63Sjeremylt 
902a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
903a681ae63Sjeremylt 
904b7c9bbdaSJeremy L Thompson   @ref Advanced
905a681ae63Sjeremylt **/
906a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
907d1d35e2fSjeremylt                                     CeedInt *num_block) {
908d1d35e2fSjeremylt   *num_block = rstr->num_blk;
909e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
910a681ae63Sjeremylt }
911a681ae63Sjeremylt 
912a681ae63Sjeremylt /**
913a681ae63Sjeremylt   @brief Get the size of blocks in the CeedElemRestriction
914a681ae63Sjeremylt 
915a681ae63Sjeremylt   @param rstr           CeedElemRestriction
916d1d35e2fSjeremylt   @param[out] blk_size  Variable to store size of blocks
917a681ae63Sjeremylt 
918a681ae63Sjeremylt   @return An error code: 0 - success, otherwise - failure
919a681ae63Sjeremylt 
920b7c9bbdaSJeremy L Thompson   @ref Advanced
921a681ae63Sjeremylt **/
922a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
923d1d35e2fSjeremylt                                     CeedInt *blk_size) {
924d1d35e2fSjeremylt   *blk_size = rstr->blk_size;
925e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
926a681ae63Sjeremylt }
927a681ae63Sjeremylt 
928a681ae63Sjeremylt /**
929d9e1f99aSValeria Barra   @brief Get the multiplicity of nodes in a CeedElemRestriction
9301469ee4dSjeremylt 
9311469ee4dSjeremylt   @param rstr       CeedElemRestriction
932d1d35e2fSjeremylt   @param[out] mult  Vector to store multiplicity (of size l_size)
9331469ee4dSjeremylt 
9341469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
9351469ee4dSjeremylt 
9367a982d89SJeremy L. Thompson   @ref User
9371469ee4dSjeremylt **/
9381469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
9391469ee4dSjeremylt                                        CeedVector mult) {
9401469ee4dSjeremylt   int ierr;
941d1d35e2fSjeremylt   CeedVector e_vec;
9421469ee4dSjeremylt 
94325509ebbSRezgar Shakeri   // Create e_vec to hold intermediate computation in E^T (E 1)
944d1d35e2fSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &e_vec); CeedChk(ierr);
9451469ee4dSjeremylt 
94625509ebbSRezgar Shakeri   // Compute e_vec = E * 1
94725509ebbSRezgar Shakeri   ierr = CeedVectorSetValue(mult, 1.0); CeedChk(ierr);
94825509ebbSRezgar Shakeri   ierr = CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec,
94925509ebbSRezgar Shakeri                                   CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
95025509ebbSRezgar Shakeri   // Compute multiplicity, mult = E^T * e_vec = E^T (E 1)
95125509ebbSRezgar Shakeri   ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr);
952d1d35e2fSjeremylt   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult,
953efc78312Sjeremylt                                   CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
9541469ee4dSjeremylt   // Cleanup
955d1d35e2fSjeremylt   ierr = CeedVectorDestroy(&e_vec); CeedChk(ierr);
956e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
9571469ee4dSjeremylt }
9581469ee4dSjeremylt 
9591469ee4dSjeremylt /**
960f02ca4a2SJed Brown   @brief View a CeedElemRestriction
961f02ca4a2SJed Brown 
962f02ca4a2SJed Brown   @param[in] rstr    CeedElemRestriction to view
963f02ca4a2SJed Brown   @param[in] stream  Stream to write; typically stdout/stderr or a file
964f02ca4a2SJed Brown 
965f02ca4a2SJed Brown   @return Error code: 0 - success, otherwise - failure
966f02ca4a2SJed Brown 
9677a982d89SJeremy L. Thompson   @ref User
968f02ca4a2SJed Brown **/
969f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
9707509a596Sjeremylt   char stridesstr[500];
9717509a596Sjeremylt   if (rstr->strides)
9727509a596Sjeremylt     sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1],
9737509a596Sjeremylt             rstr->strides[2]);
974d979a051Sjeremylt   else
975d1d35e2fSjeremylt     sprintf(stridesstr, "%d", rstr->comp_stride);
9767509a596Sjeremylt 
9770036de2cSjeremylt   fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d "
978d1d35e2fSjeremylt           "nodes each and %s %s\n", rstr->blk_size > 1 ? "Blocked " : "",
979d1d35e2fSjeremylt           rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size,
980d979a051Sjeremylt           rstr->strides ? "strides" : "component stride", stridesstr);
981e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
982f02ca4a2SJed Brown }
983f02ca4a2SJed Brown 
984f02ca4a2SJed Brown /**
985b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
986b11c1e72Sjeremylt 
9874ce2993fSjeremylt   @param rstr  CeedElemRestriction to destroy
988b11c1e72Sjeremylt 
989b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
990dfdf5a53Sjeremylt 
9917a982d89SJeremy L. Thompson   @ref User
992b11c1e72Sjeremylt **/
9934ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
994d7b241e6Sjeremylt   int ierr;
995d7b241e6Sjeremylt 
996d1d35e2fSjeremylt   if (!*rstr || --(*rstr)->ref_count > 0) return CEED_ERROR_SUCCESS;
997d1d35e2fSjeremylt   if ((*rstr)->num_readers)
9988229195eSjeremylt     // LCOV_EXCL_START
999e15f9bd0SJeremy L Thompson     return CeedError((*rstr)->ceed, CEED_ERROR_ACCESS,
1000e15f9bd0SJeremy L Thompson                      "Cannot destroy CeedElemRestriction, "
1001430758c8SJeremy L Thompson                      "a process has read access to the offset data");
10028229195eSjeremylt   // LCOV_EXCL_STOP
10034ce2993fSjeremylt   if ((*rstr)->Destroy) {
10044ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
1005d7b241e6Sjeremylt   }
10067509a596Sjeremylt   ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr);
10074ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
10084ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
1009e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1010d7b241e6Sjeremylt }
1011d7b241e6Sjeremylt 
1012d7b241e6Sjeremylt /// @}
1013